Flask Cheatsheet

Request Handling

Use this Flask reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

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.json is a shortcut property — raises 400 if body is not valid JSON. Prefer get_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

AttributeTypeDescription
request.methodstr"GET", "POST", etc.
request.urlstrFull URL including query string
request.base_urlstrURL without query string
request.hoststrhost:port
request.host_urlstrscheme://host/
request.root_urlstrscheme://host/app_root/
request.pathstrPath only, no query string
request.full_pathstrPath + query string
request.script_rootstrWSGI SCRIPT_NAME prefix
request.endpointstrMatched endpoint name
request.view_argsdictURL variable values
request.argsImmutableMultiDictQuery string params
request.formImmutableMultiDictForm body params
request.filesImmutableMultiDictUploaded files
request.jsonAnyParsed JSON body
request.databytesRaw request body
request.headersHeadersRequest headers (case-insensitive)
request.cookiesdictIncoming cookies
request.environdictRaw WSGI environ
request.remote_addrstrClient IP (may be proxy IP)
request.referrerstr | NoneReferer header
request.user_agentUserAgentParsed User-Agent
request.content_typestrContent-Type without params
request.content_lengthint | NoneBody size in bytes
request.is_jsonboolTrue if JSON content type
request.is_secureboolTrue if HTTPS
request.is_xhrboolTrue 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

Cookies

request.cookies.get("session_id")
request.cookies["theme"]                  # KeyError if missing

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_addr returns the proxy's IP and request.is_secure is always False behind HTTPS proxies.