# Shopping List API A simple internal API to track shopping list items using SQLite and FastAPI. ## Tech Stack - Python 3.12 - FastAPI - SQLite - `uv` for dependency management and local workflows - Docker for container packaging - Gitea Actions for CI ## Local Development ### Prerequisites - `uv` installed: https://docs.astral.sh/uv/ - Python 3.12 available locally ### Install dependencies ```bash uv sync --dev ``` ### Run the server ```bash uv run uvicorn main:app --reload ``` The API will be available at http://localhost:8000. ## Running Tests ```bash uv run pytest ``` Tests cover: - Root endpoint - Product CRUD - List CRUD - List items management (add, update, delete, cascade) ## Docker ### Build the image ```bash docker build -t shopping-list-api:local . ``` ### Run the container ```bash docker run --rm -p 8000:8000 -v "$PWD/data:/app/data" -e DB_PATH=/app/data/shopping.db shopping-list-api:local ``` This stores the SQLite database on the host under `./data/shopping.db`. ## Database SQLite database file: `shopping.db` by default (created automatically on first startup). Schema: - `products` (id, name, sku?, created_at) - `lists` (id, name, created_at) - `list_items` (id, list_id, product_id, quantity, added_at; foreign keys with cascade) ## API Reference ### Root **GET /** Returns a welcome message. Response: ```json { "message": "Shopping List API" } ``` ### Products **POST /products** Create a product. Body: ```json { "name": "string", "sku": "optional string" } ``` **GET /products** List all products. **GET /products/{id}** Get a product by ID. **DELETE /products/{id}** Delete a product. ### Lists **POST /lists** Create a shopping list. Body: ```json { "name": "string" } ``` **GET /lists** List all lists. **GET /lists/{id}** Get a list with its items (includes product details in items). **DELETE /lists/{id}** Delete a list (cascades to items). ### List Items **POST /lists/{list_id}/items** Add a product to a list. Body: ```json { "product_id": 1, "quantity": 2 } ``` **PATCH /lists/{list_id}/items/{item_id}** Update the quantity of an item in a list. Body: ```json { "quantity": 5 } ``` **DELETE /lists/{list_id}/items/{item_id}** Remove an item from a list. **GET /lists/{list_id}/items** List items in a list (includes product name and sku). ## Manual Testing You can use curl or any HTTP client. Example flow: ```bash # Create products curl -X POST http://localhost:8000/products -H "Content-Type: application/json" -d '{"name":"Paper Plates","sku":"PP-001"}' curl -X POST http://localhost:8000/products -H "Content-Type: application/json" -d '{"name":"Bread"}' # Create a list curl -X POST http://localhost:8000/lists -H "Content-Type: application/json" -d '{"name":"Picnic List"}' # Add items to the list (use IDs from previous responses) curl -X POST http://localhost:8000/lists/1/items -H "Content-Type: application/json" -d '{"product_id":1,"quantity":2}' curl -X POST http://localhost:8000/lists/1/items -H "Content-Type: application/json" -d '{"product_id":2,"quantity":1}' # Get list with items curl http://localhost:8000/lists/1 # Update quantity curl -X PATCH http://localhost:8000/lists/1/items/1 -H "Content-Type: application/json" -d '{"quantity":5}' # List items in list curl http://localhost:8000/lists/1/items # Delete item curl -X DELETE http://localhost:8000/lists/1/items/2 # Delete list (cascades) curl -X DELETE http://localhost:8000/lists/1 ``` ## CI The repository includes a Gitea Actions workflow at `.gitea/workflows/ci.yml` that: 1. installs Python 3.12 and `uv` 2. syncs locked dependencies 3. runs the test suite 4. builds the Docker image ## Notes - This is an internal API; security/auth is not implemented. - For production use, consider adding stronger validation, structured logging, and a non-SQLite database if concurrency requirements grow.