Free workshop · 12 chapters · about 3 hours
Build a real API with FastAPI.
Step by step, you build Shelf, a small reading-list API that is ready for the real world: validation, a database, helpful errors, auth, tests, logs and a Docker image. No magic, just Python with type hints.
Meet Shelf.
Want to read it, reading it, done. Shelf keeps the list. Reads are open; writes need a key. Small enough for one afternoon, real enough to deploy.
- GET
/booksList books, with filters and pages - GET
/books/{book_id}One book - POST
/booksAdd a bookkey - PATCH
/books/{book_id}Change only what you sendkey - DELETE
/books/{book_id}Remove a bookkey - POST
/books/{book_id}/finishMark done, rate, log itkey - GET
/statsCounts and average rating - GET
/activityWhat happened recently - GET
/readyCan it serve traffic?
Request
POST /books
X-API-Key: dev-key-change-me
{ "title": "Piranesi", "author": "Susanna Clarke", "tags": ["Fantasy"] }Response201 Created
{
"id": 1,
"title": "Piranesi",
"author": "Susanna Clarke",
"status": "want",
"rating": null,
"tags": ["fantasy"]
}Real requests and responses from the API you will build, trimmed for space.
Everything a real API needs, nothing extra.
- Validation for freeType hints become rules. Bad input is refused with one clear message per field.Chapter 04
- A real databaseSQLAlchemy 2.0 with typed models, one session per request, safe parameterised queries.Chapter 05
- Errors that helpEvery error has the same problem+json shape and a request id. No stack traces leak.Chapter 07
- Protected writesAn API key checked in constant time, and a server that refuses the dev key in production.Chapter 08
- Tests that run in a blinkpytest with a fresh in-memory database per test. Lint and strict types in CI.Chapter 09
- Ready to shipRequest ids, JSON logs, health checks, and a small non-root Docker image.Chapter 12
Twelve short chapters.
See them all- 01Why FastAPI, and what we build10 minutes
- 02Set up and run it10 minutes
- 03Routes, path and query parameters15 minutes
- 04Pydantic models and validation20 minutes
- 05A real database with SQLAlchemy20 minutes
- 06Dependencies and settings15 minutes
- 07Errors that help15 minutes
- 08Protect writes with an API key15 minutes
- 09Test it with pytest20 minutes
- 10Middleware, request ids and logs15 minutes
- 11Background tasks and async15 minutes
- 12Ship it20 minutes
Running in a minute.
You need uv and git. uv installs Python 3.13 and the exact package versions for you. Then open the live docs and click around.
Full setup in chapter 02bash
git clone https://github.com/jars-demo/fastapi-demo.git
cd fastapi-demo/api
uv sync
uv run uvicorn app.main:app --reload
# open http://127.0.0.1:8000/docs