diff --git a/apiApp/routers/ai_conclusion_router.py b/apiApp/routers/ai_conclusion_router.py new file mode 100644 index 0000000..4a8c989 --- /dev/null +++ b/apiApp/routers/ai_conclusion_router.py @@ -0,0 +1,109 @@ +""" +API endpoints для получения AI заключений от GigaAM API +""" +from fastapi import APIRouter, HTTPException +from pydantic import BaseModel +from typing import Optional, List, Dict, Any +from apiApp.database import get_db_session +from apiApp.database.Audio import Audio +from apiApp.database.AiConclusion import AiConclusion +from datetime import datetime +import logging +import uuid + +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): + """ + Сохраняет 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}") + + with get_db_session() as db: + # Находим аудио файл по имени + 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}") + + return AiConclusionResponse( + success=True, + message='Заключение сохранено', + audio_id=str(audio.id), + filename=request.filename + ) + + except HTTPException: + raise + except Exception as e: + logger.error(f"❌ Ошибка при сохранении заключения: {e}") + raise HTTPException( + status_code=500, + detail=str(e) + ) diff --git a/main.py b/main.py index 5cc805b..7b5dc0a 100644 --- a/main.py +++ b/main.py @@ -8,6 +8,7 @@ import logging from apiApp.config import APP_TITLE, APP_VERSION, API_V1_PREFIX, UPLOAD_FOLDER, DATABASE_URL, PORT, HOST from apiApp.database import engine, Base from apiApp.routers import audio_router, recognition_router +from apiApp.routers.ai_conclusion_router import ai_conclusion_router # Настройка логирования logging.basicConfig(level=logging.INFO) @@ -56,6 +57,7 @@ async def startup_event(): # Подключение routers app.include_router(audio_router, prefix=API_V1_PREFIX, tags=["audio"]) app.include_router(recognition_router, prefix=API_V1_PREFIX, tags=["recognition"]) +app.include_router(ai_conclusion_router, prefix=API_V1_PREFIX, tags=["ai_conclusion"]) # Статические файлы (для загрузки аудио) app.mount("/uploads", StaticFiles(directory=str(UPLOAD_FOLDER)), name="uploads")