diff options
| author | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-08 01:58:48 -0700 |
|---|---|---|
| committer | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-08 01:58:48 -0700 |
| commit | 2e0a94e88c847a5ed8dc6ad5fa49715cd631bdfe (patch) | |
| tree | 0c27fc5a8d8cbba60e571bb6690a13c0c0060ff4 /routers/pantry.py | |
Initial commit — Commis personal chef app
AI-powered local chef tool: pantry tracking, meal logging, rotating weekly
menu generation, and grocery list optimization via Ollama (llama3).
FastAPI backend, SQLite, vanilla JS frontend.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'routers/pantry.py')
| -rw-r--r-- | routers/pantry.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/routers/pantry.py b/routers/pantry.py new file mode 100644 index 0000000..d6638f8 --- /dev/null +++ b/routers/pantry.py @@ -0,0 +1,101 @@ +from fastapi import APIRouter, Depends, HTTPException, Query, status +from sqlalchemy.orm import Session +from datetime import datetime, timedelta +from typing import List + +from database import get_db +from models import Ingredient +from schemas import IngredientCreate, IngredientRead, IngredientUpdate + +router = APIRouter(prefix="/api/pantry", tags=["pantry"]) + + +@router.get("", response_model=List[IngredientRead]) +def list_ingredients( + expiring_soon: bool = Query(False), + db: Session = Depends(get_db) +): + """List all ingredients. Optional query param ?expiring_soon=true filters to ingredients with expiry_date within 7 days from today.""" + query = db.query(Ingredient) + + if expiring_soon: + today = datetime.utcnow().date() + seven_days_later = today + timedelta(days=7) + query = query.filter( + (Ingredient.expiry_date >= today) & (Ingredient.expiry_date <= seven_days_later) + ) + + return query.all() + + +@router.get("/expiring", response_model=List[IngredientRead]) +def list_expiring_ingredients(db: Session = Depends(get_db)): + """Ingredients expiring within 7 days.""" + today = datetime.utcnow().date() + seven_days_later = today + timedelta(days=7) + + return db.query(Ingredient).filter( + (Ingredient.expiry_date >= today) & (Ingredient.expiry_date <= seven_days_later) + ).all() + + +@router.post("", response_model=IngredientRead, status_code=status.HTTP_201_CREATED) +def create_ingredient(ingredient: IngredientCreate, db: Session = Depends(get_db)): + """Create a new ingredient.""" + db_ingredient = Ingredient(**ingredient.model_dump()) + db.add(db_ingredient) + db.commit() + db.refresh(db_ingredient) + return db_ingredient + + +@router.put("/{id}", response_model=IngredientRead) +def update_ingredient(id: int, ingredient: IngredientUpdate, db: Session = Depends(get_db)): + """Update ingredient fields (partial update).""" + db_ingredient = db.query(Ingredient).filter(Ingredient.id == id).first() + if not db_ingredient: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ingredient not found") + + update_data = ingredient.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(db_ingredient, field, value) + + db_ingredient.updated_at = datetime.utcnow() + db.commit() + db.refresh(db_ingredient) + return db_ingredient + + +@router.delete("/{id}", status_code=status.HTTP_204_NO_CONTENT) +def delete_ingredient(id: int, db: Session = Depends(get_db)): + """Delete an ingredient.""" + db_ingredient = db.query(Ingredient).filter(Ingredient.id == id).first() + if not db_ingredient: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ingredient not found") + + db.delete(db_ingredient) + db.commit() + + +@router.post("/bulk", response_model=List[IngredientRead]) +def bulk_upsert_ingredients(ingredients: List[IngredientCreate], db: Session = Depends(get_db)): + """Upsert list of ingredients. If an ingredient with same name exists, add the quantity (accumulate). If not, create new.""" + result = [] + + for ingredient_data in ingredients: + existing = db.query(Ingredient).filter(Ingredient.name == ingredient_data.name).first() + + if existing: + existing.quantity += ingredient_data.quantity + existing.updated_at = datetime.utcnow() + db.commit() + db.refresh(existing) + result.append(existing) + else: + new_ingredient = Ingredient(**ingredient_data.model_dump()) + db.add(new_ingredient) + db.commit() + db.refresh(new_ingredient) + result.append(new_ingredient) + + return result |
