Minimal app
Spins up a server immediately.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"ok": True}FastAPI 1.x patterns from the production track. Each snippet is a chunk you can paste into a real service today. Pair with the linked lessons for the full explanation.
Spins up a server immediately.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"ok": True}Typed path variables; FastAPI parses and validates.
@app.get("/items/{item_id}")
def read(item_id: int):
return {"id": item_id}Default values + types make them optional.
@app.get("/search")
def search(q: str | None = None, limit: int = 20):
...JSON in → validated model.
from pydantic import BaseModel
class ItemIn(BaseModel):
name: str
price: float
@app.post("/items")
def create(item: ItemIn):
...Filter what goes out. Prevents leaking internal fields.
class ItemOut(BaseModel):
id: int
name: str
@app.get("/items/{id}", response_model=ItemOut)
def get(id: int): ...Reject bad data with a clear message.
from pydantic import Field, field_validator
class Q(BaseModel):
name: str = Field(min_length=1, max_length=80)
@field_validator("name")
@classmethod
def strip(cls, v): return v.strip()Reusable injectable code — DB session, auth, settings.
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/users")
def list_users(db = Depends(get_db)):
...Stateless authentication.
def current_user(token: str = Depends(oauth2_scheme)):
payload = jwt.decode(token, SECRET, algorithms=["HS256"])
return get_user(payload["sub"])Non-blocking I/O — DB, HTTP calls.
import httpx
@app.get("/proxy")
async def proxy():
async with httpx.AsyncClient() as c:
r = await c.get("https://api.example.com")
return r.json()Fire-and-forget work after responding.
from fastapi import BackgroundTasks
@app.post("/email")
def send(msg: dict, bg: BackgroundTasks):
bg.add_task(write_log, msg)
return {"queued": True}Return a clean error response.
from fastapi import HTTPException
if not item:
raise HTTPException(status_code=404, detail="Not found")Map your domain errors to HTTP cleanly.
@app.exception_handler(MyDomainError)
async def handler(req, exc):
return JSONResponse({"error": str(exc)}, status_code=400)Sync-style API tests.
from fastapi.testclient import TestClient
client = TestClient(app)
def test_root():
r = client.get("/")
assert r.status_code == 200Default ASGI server for dev + simple prod.
uvicorn app:app --host 0.0.0.0 --port 8000
Slim production image.
FROM python:3.12-slim as base WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
Want to actually learn these patterns, not just paste them? Open the FastAPI cheatsheet track — each snippet has a full lesson behind it.