feat(backend): add SaluteSpeech to task dispatch (ENGINE_MAP + elif branch)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Daniil
2026-04-04 00:08:27 +03:00
parent 2c9c11fa17
commit c40aeab8be
2 changed files with 29 additions and 11 deletions
+2 -2
View File
@@ -83,7 +83,7 @@ class TranscriptionGenerateRequest(Schema):
file_key: str = Field(..., description="Storage key of the input file")
project_id: UUID | None = Field(default=None, description="Associated project ID")
engine: Literal["whisper", "google"] = Field(
engine: Literal["whisper", "google", "salutespeech"] = Field(
default="whisper", description="Transcription engine to use"
)
language: str | None = Field(default=None, description="Language code (e.g., 'en')")
@@ -164,5 +164,5 @@ class TaskWebhookEvent(Schema):
)
)
if not has_update:
raise ValueError("Webhook event must include at least one update field.")
raise ValueError("Событие вебхука должно содержать хотя бы одно обновляемое поле.")
return self
+27 -9
View File
@@ -88,14 +88,15 @@ ERROR_UNKNOWN_ENGINE = "Неизвестный движок транскрипц
ENGINE_MAP: dict[str, str] = {
"whisper": "LOCAL_WHISPER",
"google": "GOOGLE_SPEECH_CLOUD",
"salutespeech": "SALUTE_SPEECH",
}
MESSAGE_STARTING = "Starting"
MESSAGE_COMPLETED = "Completed"
MESSAGE_PROBING_MEDIA = "Probing media"
MESSAGE_PROCESSING = "Processing"
MESSAGE_CONVERTING = "Converting"
MESSAGE_RENDERING_CAPTIONS = "Rendering captions"
MESSAGE_STARTING = "Запуск"
MESSAGE_COMPLETED = "Завершено"
MESSAGE_PROBING_MEDIA = "Анализ медиафайла"
MESSAGE_PROCESSING = "Обработка"
MESSAGE_CONVERTING = "Конвертация"
MESSAGE_RENDERING_CAPTIONS = "Рендеринг субтитров"
MESSAGE_CANCELLED = "Отменено пользователем"
MESSAGE_EXTRACTING_FRAMES = "Извлечение кадров"
MESSAGE_UPLOADING_FRAMES = "Загрузка кадров"
@@ -560,7 +561,7 @@ def media_convert_actor(
try:
if output_format.lower() != "mp4":
raise ValueError(f"Unsupported format: {output_format}")
raise ValueError(f"Неподдерживаемый формат: {output_format}")
storage = _get_storage_service()
_send_webhook_event(
@@ -612,6 +613,7 @@ def transcription_generate_actor(
"""Generate transcription from audio/video file."""
from cpv3.modules.transcription.service import (
transcribe_with_google_speech,
transcribe_with_salute_speech,
transcribe_with_whisper,
)
@@ -698,6 +700,22 @@ def transcription_generate_actor(
storage, file_key=file_key, language_codes=language_codes
)
)
elif engine == "salutespeech":
audio_stream = next(
(s for s in probe.streams if s.codec_type == "audio"), None
)
sr = int(audio_stream.sample_rate) if audio_stream and audio_stream.sample_rate else 16000
document = _run_async(
transcribe_with_salute_speech(
storage,
file_key=file_key,
language=language,
model=model,
sample_rate=sr,
job_id=job_uuid,
on_progress=_on_whisper_progress,
)
)
else:
raise ValueError(ERROR_UNKNOWN_ENGINE.format(engine=engine))
@@ -1159,7 +1177,7 @@ class TaskService:
"""Apply a webhook event to the job and store a job event record."""
job = await self._job_repo.get_by_id(job_id)
if job is None:
raise ValueError(f"Job {job_id} not found")
raise ValueError(f"Задача {job_id} не найдена")
if job.status in (JOB_STATUS_DONE, JOB_STATUS_FAILED, JOB_STATUS_CANCELLED):
logger.info("Ignoring webhook for terminal job %s (status=%s)", job_id, job.status)
@@ -1644,7 +1662,7 @@ class TaskService:
transcription_repo = TranscriptionRepository(self._session)
transcription = await transcription_repo.get_by_id(request.transcription_id)
if transcription is None:
raise ValueError(f"Transcription {request.transcription_id} not found")
raise ValueError(f"Транскрипция {request.transcription_id} не найдена")
user_folder = get_user_folder(requester)
resolved_folder = (