| 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, |
| ) |
|
|