from fastapi import FastAPI, UploadFile, File, Form, HTTPException from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse from fastapi.middleware.cors import CORSMiddleware from agentLogic.graph import app as rag_app from processingPdf.indexer import Indexer import shutil import os import logging # Configurazione logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) app = FastAPI() # Middleware CORS aggiornato app.add_middleware( CORSMiddleware, allow_origins=["*"], # Più sicuro per il deploy unificato allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Inizializzazione dell'Indexer # (Nota: Se vedi che lo Space va in timeout, sposta questa riga dentro upload_pdf) indexer_worker = Indexer() # --- GESTIONE FRONTEND STATICO --- # Assicurati che la cartella 'static' esista (creata dal Dockerfile) if os.path.exists("static"): app.mount("/assets", StaticFiles(directory="static/assets"), name="assets") @app.get("/") async def serve_frontend(): index_path = os.path.join("static", "index.html") if os.path.exists(index_path): return FileResponse(index_path) return {"message": "Backend is running, but static/index.html was not found."} # --- ENDPOINT API --- @app.post("/upload") async def upload_pdf(file: UploadFile = File(...), user_id: str = Form(...)): upload_dir = "temp_uploads" os.makedirs(upload_dir, exist_ok=True) file_path = os.path.join(upload_dir, file.filename) try: logger.info(f"Ricezione file: {file.filename} per l'utente: {user_id}") with open(file_path, "wb") as buffer: shutil.copyfileobj(file.file, buffer) indexer_worker.index_pdf(file_path, user_id) return { "status": "success", "message": "Indicizzazione completata con successo", "filename": file.filename } except Exception as e: logger.error(f"Errore durante l'upload/indicizzazione: {str(e)}") raise HTTPException(status_code=500, detail=str(e)) finally: if os.path.exists(file_path): os.remove(file_path) @app.post("/chat") async def chat(query: str, filename: str, user_id: str): try: initial_state = { "query": query, "user_id": user_id, "filename": filename, "intent_data": {}, "context_chunks": [], "final_answer": "" } result = rag_app.invoke(initial_state) return {"answer": result["final_answer"]} except Exception as e: logger.error(f"Errore nella chat endpoint: {str(e)}") raise HTTPException(status_code=500, detail="Errore durante l'elaborazione.") # Gestione rotte React (SPA) per evitare 404 al refresh @app.exception_handler(404) async def custom_404_handler(request, __): return FileResponse("static/index.html") # Rimosso il blocco if __name__ == "__main__": # perché l'avvio è gestito dal Dockerfile tramite CMD