from fastapi import APIRouter, Depends, Response from app.auth import require_bearer_auth from app.config import Settings, get_settings from app.errors import OpenAICompatibleError from app.schemas import SpeechRequest from app.services.audio_formatter import format_audio from app.services.engine_registry import EngineRegistry, get_engine_registry from app.utils.text import ensure_max_length router = APIRouter(prefix="/v1") @router.post("/audio/speech", dependencies=[Depends(require_bearer_auth)]) def create_speech( payload: SpeechRequest, settings: Settings = Depends(get_settings), registry: EngineRegistry = Depends(get_engine_registry), ) -> Response: ensure_max_length(payload.input, settings.max_input_length) engine = registry.get_engine(payload.model) if not engine.supports_voice(payload.voice): raise OpenAICompatibleError( status_code=400, message=f"Unsupported voice '{payload.voice}'.", param="voice", code="unsupported_voice", ) response_format = payload.response_format or settings.default_response_format speed = payload.speed if payload.speed is not None else settings.default_speed quality = payload.quality or settings.default_quality synthesis = engine.synthesize( text=payload.input, voice=payload.voice, speed=speed, quality=quality, model_name=payload.model, lang=settings.default_language, ) audio_bytes, media_type = format_audio( waveform=synthesis.waveform, sample_rate=synthesis.sample_rate, response_format=response_format, ) return Response(content=audio_bytes, media_type=media_type)