REST APIs with FastAPI
FastAPI is Flask's modern successor — same simplicity, but type hints do triple duty:
- Editor autocomplete — IDEs know the shape of your data.
- Runtime validation — Pydantic rejects bad payloads with a clear 422 error.
- Auto-generated OpenAPI docs — visit
/docsfor a live Swagger UI,/redocfor ReDoc.
Core concepts
Pydantic models = your API contract
class TodoIn(BaseModel):
title: str = Field(min_length=1, max_length=200)
done: bool = False
If a client POSTs {"title": ""}, FastAPI auto-rejects with 422. You don't write validation code.
Response models
response_model=Todo filters output — you can't leak fields you didn't declare.
HTTPException
Raise HTTPException(404, "Not found") for typed error responses.
Async when you need it
Any handler can be async def — great for calling other APIs or an async DB driver like asyncpg.
Run it
uvicorn main:app --reload
Then open http://localhost:8000/docs.
Try it (mentally, before running locally)
- Add a
DELETE /todos/{todo_id}endpoint. - Add a query param
?done=truetoGET /todosthat filters.
3 graded exercises
Write the code, click Check. We’ll tell you exactly what to fix.
- Exercise 1
Create a FastAPI app with a
GET /route that returns{"ok": True}. Wrap it in aTestClient, call/, and print the value of theokfield from the JSON response. - Exercise 2
Define a Pydantic model
TodoInwithtitle: stranddone: bool = False. Add aPOST /todosroute that accepts aTodoInpayload and returns the dict plus anid: 1. POST{"title": "ship"}and print the returnedtitle. - Exercise 3
Add a
GET /todos/{todo_id}route. Iftodo_id > 100, raiseHTTPException(status_code=404). Otherwise return{"id": todo_id, "title": f"todo #{todo_id}"}. Call/todos/5and/todos/999, then print each response's status code on its own line.