Part 4: FastAPI backend from the spec
We have a frontend in frontend/ and an openapi.yaml at the repo root that
describes the backend it expects. Now we build that backend with FastAPI,
driven by the assistant and the spec. To keep this step about the web layer and
not about databases, the backend starts on an in-memory store. That's good
enough to return real responses and pass tests, with no database to install. We
swap in a real database in Part 7: Real persistence with SQLite.
Set up the backend project
Create the backend next to the frontend and initialize it with uv:
mkdir backend
cd backend
uv init
Tell the assistant the house rules
Coding assistants guess at tooling unless you tell them, and left alone one will
reach for pip and a requirements.txt. We use uv, so we write that down once
in an AGENTS.md file at the repo root. The assistant reads it automatically
from anywhere in the project.
Create AGENTS.md at the repo root:
for backend, use uv for dependency management. a few useful commands:
uv sync
uv add <PACKAGE-NAME>
uv run python <PYTHON-FILE>
regularly commit code to git
It's deliberately short, to remove a class of avoidable mistakes such as the wrong package manager or forgotten commits, rather than to write a manual.
Build the backend
Now point the assistant at the spec and ask for the implementation. The spec is the target, the mock store keeps the step simple, and the tests give us a way to know it works.
Use this prompt:
Build a FastAPI backend in backend/ that implements the openapi.yaml in the
parent directory. Use an in-memory store for now (no database yet) and seed it
with a few fake users, scores, and active games so the frontend has something
to show. Add authentication with hashed passwords and bearer tokens for the
endpoints that need it. Split the code into modules - routers, models, auth.
Write tests. Follow AGENTS.md.
The assistant adds the dependencies with uv add, then lays out an app like
this:
backend/
├── app/
│ ├── main.py # FastAPI app, CORS, mounts the routers under /api
│ ├── routers/ # auth.py, leaderboard.py, games.py
│ ├── models.py # Pydantic request/response models
│ └── auth.py # password hashing + JWT bearer tokens
└── tests/ # one test file per router
Each router maps straight to a group in the spec.
authhandles signup, login, logout, andme.leaderboardhandles reading and submitting scores.gamesserves the active games.
main.py mounts them all under /api and turns on CORS so the frontend can
call the backend from a different port during local development.
Run and verify it
Start the server with auto-reload:
uv run uvicorn app.main:app --reload --port 8000
FastAPI publishes interactive docs from the running code at
http://localhost:8000/api/docs. Open it, try the signup and login endpoints,
and submit a score. This live spec is generated from the actual routes. Comparing
it against the openapi.yaml we wrote in
Part 3: OpenAPI spec from the frontend is a quick way to confirm the backend
matches the agreed API.
Run the tests too:
uv run pytest
The backend grows into its finished database-backed form over the next parts. Next we connect the frontend to this backend and run both together in Part 5: Connect frontend and backend.