FastAPI cheat sheet
A scannable FastAPI reference: 13 short snippets across 10 topics, each linking back to the lesson it came from.
At a glance
| Topic | What it covers | |
|---|---|---|
| Your first FastAPI app | Path operations, type-driven validation, automatic OpenAPI docs, and the route-ordering trap that silently returns 422 | lesson |
| Pydantic request and response models | Define the wire contract with Pydantic: validation, custom validators, and response models that stop internal fields | lesson |
| Path, query and body parameters in depth | A parameter in the route string is a path parameter. FastAPI converts it using the type annotation, and a value that | lesson |
| Routers, project layout and API versioning | The rule that keeps this maintainable: routers translate HTTP to function calls, services hold the logic, and services | lesson |
| Databases with SQLAlchemy and session dependencies | The yield dependency guarantees the session closes even when the endpoint raises. Without it, a failing request leaks a | lesson |
| Authentication with OAuth2, JWT and password hashing | A JWT is signed, not encrypted: anyone can read the payload. Put only an identifier and authorisation claims in it | lesson |
| Error handling, middleware and CORS | Handlers registered for specific exception classes replace the default response entirely. Raising HTTPException stays | lesson |
| File uploads, streaming and WebSockets | A generator response starts sending headers immediately, so an error after the first chunk cannot become a 500 | lesson |
| Testing FastAPI apps with TestClient and pytest | Exercise endpoints without a running server, swap the database per test, write async tests with httpx, and assert the | lesson |
| Deployment: uvicorn workers, Docker and reverse proxies | Each worker is a separate process with its own memory. Module-level caches, in-memory rate limits and BackgroundTasks | lesson |
Quick snippets
Your first FastAPI app
The smallest app
pip install "fastapi[standard]"
fastapi dev main.py # reload on save, http://127.0.0.1:8000
uvicorn main:app --reload # equivalent, explicit ASGI server
curl http://127.0.0.1:8000/notes/1
curl "http://127.0.0.1:8000/notes/1?q=milk"Full lesson: Your first FastAPI app →
Pydantic request and response models
Request models
from fastapi import FastAPI
from schemas import NoteIn
app = FastAPI()
@app.post("/notes", status_code=201)
def create_note(note: NoteIn) -> dict[str, object]:
return {"stored": note.title, "tags": note.tags}Full lesson: Pydantic request and response models →
Path, query and body parameters in depth
Query parameters
from fastapi import Query
@app.get("/search")
def search(
q: Annotated[str, Query(min_length=2, max_length=80)],
page: Annotated[int, Query(ge=1)] = 1,
size: Annotated[int, Query(ge=1, le=100)] = 20,
sort: Annotated[str, Query(alias="order-by")] = "created_at",
tags: Annotated[list[str] | None, Query()] = None,
):
return {"q": q, "page": page, "size": size, "sort": sort, "tags": tags or []}
Query parameters
# repeated keys fill a list
curl "http://127.0.0.1:8000/search?q=hello&size=5&order-by=name&tags=a&tags=b"Full lesson: Path, query and body parameters in depth →
Routers, project layout and API versioning
APIRouter
# app/main.py
from fastapi import FastAPI
from .routers import items, users
app = FastAPI(title="Shop API", version="1.0.0")
app.include_router(items.router, prefix="/api/v1")
app.include_router(users.router, prefix="/api/v1")Full lesson: Routers, project layout and API versioning →
Databases with SQLAlchemy and session dependencies
Eager loading and transactions
from sqlalchemy.orm import selectinload
# N+1 avoided: one query for users, one for their items
users = db.scalars(
select(User).options(selectinload(User.items)).order_by(User.id).limit(50)
).all()
# a transaction block: roll back everything on error
with db.begin():
db.add(User(email="[email protected]"))
db.add(Item(name="widget", owner_id=1))Full lesson: Databases with SQLAlchemy and session dependencies →
Authentication with OAuth2, JWT and password hashing
Storing passwords
pip install "passlib[bcrypt]" "python-jose[cryptography]"Full lesson: Authentication with OAuth2, JWT and password hashing →
Error handling, middleware and CORS
CORS for browser clients
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://app.example.com"],
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE"],
allow_headers=["Authorization", "Content-Type"],
)Full lesson: Error handling, middleware and CORS →
File uploads, streaming and WebSockets
WebSockets
from fastapi import WebSocket, WebSocketDisconnect
@app.websocket("/ws/echo")
async def echo(ws: WebSocket):
await ws.accept()
try:
while True:
message = await ws.receive_text()
await ws.send_text(f"echo: {message}")
except WebSocketDisconnect:
logger.info("client disconnected")Full lesson: File uploads, streaming and WebSockets →
Testing FastAPI apps with TestClient and pytest
TestClient basics
def test_create_and_read(client):
created = client.post("/api/v1/items", json={"name": "widget", "price": 9.99})
assert created.status_code == 201
body = created.json()
assert body["name"] == "widget"
fetched = client.get(f"/api/v1/items/{body['id']}")
assert fetched.status_code == 200
assert fetched.json()["price"] == 9.99
Async tests with httpx
pip install pytest pytest-asyncio httpx
Async tests with httpx
import pytest
from httpx import ASGITransport, AsyncClient
from app.main import app
@pytest.mark.anyio
async def test_health():
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as ac:
r = await ac.get("/health")
assert r.status_code == 200
assert r.json() == {"status": "ok"}Full lesson: Testing FastAPI apps with TestClient and pytest →
Deployment: uvicorn workers, Docker and reverse proxies
Workers
# development: one process, reload on change
uvicorn app.main:app --reload --port 8000
# production: several processes, no reload
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4 --no-access-log
# or a process manager around uvicorn
gunicorn app.main:app -k uvicorn.workers.UvicornWorker -w 4 --timeout 60 --graceful-timeout 30Full lesson: Deployment: uvicorn workers, Docker and reverse proxies →
FAQ
Is this FastAPI cheat sheet free to use?
Where do the examples come from?
How do I go deeper than a cheat sheet?
Related cheat sheets
Python 3 NumPy pandas Matplotlib Jupyter Notebook Flask
Last refreshed 2026-09-27.