audio-processor / app.py
Tadeas Kosek
fixes vol4
57c92c0
"""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 <your-jwt-token>
```
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