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 aPOSTorPUTrequest with form encoding.request.args: Contains parameters parsed from the URL query string (e.g.,?id=5).request.values: A combinedMultiDictcontaining bothformandargs.
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 actualRuleobject from the URL map that matched the request. You can inspectrequest.url_rule.methodsto 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_argswould 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 theHTTPException(typically a404 NotFoundor405 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 Key | Description | Default |
|---|---|---|
MAX_CONTENT_LENGTH | Maximum bytes read during the request. | None |
MAX_FORM_MEMORY_SIZE | Maximum size for non-file form fields. | 500,000 |
MAX_FORM_PARTS | Maximum 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.