summaryrefslogtreecommitdiff
path: root/main.py
blob: 65b8271d33cbb79836cfed02e61fe342e1c3cb3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from contextlib import asynccontextmanager
import asyncio
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from sqlalchemy import text
from database import engine, Base
from config import settings
from routers import pantry, meals, recipes, menus, grocery


@asynccontextmanager
async def lifespan(app: FastAPI):
    # Startup
    Base.metadata.create_all(bind=engine)
    with engine.connect() as conn:
        result = conn.execute(text("PRAGMA table_info(menu_plans)"))
        if 'notes' not in [row[1] for row in result]:
            conn.execute(text("ALTER TABLE menu_plans ADD COLUMN notes TEXT"))
            conn.commit()
    yield
    # Shutdown
    pass


app = FastAPI(title="Commis", lifespan=lifespan)

# Include routers first so API routes take priority over the static catch-all
app.include_router(pantry.router)
app.include_router(meals.router)
app.include_router(recipes.router)
app.include_router(menus.router)
app.include_router(grocery.router)
app.include_router(grocery.ai_router)


@app.get("/api/health")
async def health():
    try:
        import ollama
        client = ollama.Client(host=settings.ollama_host)
        loop = asyncio.get_event_loop()
        models_resp = await loop.run_in_executor(None, client.list)
        model_names = [m["name"] for m in models_resp.get("models", [])]
        ollama_status = "connected"
    except Exception:
        model_names = []
        ollama_status = "disconnected"
    return {
        "status": "ok",
        "ollama": ollama_status,
        "model": settings.model_name,
        "available_models": model_names,
    }


# Static files mount last — acts as a catch-all, must come after all API routes
app.mount("/", StaticFiles(directory="static", html=True), name="static")