import logging import uvicorn from fastapi import FastAPI, Request, status from fastapi.responses import JSONResponse from fastapi.exceptions import RequestValidationError from app.api.v1.router import api_router from app.core.config import settings from app.core.exceptions import WeatherAPIException from app.core.middleware import setup_middlewares # Set up logging logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", ) logger = logging.getLogger(__name__) # Initialize FastAPI application app = FastAPI( title=settings.PROJECT_NAME, description=settings.PROJECT_DESCRIPTION, version=settings.VERSION, openapi_url="/openapi.json", docs_url="/docs", redoc_url="/redoc", ) # Set up middlewares setup_middlewares(app) # Include API router app.include_router(api_router) # Exception handlers @app.exception_handler(WeatherAPIException) async def weather_api_exception_handler(request: Request, exc: WeatherAPIException): """Handle custom WeatherAPIException.""" return JSONResponse( status_code=exc.status_code, content={"detail": exc.detail}, headers=exc.headers, ) @app.exception_handler(RequestValidationError) async def validation_exception_handler(request: Request, exc: RequestValidationError): """Handle request validation errors.""" errors = [] for error in exc.errors(): error_msg = { "loc": error["loc"], "msg": error["msg"], "type": error["type"], } errors.append(error_msg) return JSONResponse( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={ "detail": "Validation error", "errors": errors, }, ) @app.exception_handler(Exception) async def general_exception_handler(request: Request, exc: Exception): """Handle all uncaught exceptions.""" logger.error(f"Uncaught exception: {exc}", exc_info=True) return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={"detail": "Internal server error"}, ) # Health check endpoint @app.get("/health", tags=["Health"]) async def health_check(): """Health check endpoint""" return {"status": "ok"} if __name__ == "__main__": uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)