""" FastAPI Application Factory Module This module provides functionality to create and configure a FastAPI application with: - Custom OpenAPI schema configuration - Security scheme configuration for Bearer authentication - Automatic router registration - Response class configuration - Security requirements for protected endpoints """ from types import ModuleType from typing import Any, Dict, List, Optional, Union from fastapi import FastAPI, APIRouter from fastapi.responses import JSONResponse, RedirectResponse from fastapi.openapi.utils import get_openapi from fastapi.routing import APIRoute from AllConfigs.main import MainConfig as Config from middleware.auth_middleware import MiddlewareModule def setup_security_schema() -> Dict[str, Any]: """ Configure security schema for the OpenAPI documentation. Returns: Dict[str, Any]: Security schema configuration """ return { "Bearer": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "Enter the token", } } def configure_route_security( path: str, method: str, schema: Dict[str, Any], protected_paths: List[str] ) -> None: """ Configure security requirements for a specific route. Args: path: Route path method: HTTP method schema: OpenAPI schema to modify protected_paths: List of paths that require authentication """ if path in protected_paths: if "paths" not in schema: schema["paths"] = {} if path not in schema["paths"]: schema["paths"][path] = {} if method not in schema["paths"][path]: schema["paths"][path][method] = {} schema["paths"][path][method]["security"] = [{"Bearer": []}] def get_routers(routers_module: ModuleType) -> List[APIRouter]: """ Extract all routers from the routers module. Args: routers_module: Module containing router definitions Returns: List[APIRouter]: List of router instances """ routers = [] for attr_name in dir(routers_module): attr = getattr(routers_module, attr_name) if isinstance(attr, APIRouter): routers.append(attr) return routers def create_app(routers: ModuleType) -> FastAPI: """ Create and configure a FastAPI application. Args: routers: Module containing router definitions Returns: FastAPI: Configured FastAPI application instance """ # Initialize FastAPI app app = FastAPI( title=Config.TITLE, description=Config.DESCRIPTION, default_response_class=JSONResponse, ) # Add home route that redirects to API documentation @app.get("/", include_in_schema=False, summary=str(Config.DESCRIPTION)) async def home() -> RedirectResponse: """Redirect root path to API documentation.""" return RedirectResponse(url="/docs") # Get all routers router_instances = get_routers(routers) # Find protected paths protected_paths = [] for router in router_instances: for route in router.routes: if isinstance(route, APIRoute): # Check if the route has auth_required decorator if any(d.__name__ == "auth_required" for d in route.dependencies): protected_paths.append(route.path) # Include routers for router in router_instances: app.include_router(router) # Configure custom OpenAPI schema def custom_openapi(): if app.openapi_schema: return app.openapi_schema openapi_schema = get_openapi( title=Config.TITLE, version="1.0.0", description=Config.DESCRIPTION, routes=app.routes, ) # Add security schemes openapi_schema["components"] = {"securitySchemes": setup_security_schema()} # Configure security for each route for route in app.routes: if isinstance(route, APIRoute): configure_route_security( route.path, route.methods.pop().lower(), openapi_schema, protected_paths, ) app.openapi_schema = openapi_schema return app.openapi_schema app.openapi = custom_openapi return app