Documentation Index Fetch the complete documentation index at: https://mintlify.com/pallets/flask/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Flask provides Request and Response objects that wrap Werkzeug’s WSGI request and response handling with Flask-specific enhancements.
Request Object
The request object is a global proxy that provides access to incoming request data.
Accessing Request Data
from flask import Flask, request
app = Flask( __name__ )
@app.route ( '/search' )
def search ():
# Query parameters
query = request.args.get( 'q' , '' )
page = request.args.get( 'page' , 1 , type = int )
# Form data (POST)
username = request.form.get( 'username' )
# JSON data
data = request.get_json()
# Headers
user_agent = request.headers.get( 'User-Agent' )
# Cookies
session_id = request.cookies.get( 'session_id' )
return jsonify({ 'query' : query, 'page' : page})
Request Properties
From wrappers.py:18-54, the Flask Request class provides:
# URL information
request.url # Full URL
request.base_url # URL without query string
request.url_root # Root URL
request.path # Path portion
request.query_string # Raw query string (bytes)
# Method and routing
request.method # HTTP method (GET, POST, etc.)
request.endpoint # Matched endpoint name
request.view_args # URL parameter dict
request.url_rule # Matched Rule object
# Client information
request.remote_addr # Client IP address
request.user_agent # User agent string
request.referrer # Referring URL
Request Data Sources
Query String
Access GET parameters:
# URL: /search?q=flask&category=web
@app.route ( '/search' )
def search ():
query = request.args.get( 'q' ) # 'flask'
category = request.args.get( 'category' ) # 'web'
# Get with default
page = request.args.get( 'page' , 1 , type = int )
# Get list of values
tags = request.args.getlist( 'tag' )
return jsonify(request.args.to_dict())
Access POST form data:
@app.route ( '/login' , methods = [ 'POST' ])
def login ():
username = request.form[ 'username' ] # KeyError if missing
password = request.form.get( 'password' ) # None if missing
# Check if key exists
if 'remember_me' in request.form:
# Set remember cookie
pass
return redirect( '/dashboard' )
JSON Data
Parse JSON request bodies:
@app.route ( '/api/users' , methods = [ 'POST' ])
def create_user ():
# Automatically parses JSON
data = request.get_json()
# Force parsing even without Content-Type
data = request.get_json( force = True )
# Silent mode (returns None on error)
data = request.get_json( silent = True )
if data:
name = data.get( 'name' )
email = data.get( 'email' )
return jsonify({ 'id' : 123 , 'name' : name}), 201
return jsonify({ 'error' : 'Invalid JSON' }), 400
File Uploads
Handle uploaded files:
from werkzeug.utils import secure_filename
@app.route ( '/upload' , methods = [ 'POST' ])
def upload_file ():
if 'file' not in request.files:
return 'No file part' , 400
file = request.files[ 'file' ]
if file .filename == '' :
return 'No selected file' , 400
if file :
filename = secure_filename( file .filename)
file .save( f '/uploads/ { filename } ' )
return 'File uploaded' , 201
Raw Data
Access raw request body:
@app.route ( '/webhook' , methods = [ 'POST' ])
def webhook ():
# Raw bytes
raw_data = request.data
# As text
text_data = request.get_data( as_text = True )
# Stream for large files
stream = request.stream
return 'OK'
Request Limits
From wrappers.py:60-144, Flask provides security limits:
# Application-level defaults
app.config[ 'MAX_CONTENT_LENGTH' ] = 16 * 1024 * 1024 # 16 MB
app.config[ 'MAX_FORM_MEMORY_SIZE' ] = 500_000 # 500 KB
app.config[ 'MAX_FORM_PARTS' ] = 1_000
# Per-request override
@app.route ( '/upload' , methods = [ 'POST' ])
def upload ():
request.max_content_length = 50 * 1024 * 1024 # 50 MB for this route
# ... handle upload
Blueprint Context
From wrappers.py:162-195, access blueprint information:
@app.route ( '/admin/users' )
def admin_users ():
# Current blueprint name
blueprint = request.blueprint # 'admin'
# All blueprint names in hierarchy
blueprints = request.blueprints # ['admin']
# Endpoint includes blueprint
endpoint = request.endpoint # 'admin.users'
Response Object
The Response object represents the HTTP response sent to the client.
Creating Responses
Simple Responses
from flask import Flask, Response
app = Flask( __name__ )
@app.route ( '/' )
def index ():
# String response (converted to Response)
return 'Hello, World!'
@app.route ( '/json' )
def json_response ():
# Dict/list (converted to JSON)
return { 'message' : 'Hello' , 'status' : 'success' }
@app.route ( '/custom' )
def custom ():
# Explicit Response object
return Response( 'Custom response' , mimetype = 'text/plain' )
Response Tuples
Return status code and headers:
@app.route ( '/created' )
def created ():
# (body, status)
return 'Resource created' , 201
@app.route ( '/with-headers' )
def with_headers ():
# (body, status, headers)
return 'OK' , 200 , { 'X-Custom' : 'value' }
@app.route ( '/json-created' )
def json_created ():
# (body, headers) - status inferred
return { 'id' : 123 }, { 'Location' : '/api/resource/123' }
Response Properties
From wrappers.py:222-258:
@app.route ( '/example' )
def example ():
response = Response( 'Hello' )
# Status
response.status_code = 200
response.status = '200 OK'
# Headers
response.headers[ 'X-Custom' ] = 'value'
response.headers[ 'Content-Type' ] = 'application/json'
# Cookies
response.set_cookie( 'session' , 'abc123' )
# MIME type
response.mimetype = 'text/html' # Default for Flask
return response
Setting Cookies
Manage cookies in responses:
@app.route ( '/login' , methods = [ 'POST' ])
def login ():
response = make_response(redirect( '/dashboard' ))
# Simple cookie
response.set_cookie( 'username' , 'john' )
# With options
response.set_cookie(
'session_id' ,
'abc123' ,
max_age = 3600 , # 1 hour
secure = True , # HTTPS only
httponly = True , # No JavaScript access
samesite = 'Lax' # CSRF protection
)
return response
@app.route ( '/logout' )
def logout ():
response = make_response(redirect( '/' ))
response.delete_cookie( 'session_id' )
return response
make_response()
Convert return values to Response objects (from app.py:1224-1273):
from flask import make_response
@app.route ( '/custom' )
def custom ():
# String to Response
response = make_response( 'Hello' )
response.headers[ 'X-Custom' ] = 'value'
return response
@app.route ( '/render' )
def render ():
# Template to Response
html = render_template( 'page.html' )
response = make_response(html)
response.headers[ 'X-Page' ] = 'home'
return response
JSON Responses
Flask provides convenient JSON handling:
from flask import jsonify
@app.route ( '/api/user/<int:id>' )
def get_user ( id ):
user = { 'id' : id , 'name' : 'John' , 'email' : 'john@example.com' }
# jsonify() sets Content-Type to application/json
return jsonify(user)
@app.route ( '/api/users' )
def list_users ():
users = [{ 'id' : 1 , 'name' : 'John' }, { 'id' : 2 , 'name' : 'Jane' }]
return jsonify(users)
@app.route ( '/api/error' )
def error ():
return jsonify({ 'error' : 'Not found' }), 404
Streaming Responses
Stream large responses:
from flask import stream_with_context
@app.route ( '/large-file' )
def large_file ():
def generate ():
with open ( 'large_file.txt' ) as f:
for line in f:
yield line
return Response(generate(), mimetype = 'text/plain' )
@app.route ( '/events' )
def events ():
def generate ():
for i in range ( 10 ):
yield f 'data: { i } \n\n '
time.sleep( 1 )
return Response(generate(), mimetype = 'text/event-stream' )
File Downloads
Send files to clients:
from flask import send_file, send_from_directory
@app.route ( '/download/<filename>' )
def download ( filename ):
return send_from_directory( 'files' , filename, as_attachment = True )
@app.route ( '/report' )
def report ():
# Send file-like object
buffer = BytesIO()
buffer.write( b 'Report content' )
buffer.seek( 0 )
return send_file(
buffer,
mimetype = 'application/pdf' ,
as_attachment = True ,
download_name = 'report.pdf'
)
Request Context
The request object is context-local, available only during request handling:
from flask import request, has_request_context
def get_user_ip ():
if has_request_context():
return request.remote_addr
return None
@app.route ( '/' )
def index ():
ip = get_user_ip() # Works here
return f 'Your IP: { ip } '
# Outside request context
ip = get_user_ip() # Returns None
Modifying Responses
After Request Handlers
Modify all responses:
@app.after_request
def add_header ( response ):
response.headers[ 'X-Custom-Header' ] = 'value'
response.headers[ 'Cache-Control' ] = 'no-store'
return response
Per-Request Modifications
Modify specific request responses:
from flask import after_this_request
@app.route ( '/special' )
def special ():
@after_this_request
def add_special_header ( response ):
response.headers[ 'X-Special' ] = 'true'
return response
return 'Special page'
Best Practices
Validate Input Always validate and sanitize request data
Set Limits Configure MAX_CONTENT_LENGTH to prevent DOS attacks
Use get() Method Use .get() instead of dict access to avoid KeyError
Secure Cookies Always use secure, httponly cookies for sensitive data