"""Whisper transcription service for VoIdeaAI. Used as fallback when browser Web Speech API fails. Supports OpenAI Whisper API and compatible endpoints. """ import tempfile from pathlib import Path import httpx from app.core.config import get_settings WHISPER_URL = "https://api.openai.com/v1/audio/transcriptions" async def transcribe(audio_data: bytes, filename: str = "audio.webm") -> str | None: """Transcribe audio using Whisper API. Args: audio_data: Raw audio bytes filename: Original filename (determines format) Returns: Transcribed text or None if failed """ settings = get_settings() api_key = settings.openai_api_key or settings.ai_yandex_key or "" if not api_key: return None url = WHISPER_URL with tempfile.NamedTemporaryFile(delete=False, suffix=Path(filename).suffix) as tmp: tmp.write(audio_data) tmp_path = tmp.name try: async with httpx.AsyncClient(timeout=30.0) as client: with open(tmp_path, "rb") as f: resp = await client.post( url, headers={"Authorization": f"Bearer {api_key}"}, files={"file": (filename, f, "audio/webm")}, data={"model": "whisper-1", "language": "ru"}, ) if resp.status_code == 200: return resp.json().get("text") return None except Exception: return None finally: Path(tmp_path).unlink(missing_ok=True)