194 lines
3.8 KiB
Markdown
194 lines
3.8 KiB
Markdown
# 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.
|