"""FastAPI API-only application with DDD architecture.""" from fastapi import FastAPI from fastapi.responses import RedirectResponse from contextlib import asynccontextmanager import logging # Infrastructure imports from infrastructure.config.settings import settings from infrastructure.services.container import ServiceContainer # Application imports from application.use_cases.container import UseCaseContainer # Interface imports from interfaces.api.routes import register_routes from interfaces.api.middleware.error_handler import register_exception_handlers from interfaces.api.middleware.cors_middleware import configure_cors # Configure logging logging.basicConfig( level=logging.INFO if not settings.debug else logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # Global containers service_container: ServiceContainer = None use_case_container: UseCaseContainer = None @asynccontextmanager async def lifespan(app: FastAPI): """Application lifespan manager.""" global service_container, use_case_container # Startup logger.info(f"Starting {settings.app_name} v{settings.app_version}") logger.info(f"Storage type: {settings.storage_type}") # Initialize containers service_container = ServiceContainer.get_instance() use_case_container = UseCaseContainer(service_container, settings) # Start background services await service_container.startup() logger.info("API service started successfully") yield # Shutdown logger.info("Shutting down API service") # Stop background services await service_container.shutdown() logger.info("API service shut down successfully") # Create FastAPI app with API documentation app = FastAPI( title=settings.app_name, description=""" ## Audio Extraction API Extract audio from video files in various formats with customizable quality settings. ### Features - 🎥 Support for multiple video formats (MP4, AVI, MOV, MKV, WebM, etc.) - 🎵 Multiple audio output formats (MP3, AAC, WAV, FLAC, M4A, OGG) - 📊 Three quality levels (High, Medium, Low) - 🚀 Asynchronous processing for all files - ✂️ Audio trimming with start/end time parameters ### Processing Flow 1. **Upload video**: POST to `/extract` endpoint 2. **Get job ID**: Immediate response with job tracking information 3. **Check status**: Monitor progress with `/jobs/{job_id}` 4. **Download result**: Get extracted audio with `/jobs/{job_id}/download` 5. **Optional trimming**: Use `start` and `end` parameters to download specific segments ### Authentication Most endpoints require JWT Bearer token authentication. Include your token in the Authorization header: ``` Authorization: Bearer ``` Public endpoints (no authentication required): - `GET /api/v1/info` - API information - `GET /api/v1/health` - Health check """, version=settings.app_version, docs_url="/docs", redoc_url="/redoc", openapi_url="/openapi.json", lifespan=lifespan, # Add OpenAPI security scheme for Bearer token authentication openapi_tags=[ { "name": "extraction", "description": "Audio extraction operations (requires authentication)" }, { "name": "jobs", "description": "Job management operations (requires authentication)" }, { "name": "info", "description": "Public API information (no authentication required)" } ] ) # Configure OpenAPI security scheme def custom_openapi(): if app.openapi_schema: return app.openapi_schema from fastapi.openapi.utils import get_openapi openapi_schema = get_openapi( title=app.title, version=app.version, description=app.description, routes=app.routes, ) # Add Bearer token security scheme openapi_schema["components"]["securitySchemes"] = { "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "JWT Bearer token authentication" } } app.openapi_schema = openapi_schema return app.openapi_schema app.openapi = custom_openapi # Let FastAPI handle OpenAPI generation automatically # The HTTPBearer scheme in dependencies.py will be automatically detected # Configure middleware configure_cors(app) register_exception_handlers(app) # Register API routes register_routes(app) # Root redirect to documentation @app.get("/", include_in_schema=False) async def root(): """Redirect root to API documentation.""" return RedirectResponse(url="/docs") # Dependency injection functions for routes def get_service_container() -> ServiceContainer: """Get service container for dependency injection.""" return service_container def get_use_case_container() -> UseCaseContainer: """Get use case container for dependency injection.""" return use_case_container # Make containers available for dependency injection app.state.get_services = get_service_container app.state.get_use_cases = get_use_case_container