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.