A FastAPI-based REST API for managing fridges, freezers, and food items. Track your food inventory with categories, expiry dates, and storage locations.
- 🏠 Fridge Management: Create and manage multiple fridges
- ❄️ Freezer Management: Organize freezers within fridges
- 🍎 Food Tracking: Add, update, and delete food items
- 📦 Food Categories: Organize foods by type (beverage, produce, meat, condiments, fat, microwavable foods, bread, dairy, egg)
- 📅 Expiry Tracking: Optional expiry date tracking for food items
- 🔍 Filtering: Filter foods by fridge, freezer, or category
- 📊 Interactive API Docs: Built-in Swagger UI and ReDoc documentation
- FastAPI - Modern, fast web framework for building APIs
- SQLAlchemy - SQL toolkit and ORM
- SQLite - Lightweight database (can be easily switched to PostgreSQL/MySQL)
- Pydantic - Data validation using Python type annotations
- Uvicorn - ASGI server
- Python 3.9+ (tested with Python 3.13)
- uv (recommended) or pip
-
Create virtual environment:
uv venv
-
Activate virtual environment:
source .venv/bin/activate -
Install dependencies:
uv pip install -r requirements.txt
-
Create virtual environment:
python -m venv .venv
-
Activate virtual environment:
source .venv/bin/activate # On Windows: .venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
python run.pyuvicorn app.main:app --reloadThe API will be available at:
- API: http://localhost:8000
- Interactive Docs (Swagger): http://localhost:8000/docs
- Alternative Docs (ReDoc): http://localhost:8000/redoc
fridge-management/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI application and endpoints
│ ├── models.py # SQLAlchemy database models
│ ├── schemas.py # Pydantic schemas for request/response
│ └── database.py # Database configuration
├── requirements.txt # Python dependencies
├── run.py # Server startup script
└── README.md # This file
POST /fridges
Content-Type: application/json
{
"name": "Kitchen Fridge",
"location": "Kitchen"
}Response:
{
"id": 1,
"name": "Kitchen Fridge",
"location": "Kitchen",
"created_at": "2024-01-15T10:30:00",
"updated_at": "2024-01-15T10:30:00"
}GET /fridges?skip=0&limit=100GET /fridges/{fridge_id}POST /freezers
Content-Type: application/json
{
"name": "Top Freezer",
"fridge_id": 1
}GET /freezers?skip=0&limit=100GET /freezers/{freezer_id}POST /foods
Content-Type: application/json
{
"name": "Milk",
"category": "dairy",
"quantity": 2,
"expiry_date": "2024-01-20T00:00:00",
"fridge_id": 1
}Food Categories:
beverageproducemeatcondimentsfatmicrowavable_foodsbreaddairyegg
Response:
{
"id": 1,
"name": "Milk",
"category": "dairy",
"quantity": 2,
"expiry_date": "2024-01-20T00:00:00",
"fridge_id": 1,
"freezer_id": null,
"created_at": "2024-01-15T10:30:00",
"updated_at": "2024-01-15T10:30:00"
}GET /foods?skip=0&limit=100&fridge_id=1&freezer_id=2&category=dairyQuery Parameters:
skip(optional): Number of records to skip (default: 0)limit(optional): Maximum number of records to return (default: 100)fridge_id(optional): Filter by fridge IDfreezer_id(optional): Filter by freezer IDcategory(optional): Filter by food category
GET /foods/{food_id}PUT /foods/{food_id}
Content-Type: application/json
{
"name": "Whole Milk",
"quantity": 1,
"expiry_date": "2024-01-25T00:00:00"
}Note: All fields are optional in the update request. Only provided fields will be updated.
DELETE /foods/{food_id}Response: 204 No Content
Create a fridge:
curl -X POST "http://localhost:8000/fridges" \
-H "Content-Type: application/json" \
-d '{
"name": "Kitchen Fridge",
"location": "Kitchen"
}'Add food to fridge:
curl -X POST "http://localhost:8000/foods" \
-H "Content-Type: application/json" \
-d '{
"name": "Apples",
"category": "produce",
"quantity": 5,
"fridge_id": 1
}'Get all dairy products:
curl "http://localhost:8000/foods?category=dairy"Update food quantity:
curl -X PUT "http://localhost:8000/foods/1" \
-H "Content-Type: application/json" \
-d '{
"quantity": 3
}'Delete food:
curl -X DELETE "http://localhost:8000/foods/1"import requests
BASE_URL = "http://localhost:8000"
# Create a fridge
fridge = requests.post(
f"{BASE_URL}/fridges",
json={"name": "Kitchen Fridge", "location": "Kitchen"}
).json()
print(f"Created fridge: {fridge}")
# Add food to fridge
food = requests.post(
f"{BASE_URL}/foods",
json={
"name": "Milk",
"category": "dairy",
"quantity": 2,
"fridge_id": fridge["id"]
}
).json()
print(f"Added food: {food}")
# Get all foods in fridge
foods = requests.get(
f"{BASE_URL}/foods",
params={"fridge_id": fridge["id"]}
).json()
print(f"Foods in fridge: {foods}")
# Update food
updated = requests.put(
f"{BASE_URL}/foods/{food['id']}",
json={"quantity": 1}
).json()
print(f"Updated food: {updated}")
# Delete food
requests.delete(f"{BASE_URL}/foods/{food['id']}")
print("Food deleted")The application uses SQLite by default, which creates a fridge_management.db file in the project root. The database is automatically initialized when the server starts.
To use a different database (PostgreSQL, MySQL, etc.), update the SQLALCHEMY_DATABASE_URL in app/database.py:
# PostgreSQL example
SQLALCHEMY_DATABASE_URL = "postgresql://user:password@localhost/fridge_management"
# MySQL example
SQLALCHEMY_DATABASE_URL = "mysql+pymysql://user:password@localhost/fridge_management"- Food items must be placed in either a fridge or freezer (not both, and at least one)
- Fridge and freezer IDs must exist before adding food items
- Food quantity must be at least 1
- Food category must be one of the predefined categories
The API returns appropriate HTTP status codes:
200 OK- Successful GET/PUT request201 Created- Successful POST request204 No Content- Successful DELETE request400 Bad Request- Invalid request data404 Not Found- Resource not found
The server runs with auto-reload enabled by default when using run.py or uvicorn --reload, so changes to the code will automatically restart the server.
You can test the API using:
- The interactive Swagger UI at http://localhost:8000/docs
- curl commands
- Python requests library
- Postman or any HTTP client
This project is open source and available for personal and commercial use.
Contributions are welcome! Please feel free to submit a Pull Request.