""" FastAPI Application Factory Main entry point for para.AI API """ from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from contextlib import asynccontextmanager import logging import time from datetime import datetime from api.config import settings from api.routes import debug_routes, process_routes, status_routes, health_routes logging.basicConfig( level=settings.LOG_LEVEL, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): """Lifespan events""" logger.info(f"๐Ÿš€ Starting {settings.APP_NAME} v{settings.APP_VERSION}") logger.info(f"๐Ÿ“Š Environment: {'DEBUG' if settings.DEBUG else 'PRODUCTION'}") logger.info(f"๐Ÿค– LLM Model: {settings.LLM_MODEL}") yield logger.info("๐Ÿ›‘ Shutting down API") def create_app() -> FastAPI: """Factory function to create FastAPI app""" app = FastAPI( title=settings.APP_NAME, version=settings.APP_VERSION, description="API para anรกlise jurisprudencial com LLMs - Sistema de 9 Especialistas", lifespan=lifespan, docs_url="/docs" if settings.DEBUG else None, redoc_url="/redoc" if settings.DEBUG else None, ) app.add_middleware( CORSMiddleware, allow_origins=settings.CORS_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.middleware("http") async def add_process_time_header(request: Request, call_next): start_time = time.time() response = await call_next(request) process_time = time.time() - start_time response.headers["X-Process-Time"] = str(process_time) return response @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): logger.error(f"Global exception: {exc}", exc_info=True) return JSONResponse( status_code=500, content={ "error": "Internal Server Error", "detail": str(exc) if settings.DEBUG else "An error occurred", "timestamp": datetime.now().isoformat(), "path": str(request.url) } ) app.include_router(health_routes.router, prefix="/health", tags=["Health"]) app.include_router(process_routes.router, prefix="/process", tags=["Process"]) app.include_router(status_routes.router, prefix="/status", tags=["Status"]) if settings.DEBUG: app.include_router(debug_routes.router, prefix="/debug", tags=["Debug"]) @app.get("/") async def root(): return { "app": settings.APP_NAME, "version": settings.APP_VERSION, "status": "running", "timestamp": datetime.now().isoformat(), "docs": "/docs" if settings.DEBUG else "disabled" } return app app = create_app() if __name__ == "__main__": import uvicorn uvicorn.run( "api.main:app", host=settings.API_HOST, port=settings.API_PORT, reload=settings.DEBUG )