A compact FastAPI demo app that covers the core API concepts discussed in the docs: validation, pagination, partial updates, rich logging, monitoring endpoints, and HTTP behavior. Authentication and multi-cloud deployment patterns remain in the documentation.
- A realistic in-memory resource API under
/api/v1/books - Rich request logging with latency, size, status, client, and request IDs
- Lightweight health, redirect, and method-demo endpoints for smoke testing and tooling demos
- Optional background traffic generation for local demos
- Optional forced-error headers for testing unhappy paths without creating fake routes
- The live app demonstrates API and observability concepts from the docs
- The docs cover broader topics like JWT, managed identity, enterprise SSO, and cloud deployment guidance
- The local demo does not provision cloud resources or implement full identity-provider integrations
- Python 3.14 or higher
- uv
uv sync --group dev
source .venv/bin/activate # On Windows: .venv\Scripts\activateuvicorn main:app --reload --no-access-logThe API is available at http://127.0.0.1:8000.
- Swagger UI:
http://127.0.0.1:8000/docs - ReDoc:
http://127.0.0.1:8000/redoc
Enable background traffic generation:
ENABLE_TRAFFIC_GENERATOR=true uvicorn main:app --reload --no-access-logEnable forced error responses through the X-Force-Error header:
ENABLE_CHAOS_HEADERS=true uvicorn main:app --reload --no-access-logAllowed forced error codes are 400, 404, 409, 500, and 503.
GET /returns API metadata and local docs linksGET /api/psreturns a health payload and book countHEAD /api/statusreturnsX-System-Status: OKOPTIONS /api/optionsreturns supported methodsGET /api/redirectreturns a307to a seeded book
Base URL: http://127.0.0.1:8000/api/v1
GET /books?skip=0&limit=20lists books with paginationGET /books/search?q=codesearches title and author fieldsPOST /bookscreates a bookGET /books/{book_id}fetches a single bookPATCH /books/{book_id}applies a partial updateDELETE /books/{book_id}deletes a book
# List books
curl "http://127.0.0.1:8000/api/v1/books?skip=0&limit=10"
# Create a book
curl -X POST http://127.0.0.1:8000/api/v1/books \
-H "Content-Type: application/json" \
-d '{
"title": "Refactoring",
"author": "Martin Fowler",
"year": 2018
}'
# Partial update
curl -X PATCH http://127.0.0.1:8000/api/v1/books/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
-H "Content-Type: application/json" \
-d '{"year": 2022}'
# Search
curl "http://127.0.0.1:8000/api/v1/books/search?q=martin"
# Forced error demo
curl http://127.0.0.1:8000/api/v1/books \
-H "X-Force-Error: 503"uv run pytestmake checkIf you want to run the split CI paths locally:
make check-backend
make check-docsTo apply formatting locally:
make fixInstall local git hooks once per clone to automatically run the repo fix loop before every commit:
make install-hooksWith hooks installed:
- pre-commit runs
make fixandmake check - pre-push runs
make check - direct pushes to
mainare blocked by default unless you explicitly setALLOW_PROD_PUSH=true
Example intentional main push:
ALLOW_PROD_PUSH=true git push origin mainDocs deployment to GitHub Pages is manual-only.
Use workflow_dispatch and set the input confirm_production_deploy to YES.
This explicit confirmation prevents accidental production deploys.
Every request is logged with:
- Timestamp
- Status code
- Latency
- Response size
- Client IP
- HTTP method
- Request path
X-Request-ID
python-demo/
├── main.py
├── tests/
├── pyproject.toml
├── README.md
└── website/
The website under website/ contains the broader auth and multi-cloud deployment guidance. The backend and README now define the local source of truth for the live demo API.
If another team wants to build an MCP server or other machine-ingestion workflow from this repo, prefer these sources in this order:
website/static/openapi.jsonfor the live API contractwebsite/static/docs-index.jsonfor the curated docs manifestwebsite/static/llms.txtfor the concise crawler entrypointwebsite/build/sitemap.xmlor the deployed/sitemap.xmlfor URL discoverywebsite/docs/**/*.mdfor the canonical prose source
The running API also exposes GET /openapi.json automatically through FastAPI, and GET / now returns docs_url, redoc_url, and openapi_url to make those entry points explicit.
These artifacts are generated from source, not meant to be hand-maintained.
To refresh the checked-in machine-readable artifacts after changing routes, models, or docs:
uv run python scripts/generate_machine_artifacts.pyFor normal development, prefer make fix instead of calling the generator by hand. It regenerates artifacts, runs formatters in the correct order, regenerates again after docs formatting, and then validates the repo.
For the full automation loop, use one of these entrypoints:
make fix # auto-fix, regenerate, then validate everything
make check # validate only, no file changesThe same loop is available without make:
uv run python scripts/repo_loop.py fix
uv run python scripts/repo_loop.py checkfix runs generation before and after formatting so the docs formatter cannot leave docs-index.json or llms.txt stale.
Workflow split:
CIstays read-only and fails on drift.- The
backendCI job validates Python code only. - The
docsCI job owns generated artifact verification plus site formatting, typechecking, and build checks. Autofix Repo Standardsruns on pushes tomain, appliesmake fix, and opens or updates an automation PR instead of pushing directly tomain.
See scripts/README.md for the script-level details and how the loop fits into the repo.
CI also verifies that website/static/openapi.json, website/static/docs-index.json, and website/static/llms.txt are up to date.