65 lines
1.6 KiB
Python
65 lines
1.6 KiB
Python
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,
|
|
)
|
|
}
|