Flask Python micro web framework

Version 3.1 · source

Start here

flask --app <module> run
Start the dev server
flask --app <module> run --debug
Reloader and debugger on
flask run -p <port>
Use another port
flask routes
List all URL rules
flask shell
Python shell with app context
@app.route("/")
Map a URL to a function
render_template("<file>.html", x=1)
Render a Jinja template
url_for("<endpoint>")
Build a URL

Concepts

  1. Request from the browser
  2. View function @app.route
  3. Response str, dict, tuple
  4. Client HTML or JSON

Run

flask --app <module> run
Start the dev server
Serves on http://127.0.0.1:5000 by default.
flask --app <module> run --debug
Run with reloader and debugger
Never expose debug mode to untrusted networks.
flask run -p <port>
Listen on another port
flask run --no-reload
Debugger without the reloader

Config & discovery

flask --app <module>:<name> routes
Pick the app variable explicitly
flask --app "<module>:create_app('<arg>')" run
Call an app factory with arguments
Arguments are parsed as Python literals.
FLASK_APP=<module>
Environment form of --app
pip install python-dotenv
Enable .env and .flaskenv loading
.flaskenv is for public values; keep .env out of git.

Shell & routes

flask shell
Python shell with the app context pushed
flask routes
List routes, endpoints and methods

Custom commands

@app.cli.command("<name>")
Register flask <name>
Runs with an app context.
@click.option("--<flag>")
Add an option to the command

Routing

@app.route("/")
Bind a URL to a view
@app.route("/user/<name>")
Dynamic URL part
@app.route("/post/<int:id>")
Typed converter
Converters: string, int, float, path, uuid.
@app.route("/login", methods=["GET", "POST"])
Accept more HTTP methods
Routes answer GET only by default; HEAD and OPTIONS are automatic.
@app.post("/login")
Method shortcut decorator
Also get, put, delete, patch.
url_for("<endpoint>", id=1)
Build the URL for a view
Unknown keywords become query parameters.
url_for("static", filename="<file>")
URL of a static file
Blueprint("<name>", __name__)
Group routes into a module
app.register_blueprint(<bp>, url_prefix="/<p>")
Attach a blueprint

Requests

request.method
HTTP method of the request
request.args.get("<key>")
Query string value
Use get; [] raises a 400 if missing.
request.form["<key>"]
Form field from POST
request.get_json()
Parsed JSON body
request.files["<name>"]
Uploaded file
Form needs enctype="multipart/form-data".
file.save(secure_filename(file.filename))
Store an upload safely
Never trust the client filename.

Responses

return "<p>Hi</p>"
String becomes a 200 HTML response
return {"a": 1}
Dict or list becomes JSON
return <body>, 404
Body plus status code
Also (body, status, headers).
redirect(url_for("<endpoint>"))
Redirect to another view
abort(404)
Stop with an HTTP error
resp.set_cookie("<name>", "<value>")
Set a cookie on a response
@app.errorhandler(404)
Custom error page
Return the template and the status, e.g. return render_template(...), 404.

Templates & state

render_template("<file>.html", x=1)
Render templates/<file>.html
{{ x }}
Print an escaped value in Jinja
{% extends "base.html" %}
Inherit a layout
app.secret_key = <bytes>
Key needed for sessions and flash
Generate one with python -c 'import secrets; print(secrets.token_hex())'.
session["<key>"] = <value>
Per-user data in a signed cookie
flash("<msg>")
Message for the next request

Recipes

Minimal app
app = Flask(__name__)@app.route("/")def hello():    return "<p>Hi</p>"
Dotenv defaults
# .flaskenvFLASK_APP=appFLASK_RUN_PORT=8000# .env (not committed)SECRET_KEY=<random>
JSON endpoint
@app.post("/api/items")def add():    d = request.get_json()    return {"name": d["name"]}, 201