import os import requests from fastapi import FastAPI, HTTPException from fastapi.responses import Response from pydantic import BaseModel from app.config import ( ELEVENLABS_API_KEY, ELEVENLABS_BASE_URL, MODEL_ID, VOICE_IDS, DEFAULT_LANGUAGE, ) from app.voice_languag_detector import detect_language app = FastAPI(title="Africa TTS - Auto Language Voice Cloning") class TTSRequest(BaseModel): text: str stability: float = 0.5 similarity_boost: float = 0.75 @app.get("/") def root(): return {"status": "ok", "message": "Africa TTS API is running"} @app.post("/tts") def text_to_speech(request: TTSRequest): if not request.text or not request.text.strip(): raise HTTPException(status_code=400, detail="Text cannot be empty") if not ELEVENLABS_API_KEY: raise HTTPException(status_code=500, detail="ELEVENLABS_API_KEY not set") lang_code, confidence = detect_language(request.text) voice_id = VOICE_IDS.get(lang_code, VOICE_IDS[DEFAULT_LANGUAGE]) url = f"{ELEVENLABS_BASE_URL}/text-to-speech/{voice_id}" headers = { "xi-api-key": ELEVENLABS_API_KEY, "Content-Type": "application/json", "Accept": "audio/mpeg", } payload = { "text": request.text, "model_id": MODEL_ID, "voice_settings": { "stability": request.stability, "similarity_boost": request.similarity_boost, }, } response = requests.post(url, json=payload, headers=headers) if response.status_code != 200: raise HTTPException( status_code=response.status_code, detail=f"ElevenLabs API error: {response.text}", ) return Response( content = response.content, media_type = "audio/mpeg", headers = { "X-Detected-Language": lang_code, "X-Detection-confidence": str(round(confidence,4)), "X-Voice-Id-Used": voice_id, } )