Сервис для хранения файлов аудио, индексации файлов, записи и выдачи результатов распознавания
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

144 lines
5.8 KiB

"""
API endpoints для получения AI заключений от GigaAM API
"""
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel
from typing import Optional, List, Dict, Any
from sqlalchemy.orm import Session
from apiApp.database import get_db
from apiApp.database.Audio import Audio
from apiApp.database.AiConclusion import AiConclusion
from datetime import datetime
import logging
import requests
from apiApp.config import WEBHOOK_ENDPOINT, WEBHOOK_API_KEY
logger = logging.getLogger(__name__)
ai_conclusion_router = APIRouter()
class AiConclusionRequest(BaseModel):
"""Модель запроса для сохранения AI заключения"""
filename: str
transcription: str
corrected_transcription: str
analysis: Dict[str, Any]
segments: Optional[List[Dict[str, Any]]] = []
processing_time_seconds: Optional[float] = 0
class AiConclusionResponse(BaseModel):
"""Модель ответа"""
success: bool
message: Optional[str] = None
audio_id: Optional[str] = None
filename: Optional[str] = None
error: Optional[str] = None
@ai_conclusion_router.post("/conclusion/save", response_model=AiConclusionResponse)
async def save_ai_conclusion(request: AiConclusionRequest, db: Session = Depends(get_db)):
"""
Сохраняет AI заключение от GigaAM API
**Параметры:**
- **filename**: Имя файла (например, "in-xxx.wav")
- **transcription**: Исходная транскрибация
- **corrected_transcription**: Исправленная транскрибация
- **analysis**: Результат анализа (sentiment, topics, summary)
- **segments**: Сегменты диалога (опционально)
- **processing_time_seconds**: Время обработки (опционально)
"""
try:
logger.info(f"📥 Получено AI заключение для файла: {request.filename}")
# Находим аудио файл по имени
audio = db.query(Audio).filter(Audio.filename == request.filename).first()
if not audio:
logger.warning(f" Файл {request.filename} не найден в БД")
raise HTTPException(
status_code=404,
detail=f'Файл {request.filename} не найден'
)
# Проверяем, есть ли уже заключение
existing_conclusion = db.query(AiConclusion).filter(
AiConclusion.audio_id == audio.id
).first()
conclusion_data = {
"transcription": request.transcription,
"ai_transcription": request.corrected_transcription,
"conclusion": request.analysis,
"segments": request.segments,
"processing_time_seconds": request.processing_time_seconds
}
if existing_conclusion:
# Обновляем существующее заключение
logger.info(f"🔄 Обновление существующего заключения для {request.filename}")
existing_conclusion.conclusion = conclusion_data
existing_conclusion.end_date = datetime.utcnow()
else:
# Создаём новое заключение
logger.info(f"✅ Создание нового заключения для {request.filename}")
new_conclusion = AiConclusion(
audio_id=audio.id,
conclusion=conclusion_data,
index_date=datetime.utcnow()
)
db.add(new_conclusion)
db.commit()
logger.info(f"✅ Заключение сохранено для {request.filename}")
# Отправляем webhook в Calls_WEB_Client_main для анализа
try:
logger.info(f"📤 Отправка webhook в Calls_WEB_Client_main для {request.filename}")
webhook_payload = {
"audio_id": str(audio.id),
"filename": request.filename,
"transcription": request.transcription,
"corrected_transcription": request.corrected_transcription,
"segments": request.segments,
"processing_time_seconds": request.processing_time_seconds
}
webhook_response = requests.post(
WEBHOOK_ENDPOINT,
json=webhook_payload,
headers={"X-Webhook-Key": WEBHOOK_API_KEY},
timeout=30
)
if webhook_response.status_code == 200:
logger.info(f"✅ Webhook успешно отправлен для {request.filename}")
else:
logger.warning(f" Webhook вернул статус {webhook_response.status_code}")
logger.warning(f"Response: {webhook_response.text}")
except requests.exceptions.ConnectionError:
logger.error(f"❌ Не удалось подключиться к Calls_WEB_Client_main webhook: {WEBHOOK_ENDPOINT}")
except requests.exceptions.Timeout:
logger.warning(f" Таймаут при отправке webhook для {request.filename}")
except Exception as e:
logger.error(f"❌ Ошибка при отправке webhook: {e}")
return AiConclusionResponse(
success=True,
message='Заключение сохранено и отправлено на анализ',
audio_id=str(audio.id),
filename=request.filename
)
except HTTPException:
raise
except Exception as e:
logger.error(f"❌ Ошибка при сохранении заключения: {e}")
db.rollback()
raise HTTPException(
status_code=500,
detail=str(e)
)