A small FastAPI service used to manage simple todo-style items. The project is intentionally lightweight so a reviewer can clone it, start it locally, and exercise one endpoint in under twenty minutes.
The service stores items in memory and exposes a minimal CRUD API for todo records. It is designed to be easy to run locally and easy to inspect with the auto-generated FastAPI docs at /docs.
Use the following concrete versions or newer:
The project does not require a database, external cache, or cloud service. It reads configuration from environment variables only when they are set.
app/main.py – FastAPI application and API routestests/test_api.py – Basic API verification testsrequirements.txt – Runtime and test dependencies.gitignore – Ignored local filesThis service has no required environment variables for local startup. All variables are optional and default to safe values.
| Variable | Example value | Source | Required? | Used for |
|---|---|---|---|---|
HOST |
0.0.0.0 |
shell or .env file |
No | Bind address for the Uvicorn server |
PORT |
8000 |
shell or .env file |
No | Port for the HTTP server |
If you do not set HOST or PORT, the service still starts on 0.0.0.0:8000.
python -m venv .venv
source .venv/bin/activate
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
uvicorn app.main:app --host 0.0.0.0 --port 8000
You can also start it with environment variables:
set HOST=0.0.0.0
set PORT=8000
python app/main.py
The app is ready when you see a Uvicorn startup log that includes the local URL, usually http://127.0.0.1:8000.
The API uses JSON for requests and responses.
Request:
curl http://127.0.0.1:8000/health
Example response:
{
"status": "ok",
"service": "readmedev-api"
}
Status codes:
200 OK – service is runningRequest:
curl http://127.0.0.1:8000/items
Example success response:
[
{
"id": 1,
"title": "Write README",
"completed": false
}
]
Status codes:
200 OK – list returned successfullyRequest body:
{
"title": "Write README",
"completed": false
}
Request:
curl -X POST http://127.0.0.1:8000/items \
-H "Content-Type: application/json" \
-d '{"title":"Write README","completed":false}'
Example success response:
{
"id": 1,
"title": "Write README",
"completed": false
}
Status codes:
201 Created – item created422 Unprocessable Entity – invalid payload, such as missing title or wrong field typesRequest:
curl http://127.0.0.1:8000/items/1
Example success response:
{
"id": 1,
"title": "Write README",
"completed": false
}
Status codes:
200 OK – item exists404 Not Found – item ID does not existRequest body (partial update is supported):
{
"title": "Ship project",
"completed": true
}
Request:
curl -X PUT http://127.0.0.1:8000/items/1 \
-H "Content-Type: application/json" \
-d '{"title":"Ship project","completed":true}'
Example success response:
{
"id": 1,
"title": "Ship project",
"completed": true
}
Status codes:
200 OK – update succeeded404 Not Found – item ID does not exist422 Unprocessable Entity – request body is invalidRequest:
curl -X DELETE http://127.0.0.1:8000/items/1
Success response: no body, status 204 No Content.
Status codes:
204 No Content – deletion succeeded404 Not Found – item ID does not existEach item is represented as:
{
"id": 1,
"title": "Write README",
"completed": false
}
Field definitions:
id: integer, unique, auto-incrementingtitle: string, required when creating an itemcompleted: boolean, defaults to falseThe API keeps items in an in-memory dictionary, so data is lost when the process restarts.
FastAPI automatically generates interactive docs at:
http://127.0.0.1:8000/docshttp://127.0.0.1:8000/redocRun the test suite:
pytest
This project includes a basic smoke test covering health, create/get, and update/delete flows.
At roughly ten times the current traffic, I would revisit these decisions:
/items to avoid returning unbounded payloads.From a clean clone, a reviewer can do the following:
python -m venv .venv
source .venv/bin/activate # or .\.venv\Scripts\Activate.ps1 on Windows
pip install -r requirements.txt
uvicorn app.main:app --host 0.0.0.0 --port 8000
curl -X POST http://127.0.0.1:8000/items -H "Content-Type: application/json" -d '{"title":"Write README","completed":false}'
This returns a 201 Created response with a JSON body containing a new item ID.