from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Request from fastapi.security import HTTPBearer from pydantic import BaseModel, Field from slowapi.util import get_remote_address from slowapi import Limiter from typing import Optional from config import ACCESS_RATE, Config from .controller import ( handle_rag_query, handle_document_upload, handle_health_check, verify_token, ) limiter = Limiter(key_func=get_remote_address) router = APIRouter(prefix="/rag", tags=["RAG Chatbot"]) security = HTTPBearer() class QueryInput(BaseModel): query: str = Field(..., min_length=1, max_length=1000, description="The question to ask") class QueryResponse(BaseModel): answer: str source: str route: Optional[str] = None documents: Optional[list] = None error: Optional[str] = None class UploadResponse(BaseModel): message: str filename: str text_length: int content_type: str class HealthResponse(BaseModel): status: str components: Optional[dict] = None error: Optional[str] = None @router.post("/question", response_model=QueryResponse) @limiter.limit(ACCESS_RATE) async def ask_question( request: Request, data: QueryInput, token: str = Depends(verify_token) ) -> QueryResponse: """ Ask a question to the RAG chatbot. The chatbot can answer: - Company-related questions (based on uploaded documents) - Cybersecurity questions (from knowledge base) """ response = await handle_rag_query(data.query) return QueryResponse(**response) @router.post("/upload", response_model=UploadResponse) @limiter.limit(ACCESS_RATE) async def upload_document( request: Request, file: UploadFile = File(..., description="Document file (PDF, DOCX, or TXT)"), token: str = Depends(verify_token) ) -> UploadResponse: """ Upload a document to the company knowledge base. Supported formats: - PDF (.pdf) - Word documents (.docx) - Plain text (.txt) Maximum file size: 10MB """ response = await handle_document_upload(file) return UploadResponse(**response) @router.get("/health", response_model=HealthResponse) @limiter.limit(ACCESS_RATE) async def health_check(request: Request) -> HealthResponse: """ Check the health status of the RAG system. Returns the status of all components: - ChromaDB connection - Vector store - AI chains """ response = await handle_health_check() return HealthResponse(**response) @router.get("/info") @limiter.limit(ACCESS_RATE) async def get_system_info(request: Request): """Get information about the RAG system capabilities.""" return { "name": "RAG Chatbot", "version": "1.0.0", "description": "A specialized chatbot for cybersecurity and company-related questions", "capabilities": [ "Company document Q&A (based on uploaded documents)", "Cybersecurity knowledge and best practices", "Document upload and processing (PDF, DOCX, TXT)" ], "supported_file_types": sorted(Config.RAG_SUPPORTED_CONTENT_TYPES), "max_file_size_mb": round(Config.RAG_MAX_FILE_SIZE / (1024 * 1024), 2), "max_query_length": Config.RAG_MAX_QUERY_LENGTH }