"""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 fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles 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 from app.presentation.web import router as web_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.include_router(web_router) app.mount("/static", StaticFiles(directory="static"), name="static") @app.get("/", response_class=HTMLResponse) async def root_redirect() -> HTMLResponse: """Redirect root URL to web UI. Returns: HTMLResponse with redirect to web interface. """ return HTMLResponse( content='', status_code=200 ) @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()