from typing import List, Annotated from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form from app.models.speaker_models import Speaker, SpeakerResponse from app.services.speaker_service import SpeakerManagementService router = APIRouter( tags=["Speakers"], responses={404: {"description": "Not found"}}, ) # Dependency to get the speaker service instance # This could be more sophisticated with a proper DI system later def get_speaker_service(): return SpeakerManagementService() @router.get("/", response_model=List[Speaker]) async def get_all_speakers( service: Annotated[SpeakerManagementService, Depends(get_speaker_service)] ): """ Retrieve all available speakers. """ return service.get_speakers() @router.post("/", response_model=SpeakerResponse, status_code=201) async def create_new_speaker( name: Annotated[str, Form()], audio_file: Annotated[UploadFile, File()], service: Annotated[SpeakerManagementService, Depends(get_speaker_service)] ): """ Add a new speaker. Requires speaker name (form data) and an audio sample file (file upload). """ if not audio_file.filename: raise HTTPException(status_code=400, detail="No audio file provided.") if not audio_file.content_type or not audio_file.content_type.startswith("audio/"): raise HTTPException(status_code=400, detail="Invalid audio file type. Please upload a valid audio file (e.g., WAV, MP3).") try: new_speaker = await service.add_speaker(name=name, audio_file=audio_file) return SpeakerResponse( id=new_speaker.id, name=new_speaker.name, message="Speaker added successfully." ) except HTTPException as e: # Re-raise HTTPExceptions from the service (e.g., file save error) raise e except Exception as e: # Catch-all for other unexpected errors raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}") @router.get("/{speaker_id}", response_model=Speaker) async def get_speaker_details( speaker_id: str, service: Annotated[SpeakerManagementService, Depends(get_speaker_service)] ): """ Get details for a specific speaker by ID. """ speaker = service.get_speaker_by_id(speaker_id) if not speaker: raise HTTPException(status_code=404, detail="Speaker not found") return speaker @router.delete("/{speaker_id}", response_model=dict) async def remove_speaker( speaker_id: str, service: Annotated[SpeakerManagementService, Depends(get_speaker_service)] ): """ Delete a speaker by ID. """ deleted = service.delete_speaker(speaker_id) if not deleted: raise HTTPException(status_code=404, detail="Speaker not found or could not be deleted.") return {"message": "Speaker deleted successfully"}