from fastapi import FastAPI, Request, status from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from fastapi.exceptions import RequestValidationError from starlette.exceptions import HTTPException as StarletteHTTPException import time from app.config import settings from app.api.v1.api import api_router from app.core.exceptions import PrepMindException # Create FastAPI app app = FastAPI( title=settings.APP_NAME, description="AI-powered placement preparation platform API", version=settings.API_VERSION, debug=settings.DEBUG, docs_url=f"/api/{settings.API_VERSION}/docs", redoc_url=f"/api/{settings.API_VERSION}/redoc", openapi_url=f"/api/{settings.API_VERSION}/openapi.json", ) # CORS Middleware app.add_middleware( CORSMiddleware, allow_origins=settings.CORS_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Request timing middleware @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 # Exception handlers @app.exception_handler(PrepMindException) async def prepmind_exception_handler(request: Request, exc: PrepMindException): return JSONResponse( status_code=exc.status_code, content={"detail": exc.detail}, ) @app.exception_handler(StarletteHTTPException) async def http_exception_handler(request: Request, exc: StarletteHTTPException): return JSONResponse( status_code=exc.status_code, content={"detail": exc.detail}, ) @app.exception_handler(RequestValidationError) async def validation_exception_handler(request: Request, exc: RequestValidationError): return JSONResponse( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={"detail": exc.errors()}, ) # Root endpoint @app.get("/") async def root(): return { "message": "Welcome to PrepMind API", "version": settings.API_VERSION, "docs": f"/api/{settings.API_VERSION}/docs", } # Health check @app.get("/health") async def health_check(): return { "status": "healthy", "environment": settings.ENVIRONMENT, } # Include API router app.include_router(api_router, prefix=f"/api/{settings.API_VERSION}") if __name__ == "__main__": import uvicorn uvicorn.run( "app.main:app", host=settings.HOST, port=settings.PORT, reload=settings.DEBUG, )