from __future__ import annotations from contextlib import asynccontextmanager from fastapi import FastAPI from .config import settings from .menu_catalog import MenuCatalog from .models import ChatRequest, ChatResponse, IndexResponse from .service import RagService rag_service = RagService() menu_catalog = MenuCatalog() @asynccontextmanager async def lifespan(_: FastAPI): if settings.index_on_startup: await rag_service.reindex() yield app = FastAPI(title=settings.app_name, version="1.0.0", lifespan=lifespan) @app.get("/health") async def health() -> dict[str, str]: return {"status": "ok"} @app.post("/chat", response_model=ChatResponse) async def chat(request: ChatRequest) -> ChatResponse: return await rag_service.chat(request) @app.post("/admin/reindex", response_model=IndexResponse) async def reindex() -> IndexResponse: return await rag_service.reindex() @app.get("/menu/search") async def search_menu( query: str = "", max_price: int | None = None, category: str | None = None, must_include: str | None = None, must_not_include: str | None = None, limit: int = 5, ) -> dict[str, object]: return { "items": rag_service.search_menu( query=query, max_price=max_price, category=category, must_include=[value.strip() for value in must_include.split(",")] if must_include else None, must_not_include=[value.strip() for value in must_not_include.split(",")] if must_not_include else None, limit=limit, ) }