Skip to main content

The Request Object

The Request object in Flask is the central interface for interacting with incoming HTTP data. Implemented in src/flask/wrappers.py, the Request class extends werkzeug.wrappers.Request to provide additional integration with Flask's routing system, blueprints, and application configuration.

Accessing Incoming Data

The Request object provides several attributes to access data sent by the client, depending on the HTTP method and content type.

Form and Query Data

For standard web forms and URL parameters, Flask uses MultiDict structures which allow multiple values for a single key.

  • request.form: Contains data sent in a POST or PUT request with form encoding.
  • request.args: Contains parameters parsed from the URL query string (e.g., ?id=5).
  • request.values: A combined MultiDict containing both form and args.

A common pattern in this codebase is using .get() with the type parameter to perform inline type conversion, as seen in examples/javascript/js_example/views.py:

@app.route("/add", methods=["POST"])
def add():
# Safely convert form values to floats with defaults
a = request.form.get("a", 0, type=float)
b = request.form.get("b", 0, type=float)
return jsonify(result=a + b)

JSON Data

When a request is sent with Content-Type: application/json, the data is accessible via request.json. If the JSON is invalid, Flask triggers on_json_loading_failed. In debug mode, this method raises a detailed error; in production, it raises a standard 400 BadRequest.

HTTP Methods

View functions often branch logic based on request.method. This is frequently used in the flaskr tutorial (e.g., examples/tutorial/flaskr/auth.py) to handle both the display and submission of a form in a single view:

@bp.route("/register", methods=("GET", "POST"))
def register():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
# ... process registration ...

# If GET, just render the template
return render_template("auth/register.html")

Routing and View Metadata

Unlike a generic Werkzeug request, the Flask Request object is aware of the routing process that led to the current view execution.

  • request.url_rule: The actual Rule object from the URL map that matched the request. You can inspect request.url_rule.methods to see which HTTP methods are allowed for this specific route.
  • request.view_args: A dictionary containing the variables extracted from the URL. For a route like /user/<int:user_id>, view_args would contain {'user_id': ...}.
  • request.endpoint: The internal name of the matched view function (e.g., 'auth.login').
  • request.routing_exception: If URL matching fails, this attribute stores the HTTPException (typically a 404 NotFound or 405 MethodNotAllowed) that was encountered.

Blueprint Integration

The Request object provides properties to identify which blueprint handled the request, which is essential for modular applications.

  • request.blueprint: The name of the blueprint that the current endpoint belongs to.
  • request.blueprints: A list of blueprint names, starting from the current one and moving up through parent blueprints. This is useful for nested blueprints.

The implementation in src/flask/wrappers.py determines the blueprint by parsing the endpoint string:

@property
def blueprint(self) -> str | None:
endpoint = self.endpoint
if endpoint is not None and "." in endpoint:
return endpoint.rpartition(".")[0]
return None

Request Limits and Security

Flask allows you to enforce limits on incoming data to prevent denial-of-service attacks or excessive memory usage. These are managed via application configuration but can be overridden on a per-request basis.

Configuration KeyDescriptionDefault
MAX_CONTENT_LENGTHMaximum bytes read during the request.None
MAX_FORM_MEMORY_SIZEMaximum size for non-file form fields.500,000
MAX_FORM_PARTSMaximum number of fields in a multipart body.1,000

You can override these limits dynamically within a view or a before_request handler:

@app.route("/upload", methods=["POST"])
def upload_file():
# Increase limit specifically for this large upload view
request.max_content_length = 50 * 1024 * 1024 # 50MB
# ... process upload ...

Debugging Helpers

In debug mode, the Request object provides extra assistance for common mistakes. If you attempt to access request.files but the request was sent without the correct enctype="multipart/form-data", Flask's _load_form_data method uses attach_enctype_error_multidict to provide a more descriptive error message than a standard KeyError.

# Internal logic in src/flask/wrappers.py
if (
current_app
and current_app.debug
and self.mimetype != "multipart/form-data"
and not self.files
):
from .debughelpers import attach_enctype_error_multidict
attach_enctype_error_multidict(self)

Contextual Availability

The request object is a thread-local proxy. It is only available when a request context is active. Attempting to access request.form or other attributes outside of a view function (or a lifecycle hook like before_request) will result in a RuntimeError. You can use flask.has_request_context() to safely check if the object is currently accessible in utility code.