Spaces:
Sleeping
Sleeping
| """FastAPI dependency injection configuration.""" | |
| from typing import Annotated, Optional | |
| from fastapi import Depends, UploadFile, Form, HTTPException, Request, Header | |
| from fastapi.security import HTTPBearer | |
| from pydantic import BaseModel, Field, validator | |
| import re | |
| from application.use_cases.container import UseCaseContainer | |
| from infrastructure.services.container import ServiceContainer | |
| from infrastructure.services.jwt_validation_service import JWTValidationService | |
| # Create HTTPBearer scheme that will be recognized by OpenAPI | |
| bearer_scheme = HTTPBearer( | |
| scheme_name="BearerAuth", | |
| bearerFormat="JWT", | |
| description="JWT Bearer token authentication" | |
| ) | |
| class ExtractionRequest(BaseModel): | |
| """Request model for audio extraction.""" | |
| output_format: str = Field(default="mp3", description="Output audio format") | |
| quality: str = Field(default="medium", description="Audio quality level") | |
| def validate_format(cls, v): | |
| allowed = ['mp3', 'aac', 'wav', 'flac', 'm4a', 'ogg'] | |
| if v.lower() not in allowed: | |
| raise ValueError(f"Format must be one of: {', '.join(allowed)}") | |
| return v.lower() | |
| def validate_quality(cls, v): | |
| allowed = ['high', 'medium', 'low'] | |
| if v.lower() not in allowed: | |
| raise ValueError(f"Quality must be one of: {', '.join(allowed)}") | |
| return v.lower() | |
| def extraction_params( | |
| output_format: str = Form("mp3"), | |
| quality: str = Form("medium") | |
| ) -> ExtractionRequest: | |
| """Parse and validate extraction parameters.""" | |
| return ExtractionRequest(output_format=output_format, quality=quality) | |
| async def validate_video_file(video: UploadFile) -> UploadFile: | |
| """Validate uploaded video file.""" | |
| if not video.filename: | |
| raise HTTPException(400, "No filename provided") | |
| # Check file extension | |
| allowed_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.webm', '.flv', '.wmv', '.m4v'] | |
| file_ext = '.' + video.filename.lower().split('.')[-1] if '.' in video.filename else '' | |
| if file_ext not in allowed_extensions: | |
| raise HTTPException( | |
| 400, | |
| f"Unsupported video format. Allowed: {', '.join(allowed_extensions)}" | |
| ) | |
| # Check content type (basic validation) | |
| if video.content_type and not video.content_type.startswith(('video/', 'application/octet-stream')): | |
| raise HTTPException(400, "File must be a video") | |
| return video | |
| async def get_validated_token( | |
| credentials = Depends(bearer_scheme) | |
| ) -> str: | |
| """ | |
| Extract and validate bearer token from HTTPBearer scheme. | |
| Args: | |
| credentials: HTTPAuthorizationCredentials from HTTPBearer scheme | |
| Returns: | |
| str: The validated bearer token | |
| Raises: | |
| HTTPException: 401 if token is missing or invalid | |
| """ | |
| from infrastructure.config.settings import settings | |
| if not settings.enforce_authentication: | |
| return "authentication-disabled" | |
| if not credentials: | |
| raise HTTPException( | |
| status_code=401, | |
| detail="Missing Authorization header", | |
| headers={"WWW-Authenticate": "Bearer"} | |
| ) | |
| # Extract token from credentials | |
| token = credentials.credentials | |
| if not token: | |
| raise HTTPException( | |
| status_code=401, | |
| detail="Empty bearer token", | |
| headers={"WWW-Authenticate": "Bearer"} | |
| ) | |
| # Validate JWT structure | |
| jwt_service = JWTValidationService() | |
| if not jwt_service.validate_structure(token): | |
| raise HTTPException( | |
| status_code=401, | |
| detail="Invalid JWT token structure", | |
| headers={"WWW-Authenticate": "Bearer"} | |
| ) | |
| return token | |
| def get_services(request: Request) -> ServiceContainer: | |
| """Get service container from app state.""" | |
| return request.app.state.get_services() | |
| def get_use_cases(request: Request) -> UseCaseContainer: | |
| """Get use case container from app state.""" | |
| return request.app.state.get_use_cases() | |
| # Type aliases for dependency injection | |
| ValidatedVideo = Annotated[UploadFile, Depends(validate_video_file)] | |
| ExtractionParams = Annotated[ExtractionRequest, Depends(extraction_params)] | |
| Services = Annotated[ServiceContainer, Depends(get_services)] | |
| UseCases = Annotated[UseCaseContainer, Depends(get_use_cases)] | |
| BearerToken = Annotated[str, Depends(get_validated_token)] | |