A tiny CRUD REST API for managing a list of tasks, built with FastAPI. The "database" is just an in-memory Python list, so it resets every time the server restarts — the point of this project is the HTTP layer, not persistence.
It was built stage by stage as a first backend project: hello-world server → info/health endpoints → read → create → update/delete → interactive docs.
- Python 3.11+ (developed on 3.14)
From the project folder, create a virtual environment, activate it, install the dependencies, and start the server:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -r requirements.txt
python -m uvicorn main:app --reloadThe API is now live at http://localhost:8000, and interactive Swagger docs are at http://localhost:8000/docs.
Once the virtual environment is active you can drop the
python -mprefix and just runpip ...anduvicorn ....
| Method | Path | Description | Success | Errors |
|---|---|---|---|---|
| GET | / |
API info (name, version, endpoints) | 200 | — |
| GET | /health |
Liveness check — {"status":"ok"} |
200 | — |
| GET | /tasks |
List all tasks | 200 | — |
| GET | /tasks/{id} |
Get one task by id | 200 | 404 if id unknown |
| POST | /tasks |
Create a task from {"title": "…"} |
201 | 400 if title missing/empty |
| PUT | /tasks/{id} |
Update title and/or done |
200 | 404 if id unknown · 400 if body has neither field |
| DELETE | /tasks/{id} |
Delete a task | 204 | 404 if id unknown |
{ "id": 1, "title": "Read the FastAPI tutorial", "done": true }Task-level errors (400 and 404 above) come back as { "error": "message" }.
Input that isn't valid JSON of the right type — e.g. GET /tasks/abc — is
rejected by FastAPI before it reaches the handler and uses FastAPI's default
422 validation shape ({ "detail": [ ... ] }).
$ curl -i http://localhost:8000/tasks/1
HTTP/1.1 200 OK
date: Wed, 02 Sep 2026 17:22:05 GMT
server: uvicorn
content-length: 56
content-type: application/json
{"id":1,"title":"Read the FastAPI tutorial","done":true}
Requesting an unknown id:
$ curl -i http://localhost:8000/tasks/99
HTTP/1.1 404 Not Found
content-type: application/json
{"error":"Task 99 not found"}
Creating a task:
curl -i -X POST http://localhost:8000/tasks \
-H "Content-Type: application/json" \
-d '{"title":"Buy milk"}'
# → 201 Created
# {"id":4,"title":"Buy milk","done":false}FastAPI generates interactive documentation from the code. Every endpoint is listed with a Try it out button that sends real requests.
Running GET /tasks straight from the docs page:
task-api/
├── main.py # the whole API — routes + in-memory data
├── requirements.txt # FastAPI + uvicorn
├── docs/ # Swagger UI screenshots
└── README.md

