Python Flask
Tutorial 54 of 65 · pythondeck.com Python course
Flask is a micro web framework. Define routes with @app.route, return strings, dicts (auto-JSON) or rendered templates. Pair with Jinja2 for HTML and SQLAlchemy for persistence.
Flask is a microframework: routing, request context, and Jinja templates without prescribing ORM or project layout. Ideal for APIs, internal tools, and learning WSGI fundamentals.
Blueprints and application factories scale small codebases into maintainable services.
Because Flask stays minimal, you choose extensions deliberately—SQLAlchemy, Marshmallow, Flask-Login—rather than inheriting a monolithic stack you may not need.
App factory — create_app() with config objects per environment.
Routing — decorators, HTTP methods, URL converters.
Request context — request, g, session; thread-local per request.
Blueprints — modular routes and static files.
Extensions — Flask-SQLAlchemy, Flask-Login, marshmallow for common patterns.
WSGI deployment — gunicorn/waitress behind nginx, not flask dev server in prod.
Flask stays unopinionated—choose structure early: package by feature vs layer. Error handlers and logging hooks belong in factory setup. For JSON APIs, return consistent error envelopes and use after_request for security headers.
Async Flask (as of recent versions) helps I/O-bound views but WSGI workers remain process-based; compare with ASGI frameworks when WebSockets and long-lived connections dominate.
Template filters and context processors inject globals into Jinja; keep them thin. For JSON APIs, consider flask-smorest or similar for OpenAPI parity with larger frameworks.
Limit request body size at the reverse proxy to reduce abuse of file-upload endpoints.
Using the built-in development server in production.
Global mutable state on the app object shared across requests.
Secret key hardcoded; insecure cookie sessions for sensitive apps.
No CSRF protection on form endpoints using session auth.
Configure via environment-specific classes, never committed secrets.
Use blueprints + url_prefix for API versioning (/api/v1).
Test with flask test client and factory per test for isolation.
Run behind HTTPS-terminating proxy; set SESSION_COOKIE_SECURE.
Register CLI commands with flask cli for repeatable admin tasks beside HTTP routes.
Re-read the examples below with these ideas in mind; change variable names and inputs to match your own project.
The program below demonstrates hello flask. Read the comments on each line, run the code, then change names or values to see how the output shifts.
# Example: Hello Flask
# Run in the REPL or save as a .py file and execute with python.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "<h1>Hello from Flask</h1>"
if __name__ == "__main__":
app.run(debug=True)
This sample walks through json api in a small, runnable script. Paste it into the REPL or save it as a .py file before you continue to the next block.
# Example: JSON API
# Run in the REPL or save as a .py file and execute with python.
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.post("/api/echo")
def echo():
return jsonify(received=request.json)
Here is a hands-on illustration of url params + template. Follow the inline comments first; only then execute the snippet and compare the result with what you expected.
# Example: URL params + template
# Run in the REPL or save as a .py file and execute with python.
from flask import Flask, render_template_string
app = Flask(__name__)
@app.route("/hi/<name>")
def hi(name):
return render_template_string("<h1>Hello {{ n }}</h1>", n=name)
The program below demonstrates hello route. Read the comments on each line, run the code, then change names or values to see how the output shifts.
# Flask maps URL paths to Python callables
from flask import Flask, jsonify # micro web framework
app = Flask(__name__) # application object
@app.get("/") # register GET /
def home(): # view function
return jsonify(message="hello") # JSON response
@app.get("/health") # health check endpoint
def health(): # another view
return jsonify(ok=True) # simple status
if __name__ == "__main__": # dev server entry
app.run(debug=True) # listen on :5000
This sample walks through query params in a small, runnable script. Paste it into the REPL or save it as a .py file before you continue to the next block.
# request.args exposes query string values
from flask import Flask, request, jsonify # request proxy
app = Flask(__name__) # app
@app.get("/search") # /search?q=term
def search(): # handle query
q = request.args.get("q", "") # default empty
limit = int(request.args.get("limit", 10)) # cast with default
return jsonify(q=q, limit=limit) # echo inputs
if __name__ == "__main__": # run locally
app.run() # production uses WSGI server instead
Continue with these focused follow-up lessons on Python Flask: