"""Audio extraction API endpoints.""" from typing import Annotated from fastapi import APIRouter, Depends, HTTPException, Query, status from sqlmodel.ext.asyncio.session import AsyncSession from app.core.database import get_db from app.core.dependencies import get_current_active_user_flexible from app.models.user import User from app.services.extraction import ExtractionInfo, ExtractionService from app.services.extraction_processor import extraction_processor router = APIRouter(prefix="/extractions", tags=["extractions"]) async def get_extraction_service( session: Annotated[AsyncSession, Depends(get_db)], ) -> ExtractionService: """Get the extraction service.""" return ExtractionService(session) @router.post("/") async def create_extraction( url: str, current_user: Annotated[User, Depends(get_current_active_user_flexible)], extraction_service: Annotated[ExtractionService, Depends(get_extraction_service)], ) -> dict[str, ExtractionInfo | str]: """Create a new extraction job for a URL.""" try: if current_user.id is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="User ID not available", ) extraction_info = await extraction_service.create_extraction( url, current_user.id, ) # Queue the extraction for background processing await extraction_processor.queue_extraction(extraction_info["id"]) except ValueError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=str(e), ) from e except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to create extraction: {e!s}", ) from e else: return { "message": "Extraction queued successfully", "extraction": extraction_info, } @router.get("/user") async def get_user_extractions( # noqa: PLR0913 current_user: Annotated[User, Depends(get_current_active_user_flexible)], extraction_service: Annotated[ExtractionService, Depends(get_extraction_service)], search: Annotated[ str | None, Query(description="Search in title, URL, or service"), ] = None, sort_by: Annotated[str, Query(description="Sort by field")] = "created_at", sort_order: Annotated[str, Query(description="Sort order (asc/desc)")] = "desc", status_filter: Annotated[str | None, Query(description="Filter by status")] = None, page: Annotated[int, Query(description="Page number", ge=1)] = 1, limit: Annotated[int, Query(description="Items per page", ge=1, le=100)] = 50, ) -> dict: """Get all extractions for the current user.""" try: if current_user.id is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="User ID not available", ) result = await extraction_service.get_user_extractions( user_id=current_user.id, search=search, sort_by=sort_by, sort_order=sort_order, status_filter=status_filter, page=page, limit=limit, ) except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to get extractions: {e!s}", ) from e else: return result @router.get("/{extraction_id}") async def get_extraction( extraction_id: int, current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 extraction_service: Annotated[ExtractionService, Depends(get_extraction_service)], ) -> ExtractionInfo: """Get extraction information by ID.""" try: extraction_info = await extraction_service.get_extraction_by_id(extraction_id) if not extraction_info: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Extraction {extraction_id} not found", ) except HTTPException: raise except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to get extraction: {e!s}", ) from e else: return extraction_info @router.get("/") async def get_all_extractions( # noqa: PLR0913 extraction_service: Annotated[ExtractionService, Depends(get_extraction_service)], search: Annotated[ str | None, Query(description="Search in title, URL, or service"), ] = None, sort_by: Annotated[str, Query(description="Sort by field")] = "created_at", sort_order: Annotated[str, Query(description="Sort order (asc/desc)")] = "desc", status_filter: Annotated[str | None, Query(description="Filter by status")] = None, page: Annotated[int, Query(description="Page number", ge=1)] = 1, limit: Annotated[int, Query(description="Items per page", ge=1, le=100)] = 50, ) -> dict: """Get all extractions with optional filtering, search, and sorting.""" try: result = await extraction_service.get_all_extractions( search=search, sort_by=sort_by, sort_order=sort_order, status_filter=status_filter, page=page, limit=limit, ) except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to get extractions: {e!s}", ) from e else: return result