"""Application entry point with DDD architecture. This module is the main entry point for the FastAPI application. Configures DI container, middleware, and routes following DDD principles. """ from collections.abc import AsyncGenerator from contextlib import asynccontextmanager import uvicorn from dishka import make_async_container from dishka.integrations.fastapi import setup_dishka from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.infrastructure import close_db, init_db, register_exception_handlers, settings from app.infrastructure.di.providers import ( DatabaseProvider, KeycloakProvider, RepositoryProvider, TransactionManagerProvider, UseCaseProvider, ) from app.presentation import router @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator[None]: """Application lifespan manager. Handles startup and shutdown tasks for the application. Args: app: FastAPI application instance. Yields: None during application runtime. """ await init_db() yield await close_db() def app_factory() -> FastAPI: """Create and configure FastAPI application. Sets up DI container, exception handlers, middleware, and routes. Returns: Configured FastAPI application instance. """ app = FastAPI( title=settings.app.name, debug=settings.app.debug, lifespan=lifespan, docs_url="/docs" if settings.is_dev else None, redoc_url="/redoc" if settings.is_dev else None, ) container = make_async_container( DatabaseProvider(), RepositoryProvider(), TransactionManagerProvider(), UseCaseProvider(), KeycloakProvider(), ) setup_dishka(container, app) register_exception_handlers(app) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(router, prefix="/api") @app.get("/health", tags=["health"]) async def health_check() -> dict[str, str]: """Health check endpoint. Returns: Status information dictionary. """ return { "status": "ok", "app": settings.app.name, "env": settings.environment.value, } return app def main() -> None: """Run the application. Starts uvicorn server with application factory. """ uvicorn.run( app_factory, factory=True, host=settings.app.host, port=settings.app.port, ) if __name__ == "__main__": main()