fix start recognition external file
This commit is contained in:
@@ -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 apiApp.database import get_db
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
import os, uuid
|
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
|
import aiofiles
|
||||||
|
|
||||||
from apiApp.schemas import (
|
from apiApp.schemas import AudioCreate
|
||||||
AudioCreate,
|
|
||||||
AudioResponse,
|
|
||||||
AudioListResponse,
|
|
||||||
MessageResponse
|
|
||||||
)
|
|
||||||
from apiApp.services import AudioCRUD
|
from apiApp.services import AudioCRUD
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
router = APIRouter(
|
router = APIRouter(
|
||||||
prefix="/external_audio",
|
prefix="/external_audio",
|
||||||
tags=["Внешние аудиофайлы"]
|
tags=["Внешние аудиофайлы"]
|
||||||
@@ -22,10 +23,12 @@ router = APIRouter(
|
|||||||
@router.post("/upload")
|
@router.post("/upload")
|
||||||
async def upload_external_audio(
|
async def upload_external_audio(
|
||||||
file: UploadFile = FastAPIFile(...),
|
file: UploadFile = FastAPIFile(...),
|
||||||
|
callback_url: str = Form(..., description="URL для отправки результата распознавания (FileAudioAPI вызовет GigaAM и затем отправит результат на этот URL)"),
|
||||||
db: Session = Depends(get_db)
|
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"
|
detail=f"File too large. Maximum size: {MAX_UPLOAD_SIZE / (1024*1024)}MB"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Сохранение файла
|
# Сохранение в общей папке под именем uuid+ext; это же имя передаём в GigaAM
|
||||||
file_path = UPLOAD_FOLDER / f"{uuid.uuid4()}{file_ext}"
|
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:
|
try:
|
||||||
async with aiofiles.open(file_path, 'wb') as f:
|
async with aiofiles.open(file_path, 'wb') as f:
|
||||||
await f.write(content)
|
await f.write(content)
|
||||||
@@ -54,9 +60,9 @@ async def upload_external_audio(
|
|||||||
detail=f"Error saving file: {str(e)}"
|
detail=f"Error saving file: {str(e)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Создание записи в БД
|
# Создание записи в БД (filename = имя файла на диске, его же передаём в GigaAM)
|
||||||
try:
|
try:
|
||||||
audio_data = AudioCreate(filename=file.filename)
|
audio_data = AudioCreate(filename=safe_name)
|
||||||
audio = AudioCRUD.create(
|
audio = AudioCRUD.create(
|
||||||
db=db,
|
db=db,
|
||||||
audio_data=audio_data,
|
audio_data=audio_data,
|
||||||
@@ -64,18 +70,56 @@ async def upload_external_audio(
|
|||||||
file_size=len(content),
|
file_size=len(content),
|
||||||
sourse="external"
|
sourse="external"
|
||||||
)
|
)
|
||||||
return audio
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Удаление файла при ошибке записи в БД
|
|
||||||
if os.path.exists(file_path):
|
if os.path.exists(file_path):
|
||||||
os.remove(file_path)
|
os.remove(file_path)
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
detail=f"Error creating database record: {str(e)}"
|
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:
|
||||||
"""
|
"""
|
||||||
Отправка аудиофайла на распознавание
|
Отправка аудиофайла на распознавание в 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))
|
||||||
Reference in New Issue
Block a user