Team Ai
Apppublic

Programmer140/Hackathon

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
api.py163 linesDownload Raw Back to root
1from fastapi import FastAPI, HTTPException2from fastapi.middleware.cors import CORSMiddleware3from pydantic import BaseModel4import sys5import os6import logging7 8# Add the parent directory to sys.path so we can import the chat functionality9sys.path.append(os.path.dirname(os.path.abspath(__file__)))10 11# Import and validate configuration on startup12from secure_config import validate_config13validate_config()14 15from chat_openai import query_qdrant, format_response16from ingest_local_docs import ingest_local_docs  # <- only import the main function, no circular import17 18# Create FastAPI app19app = FastAPI(20    title="AI Assistant Backend",21    description="Backend API for Docusaurus AI Assistant"22)23 24# Add CORS middleware25app.add_middleware(26    CORSMiddleware,27    allow_origins=[28        "http://localhost:3000",29        "http://localhost:5173",30        "http://127.0.0.1:5173",31        "http://localhost:3001",32        "http://127.0.0.1:8000",33        "http://localhost:8000",34        "https://*.vercel.app"35    ],36    allow_credentials=True,37    allow_methods=["*"],38    allow_headers=["*"],39)40 41# Define request/response models42class ChatRequest(BaseModel):43    query: str44 45class ChatResponse(BaseModel):46    response: str47 48# ======================49# Startup Event50# ======================51@app.on_event("startup")52async def startup_event():53    """Ensure Qdrant collection exists and ingest docs if empty"""54    try:55        print("Starting ingestion process on startup...")56        # This will safely create collection if needed and ingest docs57        documents_indexed = ingest_local_docs()58        print(f"Ingestion completed. Total chunks stored: {documents_indexed}")59    except Exception as e:60        logging.error(f"Startup ingestion failed: {e}")61        # Continue running backend even if ingestion fails62 63# ======================64# Basic endpoints65# ======================66@app.get("/")67def read_root():68    return {"message": "AI Assistant Backend is running!"}69 70@app.get("/health")71def health_check():72    return {"status": "ok", "service": "backend", "errors": False}73 74# ======================75# Chat endpoint76# ======================77@app.post("/chat", response_model=ChatResponse)78async def chat_endpoint(request: ChatRequest):79    try:80        query = request.query81        if not query:82            raise HTTPException(status_code=400, detail="Query is required")83 84        # Query Qdrant database85        try:86            search_results = query_qdrant(query)87        except Exception as e:88            logging.error(f"Error querying Qdrant: {str(e)}")89            raise HTTPException(90                status_code=500,91                detail=f"Unable to connect to the knowledge base: {str(e)}"92            )93 94        # Format the response95        try:96            response = format_response(query, search_results)97        except Exception as e:98            logging.error(f"Error formatting response: {str(e)}")99            raise HTTPException(100                status_code=500,101                detail=f"Error generating response: {str(e)}"102            )103 104        return ChatResponse(response=response)105 106    except HTTPException:107        raise108    except Exception as e:109        logging.error(f"Unexpected error in chat endpoint: {str(e)}")110        raise HTTPException(111            status_code=500,112            detail=f"An unexpected error occurred: {str(e)}"113        )114 115# ======================116# Admin endpoints117# ======================118@app.post("/admin/ingest")119async def admin_ingest():120    """Manual ingestion endpoint"""121    try:122        documents_indexed = ingest_local_docs()123        return {124            "status": "success",125            "message": "Documents ingested successfully",126            "documents_indexed": documents_indexed127        }128    except Exception as e:129        logging.error(f"Error during manual ingestion: {str(e)}")130        raise HTTPException(status_code=500, detail=f"Error during ingestion: {str(e)}")131 132@app.get("/admin/status")133async def admin_status():134    """Check collection status"""135    try:136        from qdrant_client import QdrantClient137        from config import QDRANT_URL, QDRANT_API_KEY, COLLECTION_NAME138 139        qdrant_client = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY, prefer_grpc=False)140        collection_info = qdrant_client.get_collection(collection_name=COLLECTION_NAME)141        point_count = getattr(collection_info, "points_count", 0)142        return {"collection_exists": True, "point_count": point_count, "status": "healthy"}143    except Exception as e:144        return {"collection_exists": False, "point_count": 0, "status": "missing", "error": str(e)}145 146@app.get("/debug/docs")147async def debug_docs():148    """Check if docs directory exists and its contents"""149    docs_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'docs')150    if os.path.exists(docs_path):151        files = os.listdir(docs_path)152        return {"docs_exists": True, "file_count": len(files), "files": files}153    else:154        return {"docs_exists": False, "file_count": 0, "files": []}155 156# ======================157# Run Uvicorn158# ======================159if __name__ == "__main__":160    import uvicorn161    port = int(os.environ.get("PORT", 8000))162    uvicorn.run(app, host="0.0.0.0", port=port)163