first
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
"""Klient pro OpenAI — Whisper přepis + Chat Completions (slučování), přes httpx."""
|
||||
import httpx
|
||||
|
||||
from ..config import OPENAI_BASE_URL, UPSTREAM_TIMEOUT_SECONDS
|
||||
from ..errors import UpstreamError
|
||||
from ..logging_config import get_logger
|
||||
|
||||
log = get_logger("audio-transcription.openai")
|
||||
|
||||
|
||||
async def transcribe(
|
||||
*,
|
||||
api_key: str,
|
||||
audio: bytes,
|
||||
filename: str,
|
||||
content_type: str,
|
||||
model: str,
|
||||
language: str | None = None,
|
||||
) -> str:
|
||||
"""Přepíše audio přes OpenAI Whisper (/audio/transcriptions) a vrátí text."""
|
||||
headers = {"Authorization": f"Bearer {api_key}"}
|
||||
files = {"file": (filename or "audio.mp3", audio, content_type or "application/octet-stream")}
|
||||
form = {"model": model}
|
||||
if language:
|
||||
form["language"] = language
|
||||
url = f"{OPENAI_BASE_URL}/audio/transcriptions"
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=UPSTREAM_TIMEOUT_SECONDS) as client:
|
||||
resp = await client.post(url, headers=headers, data=form, files=files)
|
||||
except httpx.HTTPError as exc:
|
||||
log.error("OpenAI transcription request failed: %s", exc)
|
||||
raise UpstreamError(f"OpenAI Whisper request se nezdařil: {exc}") from exc
|
||||
|
||||
if resp.status_code >= 400:
|
||||
snippet = resp.text[:500]
|
||||
log.warning("OpenAI transcription returned %s: %s", resp.status_code, snippet)
|
||||
raise UpstreamError(
|
||||
f"OpenAI Whisper vrátil chybu {resp.status_code}.",
|
||||
detail=snippet,
|
||||
)
|
||||
|
||||
data = resp.json()
|
||||
return data.get("text", "") or ""
|
||||
|
||||
|
||||
async def merge_transcripts(
|
||||
*,
|
||||
api_key: str,
|
||||
model: str,
|
||||
system_prompt: str,
|
||||
text_deepgram: str,
|
||||
text_whisper: str,
|
||||
) -> str:
|
||||
"""Sloučí dva přepisy do jednoho přes Chat Completions dle system promptu."""
|
||||
headers = {"Authorization": f"Bearer {api_key}"}
|
||||
payload = {
|
||||
"model": model,
|
||||
"messages": [
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": f"Text z Deepgram: {text_deepgram}"},
|
||||
{"role": "user", "content": f"Text z OpenAI Whisper: {text_whisper}"},
|
||||
],
|
||||
}
|
||||
url = f"{OPENAI_BASE_URL}/chat/completions"
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=UPSTREAM_TIMEOUT_SECONDS) as client:
|
||||
resp = await client.post(url, headers=headers, json=payload)
|
||||
except httpx.HTTPError as exc:
|
||||
log.error("OpenAI chat request failed: %s", exc)
|
||||
raise UpstreamError(f"OpenAI chat (merge) request se nezdařil: {exc}") from exc
|
||||
|
||||
if resp.status_code >= 400:
|
||||
snippet = resp.text[:500]
|
||||
log.warning("OpenAI chat returned %s: %s", resp.status_code, snippet)
|
||||
raise UpstreamError(
|
||||
f"OpenAI chat (merge) vrátil chybu {resp.status_code}.",
|
||||
detail=snippet,
|
||||
)
|
||||
|
||||
data = resp.json()
|
||||
try:
|
||||
return data["choices"][0]["message"]["content"] or ""
|
||||
except (KeyError, IndexError, TypeError) as exc:
|
||||
log.error("Unexpected OpenAI chat response shape: %s", exc)
|
||||
raise UpstreamError("Neočekávaná struktura odpovědi z OpenAI chatu.") from exc
|
||||
Reference in New Issue
Block a user