import sys import time import traceback from contextlib import asynccontextmanager import uvicorn from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from loguru import logger from app.api.v1.api import api_router from app.core.config import settings from app.core.logging import setup_logging @asynccontextmanager async def lifespan(app: FastAPI): """ Context manager for FastAPI app lifespan events. Startup and shutdown events run on application startup and shutdown. """ # Setup logging on startup try: setup_logging() logger.info(f"Starting up {settings.PROJECT_NAME}") # Verify imports and application setup logger.info("Application initialized successfully") yield # Run the application # Clean up resources on shutdown logger.info(f"Shutting down {settings.PROJECT_NAME}") except Exception as e: logger.error(f"Error during application startup: {e}") traceback.print_exc() sys.exit(1) app = FastAPI( title=settings.PROJECT_NAME, openapi_url="/openapi.json", version=settings.VERSION, lifespan=lifespan, docs_url="/docs", redoc_url="/redoc", ) # Add middleware @app.middleware("http") async def add_process_time_header(request: Request, call_next): """ Middleware to add X-Process-Time header to response. """ start_time = time.time() response = await call_next(request) process_time = time.time() - start_time response.headers["X-Process-Time"] = str(process_time) # Log request details logger.info( f"{request.method} {request.url.path} " f"Status: {response.status_code} " f"Process Time: {process_time:.4f}s" ) return response # Set all CORS enabled origins app.add_middleware( CORSMiddleware, allow_origins=["*"], # Allow all origins allow_credentials=True, allow_methods=["*"], # Allow all methods allow_headers=["*"], # Allow all headers ) app.include_router(api_router, prefix=settings.API_V1_STR) @app.get("/health", tags=["health"]) async def health_check(): """ Health check endpoint to verify the API is running. """ logger.debug("Health check endpoint called") return {"status": "healthy"} if __name__ == "__main__": try: logger.info("Starting server with uvicorn...") uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True) except Exception as e: logger.error(f"Failed to start server: {e}") traceback.print_exc() sys.exit(1)