Flask Cheatsheet
Request Handling
Use this Flask reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
The request Object
from flask import request
request is a thread-local proxy — it is only valid inside a view function or a function called from one (or inside a manually pushed request context).
Query String Parameters
# GET /search?q=flask&page=2&tag=python&tag=web request.args.get("q") # "flask" request.args.get("page", 1, type=int) # 2 (converts, returns default on failure) request.args.getlist("tag") # ["python", "web"] request.args["q"] # KeyError if missing — prefer .get() dict(request.args) # {"q": ["flask"], "page": ["2"], ...}
Form Data (POST body)
# application/x-www-form-urlencoded or multipart/form-data request.form.get("username") request.form.get("age", type=int) request.form.getlist("colors") # multi-select checkbox values request.form["username"] # KeyError if missing
JSON Body
# Content-Type: application/json data = request.get_json() # dict or None data = request.get_json(force=True) # parse even without correct Content-Type data = request.get_json(silent=True) # return None on parse error (no 400)
request.jsonis a shortcut property — raises 400 if body is not valid JSON. Preferget_json(silent=True)for APIs.
File Uploads
# enctype="multipart/form-data" required in HTML form file = request.files.get("avatar") if file and file.filename: from werkzeug.utils import secure_filename import os filename = secure_filename(file.filename) # sanitize path file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename)) # file.read() → bytes # file.stream → file-like object # file.mimetype → "image/png" # file.content_length → int or None
Multiple files:
files = request.files.getlist("photos") for f in files: f.save(...)
Request Attributes Quick Reference
| Attribute | Type | Description |
|---|---|---|
request.method | str | "GET", "POST", etc. |
request.url | str | Full URL including query string |
request.base_url | str | URL without query string |
request.host | str | host:port |
request.host_url | str | scheme://host/ |
request.root_url | str | scheme://host/app_root/ |
request.path | str | Path only, no query string |
request.full_path | str | Path + query string |
request.script_root | str | WSGI SCRIPT_NAME prefix |
request.endpoint | str | Matched endpoint name |
request.view_args | dict | URL variable values |
request.args | ImmutableMultiDict | Query string params |
request.form | ImmutableMultiDict | Form body params |
request.files | ImmutableMultiDict | Uploaded files |
request.json | Any | Parsed JSON body |
request.data | bytes | Raw request body |
request.headers | Headers | Request headers (case-insensitive) |
request.cookies | dict | Incoming cookies |
request.environ | dict | Raw WSGI environ |
request.remote_addr | str | Client IP (may be proxy IP) |
request.referrer | str | None | Referer header |
request.user_agent | UserAgent | Parsed User-Agent |
request.content_type | str | Content-Type without params |
request.content_length | int | None | Body size in bytes |
request.is_json | bool | True if JSON content type |
request.is_secure | bool | True if HTTPS |
request.is_xhr | bool | True if X-Requested-With: XMLHttpRequest |
Headers
request.headers["Authorization"] # KeyError if missing request.headers.get("X-Api-Key") # None if missing request.headers.get("Content-Type") # case-insensitive lookup dict(request.headers) # all headers as dict
Raw Body
request.data # bytes; only populated if not form/files request.get_data() # bytes; always reads body request.get_data(cache=False) # don't cache body (saves memory for large bodies) request.stream # file-like, for streaming uploads
Request Context Locals
from flask import g # g is per-request storage, cleared after each request g.user = load_user_from_db() g.db = get_db_connection() g.get("user", None) # safe access with default
Accessing Request Outside View
Push a context manually for scripts/tests:
with app.test_request_context("/search?q=flask", method="GET"): print(request.args["q"]) # "flask"
Content Negotiation
request.accept_mimetypes.best_match(["application/json", "text/html"]) # returns "application/json" or "text/html" based on Accept header request.accept_languages.best_match(["en", "fr"])
Trusted Proxies (ProxyFix)
When running behind a reverse proxy (nginx, load balancer):
from werkzeug.middleware.proxy_fix import ProxyFix app.wsgi_app = ProxyFix( app.wsgi_app, x_for=1, # X-Forwarded-For hops to trust x_proto=1, # X-Forwarded-Proto x_host=1, # X-Forwarded-Host x_prefix=1, # X-Forwarded-Prefix ) # Now request.remote_addr and request.is_secure are correct
Without ProxyFix,
request.remote_addrreturns the proxy's IP andrequest.is_secureis always False behind HTTPS proxies.