from __future__ import annotations from contextlib import asynccontextmanager from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field import logging from google.genai.errors import ClientError, ServerError from rag.chain import aanswer logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): logger.info("FAQ RAG Chatbot starting up") yield logger.info("FAQ RAG Chatbot shutting down") app = FastAPI( title="FAQ RAG Chatbot", version="1.0.0", description="RAG-based chatbot for samagama internship portal - CSFAQ Project", openapi_url="/openapi.json", docs_url="/", lifespan=lifespan, ) class ChatRequest(BaseModel): question: str = Field(..., min_length=1, description="User Query..") class ChatResponse(BaseModel): question: str answer: str sources: list[str] = Field(default_factory=list) @app.get("/health") async def health() -> dict[str, str]: return {"status": "ok"} @app.post("/chat", response_model=ChatResponse) async def chat(payload: ChatRequest) -> ChatResponse: question = payload.question.strip() try: response = await aanswer(question) except ClientError as error: message = str(error).lower() if error.code == 429 or "quota" in message or "rate limit" in message: raise HTTPException( status_code=429, detail=( "The language model quota has been exceeded. " "Please try again later." ), ) from None raise HTTPException( status_code=400, detail=( "Unable to process your request right now. " "Please try again later." ), ) from None except ServerError as error: if error.code == 503 or "unavailable" in str(error).lower(): raise HTTPException( status_code=503, detail=( "The language service is temporarily unavailable. " "Please try again later." ), ) from None raise HTTPException( status_code=502, detail=( "Unable to process your request right now. " "Please try again later." ), ) from None except Exception: logger.exception("Chat handler error") raise HTTPException( status_code=502, detail=( "Unable to process your request right now. " "Please try again later." ), ) return ChatResponse( question=question, answer=response.answer, sources=response.sources, )