import time 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 setup_logging() logger.info(f"Starting up {settings.PROJECT_NAME}") yield # Run the application # Clean up resources on shutdown logger.info(f"Shutting down {settings.PROJECT_NAME}") app = FastAPI( title=settings.PROJECT_NAME, openapi_url="/openapi.json", version=settings.VERSION, lifespan=lifespan, ) # 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 if settings.BACKEND_CORS_ORIGINS: app.add_middleware( CORSMiddleware, allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], allow_credentials=True, allow_methods=["*"], allow_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__": uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)