FastAPI Expert Skill
Idiomatic FastAPI service generation and review - an Agent Skill for Python 3.14, FastAPI 0.115+, and Pydantic 2.
What This Skill Does
Produces a deployable API checklist: src/ layout, pyproject.toml with uv, router modules, settings via pydantic-settings, /health and /ready, structured logging, pytest + httpx tests, and Dockerfile stub.
When to Invoke
- New microservice in a monorepo or standalone repo
- Reviewing a PR for FastAPI anti-patterns (sync DB in async route, missing validation)
- Splitting a Flask script into a typed API service
- Standardizing hackathon code before production hardening
Inputs
| Input | Why |
|---|---|
| Service name | Package name, log field, Docker image tag |
| Sync vs async DB | AsyncSession + asyncpg vs sync SQLAlchemy |
| Auth model | None, API key, OAuth2 JWT |
| Port default | 8000 or platform convention |
| Monorepo path | services/billing-api vs root repo |
Outputs
pyproject.tomlwithfastapi,uvicorn[standard],pydantic-settings,httpx,pytestapp/main.pywith lifespan, CORS policy stub, router includesapp/settings.pywithBaseSettingsand.env.exampleapp/routers/health.pywith/healthand/readytests/test_health.pyusingTestClientorhttpx.ASGITransport- Verification command block
Guardrails
- Pydantic v2 -
model_validate,Field(alias=...), not v1.dict(). - No secrets in generated files -
.env.exampleplaceholders only. - Health routes before domain routes - load balancers need them day one.
- Structured logging -
loggingJSON orstructlog- no bareprintin prod paths. - Async routes must not block - no sync
requestsor heavy CPU withoutto_thread. requires-python >= 3.14when org standard allows - document 3.13 fallback if needed.
Recipe
cd services/billing-api
uv sync
uv run ruff check .
uv run pytest -q
uv run uvicorn app.main:app --reload &
curl -sf http://localhost:8000/health
curl -sf http://localhost:8000/readyWorking Example (app skeleton)
# app/main.py
from contextlib import asynccontextmanager
from fastapi import FastAPI
from app.routers import health
@asynccontextmanager
async def lifespan(app: FastAPI):
yield
app = FastAPI(title="billing-api", lifespan=lifespan)
app.include_router(health.router)# app/routers/health.py
from fastapi import APIRouter
router = APIRouter(tags=["health"])
@router.get("/health")
def health() -> dict[str, str]:
return {"status": "ok"}
@router.get("/ready")
def ready() -> dict[str, str]:
return {"status": "ready"}FAQs
FastAPI or Django for this service?
FastAPI for IO-bound JSON APIs. Django when admin, ORM monolith, and templates are core - skill does not override ADR.
Include SQLModel in scaffold?
Only when input specifies persistence day one - otherwise stub repository protocol and add DB in follow-up PR.
Gunicorn or uvicorn?
uvicorn for dev; production often gunicorn -k uvicorn.workers.UvicornWorker behind reverse proxy.
Related
- FastAPI Basics - human cookbook
- Testing FastAPI - TestClient patterns
- pydantic-settings - configuration
- Packaging & Publishing Skill - PyPI layout
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.