From 8e1175c9bfad03bc5bbcb229a176093d94536f7d Mon Sep 17 00:00:00 2001 From: poturaevpetr Date: Wed, 18 Mar 2026 00:49:26 +0500 Subject: [PATCH] fix start recognition external file --- apiApp/routers/external_audio.py | 82 ++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/apiApp/routers/external_audio.py b/apiApp/routers/external_audio.py index 5c25cd3..ea4ff06 100644 --- a/apiApp/routers/external_audio.py +++ b/apiApp/routers/external_audio.py @@ -1,19 +1,20 @@ -from fastapi import APIRouter, Depends, HTTPException, UploadFile, File as FastAPIFile, status +from fastapi import APIRouter, Depends, HTTPException, UploadFile, File as FastAPIFile, Form, status from apiApp.database import get_db from fastapi.responses import FileResponse from sqlalchemy.orm import Session import os, uuid -from apiApp.config import UPLOAD_FOLDER, ALLOWED_AUDIO_EXTENSIONS, MAX_UPLOAD_SIZE +import logging +from pathlib import Path +import requests + +from apiApp.config import ALLOWED_AUDIO_EXTENSIONS, MAX_UPLOAD_SIZE, AUDIOFILES_PATH, GIGAAM_API_URL import aiofiles -from apiApp.schemas import ( - AudioCreate, - AudioResponse, - AudioListResponse, - MessageResponse -) +from apiApp.schemas import AudioCreate from apiApp.services import AudioCRUD +logger = logging.getLogger(__name__) + router = APIRouter( prefix="/external_audio", tags=["Внешние аудиофайлы"] @@ -22,10 +23,12 @@ router = APIRouter( @router.post("/upload") async def upload_external_audio( file: UploadFile = FastAPIFile(...), + callback_url: str = Form(..., description="URL для отправки результата распознавания (FileAudioAPI вызовет GigaAM и затем отправит результат на этот URL)"), db: Session = Depends(get_db) ): """ - Загрузка внешнего аудиофайла на сервер + Загрузка внешнего аудиофайла. Файл сохраняется в общей папке, после чего + автоматически отправляется на распознавание в GigaAM. Результат придёт на callback_url. """ # Проверка расширения файла @@ -43,8 +46,11 @@ async def upload_external_audio( detail=f"File too large. Maximum size: {MAX_UPLOAD_SIZE / (1024*1024)}MB" ) - # Сохранение файла - file_path = UPLOAD_FOLDER / f"{uuid.uuid4()}{file_ext}" + # Сохранение в общей папке под именем uuid+ext; это же имя передаём в GigaAM + safe_name = f"{uuid.uuid4()}{file_ext}" + upload_dir = Path(AUDIOFILES_PATH) if isinstance(AUDIOFILES_PATH, str) else AUDIOFILES_PATH + upload_dir.mkdir(parents=True, exist_ok=True) + file_path = upload_dir / safe_name try: async with aiofiles.open(file_path, 'wb') as f: await f.write(content) @@ -54,9 +60,9 @@ async def upload_external_audio( detail=f"Error saving file: {str(e)}" ) - # Создание записи в БД + # Создание записи в БД (filename = имя файла на диске, его же передаём в GigaAM) try: - audio_data = AudioCreate(filename=file.filename) + audio_data = AudioCreate(filename=safe_name) audio = AudioCRUD.create( db=db, audio_data=audio_data, @@ -64,18 +70,56 @@ async def upload_external_audio( file_size=len(content), sourse="external" ) - return audio except Exception as e: - # Удаление файла при ошибке записи в БД if os.path.exists(file_path): os.remove(file_path) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Error creating database record: {str(e)}" ) - return {"message": "External audio uploaded successfully"} -def send_to_recognition(file_path: str): + # Запрос на распознавание в GigaAM (файл уже в общей папке по имени safe_name) + task_id, recognition_error = send_to_recognition(filename=safe_name, callback_url=callback_url.strip()) + + # Ответ: запись аудио + данные по постановке в очередь распознавания + result = { + "id": str(audio.id), + "filename": audio.filename, + "index_date": audio.index_date.isoformat() if audio.index_date else None, + "file_path": audio.file_path, + "file_size": audio.file_size, + "sourse": audio.sourse, + } + if task_id: + result["recognition_task_id"] = task_id + result["recognition_status_url"] = f"{GIGAAM_API_URL.rstrip('/')}/api/call/task/{task_id}" + if recognition_error: + result["recognition_error"] = recognition_error + return result + +def send_to_recognition(filename: str, callback_url: str) -> tuple: """ - Отправка аудиофайла на распознавание - """ \ No newline at end of file + Отправка аудиофайла на распознавание в GigaAM. + Файл должен уже лежать в общей папке под именем filename. + + Returns: + (task_id или None, recognition_error или None) + """ + try: + gigaam_url = f"{GIGAAM_API_URL.rstrip('/')}/api/call/external/process" + resp = requests.post( + gigaam_url, + json={"filename": filename, "callback_url": callback_url}, + timeout=15, + ) + if resp.status_code == 202: + data = resp.json() + task_id = data.get("task_id") + logger.info(f"✅ Внешний файл {filename} поставлен в очередь GigaAM, task_id={task_id}") + return (task_id, None) + recognition_error = resp.text or f"HTTP {resp.status_code}" + logger.warning(f"⚠️ GigaAM не принял задачу {filename}: {recognition_error}") + return (None, recognition_error) + except requests.exceptions.RequestException as e: + logger.warning(f"⚠️ Ошибка вызова GigaAM для {filename}: {e}") + return (None, str(e)) \ No newline at end of file