Part 5: 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 ask the assistant to build the backend using the spec we just created.

Set up the backend project

Create the backend next to the frontend and initialize it with uv:

mkdir backend
cd backend
uv init

Build the backend

Now ask the assistant to create a FastAPI backend from the spec. We start with an in-memory store rather than a real database, so we can test the frontend-backend connection first. We'll switch to a proper database once it works.

Use this prompt:

Build a FastAPI backend in backend/ that implements the openapi.yaml spec

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, store, auth

Write tests

The assistant adds the dependencies with uv add, then lays out an app like this:

backend/
├── main.py            # entrypoint: starts uvicorn for app.main:app
├── app/
│   ├── main.py        # FastAPI app, CORS, mounts the routers under /api
│   ├── routers/       # auth.py, scores.py, active_games.py
│   ├── models.py      # Pydantic request/response models
│   ├── store.py       # the data store (in-memory now, a database later)
│   ├── security.py    # password hashing
│   └── auth.py        # bearer-token auth
└── tests/             # one test file per router

The tokens here are plain random bearer tokens, not JWTs. Passwords are hashed with the standard library, which is enough for a workshop and easy to read.

Each router maps straight to a group in the spec.

  • auth handles signup, login, logout, and me.
  • scores handles reading and submitting scores for the leaderboard.
  • active_games serves the active games to spectate.

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 the generated main.py, which runs uvicorn with auto-reload on port 8000:

uv run python main.py

FastAPI publishes interactive docs from the running code at http://localhost:8000/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 4: OpenAPI spec from the frontend is a quick way to confirm the backend matches the agreed API.

Run the tests too:

uv run pytest

Commit the backend:

git add .
git commit -m "Add FastAPI backend"

In the next parts, we add SQLAlchemy persistence and move the backend from an in-memory store to a database-backed implementation. First, though, we collect our commands into a Makefile in Part 6: A Makefile for the project.

Questions & Answers

Sign up to ask questions, track your progress, and get access to other workshops · Already have an account? Sign in