chatterbox-ui/backend/app/routers/speakers.py

82 lines
2.8 KiB
Python

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"}