логирование ошибок транскрибации для битых файлов
This commit is contained in:
@@ -62,6 +62,11 @@ class AiConclusionResponse(BaseModel):
|
||||
error: Optional[str] = None
|
||||
|
||||
|
||||
class RecognitionFailedRequest(BaseModel):
|
||||
filename: str
|
||||
error: str
|
||||
|
||||
|
||||
class ConclusionByFilenameResponse(BaseModel):
|
||||
"""Заключение по имени файла"""
|
||||
filename: str
|
||||
@@ -154,6 +159,11 @@ async def save_ai_conclusion(request: AiConclusionRequest, db: Session = Depends
|
||||
db.commit()
|
||||
logger.info(f"✅ Заключение сохранено для {request.filename}")
|
||||
|
||||
# Обновляем статус распознавания у Audio
|
||||
audio.recognition_status = "completed"
|
||||
audio.recognition_last_error = None
|
||||
db.commit()
|
||||
|
||||
# Для внешних файлов — отправляем результат клиенту из FileAudioAPI
|
||||
if (audio.sourse or "").lower() == "external" and request.callback_url:
|
||||
_send_callback(request.callback_url, audio, conclusion_data)
|
||||
@@ -207,3 +217,25 @@ async def save_ai_conclusion(request: AiConclusionRequest, db: Session = Depends
|
||||
status_code=500,
|
||||
detail=str(e)
|
||||
)
|
||||
|
||||
|
||||
@ai_conclusion_router.post("/conclusion/failed", response_model=AiConclusionResponse)
|
||||
async def mark_recognition_failed(request: RecognitionFailedRequest, db: Session = Depends(get_db)):
|
||||
"""
|
||||
Помечает распознавание как failed для файла (чтобы auto-restore не пытался бесконечно).
|
||||
Используется GigaAM_API при невозможности получить результат.
|
||||
"""
|
||||
audio = db.query(Audio).filter(Audio.filename == request.filename).first()
|
||||
if not audio:
|
||||
raise HTTPException(status_code=404, detail=f"Файл не найден: {request.filename}")
|
||||
|
||||
audio.recognition_status = "failed"
|
||||
audio.recognition_last_error = request.error
|
||||
db.commit()
|
||||
|
||||
return AiConclusionResponse(
|
||||
success=True,
|
||||
message="Recognition marked as failed",
|
||||
audio_id=str(audio.id),
|
||||
filename=audio.filename
|
||||
)
|
||||
|
||||
@@ -13,7 +13,7 @@ from datetime import datetime
|
||||
from apiApp.database import get_db
|
||||
from apiApp.database.Audio import Audio
|
||||
from apiApp.database.AiConclusion import AiConclusion
|
||||
from apiApp.config import AUDIOFILES_PATH
|
||||
from apiApp.config import AUDIOFILES_PATH, MAX_RECOGNITION_ATTEMPTS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
audio_management_router = APIRouter()
|
||||
@@ -32,10 +32,14 @@ def query_audio_without_conclusion(db, limit=None):
|
||||
AiConclusion.audio_id == Audio.id
|
||||
)
|
||||
|
||||
# Берём только те, которые еще можно/нужно распознавать
|
||||
query = db.query(Audio).filter(
|
||||
~subquery
|
||||
).filter(
|
||||
Audio.sourse == "internal"
|
||||
).filter(
|
||||
(Audio.recognition_status.in_(["pending", "processing"])) |
|
||||
((Audio.recognition_status == "failed") & (Audio.recognition_attempts < MAX_RECOGNITION_ATTEMPTS))
|
||||
).order_by(Audio.index_date.asc())
|
||||
|
||||
if limit:
|
||||
@@ -112,6 +116,10 @@ async def register_audio_file(
|
||||
audio.filename = filename
|
||||
audio.file_size = file_size
|
||||
audio.index_date = datetime.utcnow()
|
||||
audio.recognition_status = "pending"
|
||||
audio.recognition_attempts = 0
|
||||
audio.recognition_last_error = None
|
||||
audio.recognition_last_attempt_at = None
|
||||
|
||||
db.add(audio)
|
||||
db.commit()
|
||||
@@ -150,6 +158,11 @@ def process_audio_file(audio_id: str, db: Session):
|
||||
return
|
||||
|
||||
logger.info(f"🎵 Запуск распознавания для {audio.filename}")
|
||||
audio.recognition_status = "processing"
|
||||
audio.recognition_attempts = (audio.recognition_attempts or 0) + 1
|
||||
audio.recognition_last_attempt_at = datetime.utcnow()
|
||||
audio.recognition_last_error = None
|
||||
db.commit()
|
||||
|
||||
# Проверяем что файл существует на диске
|
||||
from apiApp.config import AUDIOFILES_PATH
|
||||
@@ -158,7 +171,9 @@ def process_audio_file(audio_id: str, db: Session):
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
logger.error(f"❌ Файл не найден на диске в FileAudioAPI: {file_path}")
|
||||
# Помечаем audio как проблемный
|
||||
audio.recognition_status = "failed"
|
||||
audio.recognition_last_error = f"File not found on disk: {file_path}"
|
||||
db.commit()
|
||||
return
|
||||
|
||||
file_size = os.path.getsize(file_path)
|
||||
@@ -187,11 +202,20 @@ def process_audio_file(audio_id: str, db: Session):
|
||||
error_detail = response.text
|
||||
logger.error(f"❌ Ошибка запуска распознавания для {audio.filename}: {response.status_code}")
|
||||
logger.error(f" Detail: {error_detail}")
|
||||
audio.recognition_status = "failed"
|
||||
audio.recognition_last_error = f"GigaAM start failed: {response.status_code} {error_detail}"
|
||||
db.commit()
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
logger.error(f"❌ Таймаут при отправке задачи для {audio.filename}")
|
||||
audio.recognition_status = "failed"
|
||||
audio.recognition_last_error = "Timeout when starting recognition in GigaAM"
|
||||
db.commit()
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
logger.error(f"❌ Ошибка подключения к GigaAM API для {audio.filename}: {e}")
|
||||
audio.recognition_status = "failed"
|
||||
audio.recognition_last_error = f"Connection error when starting recognition in GigaAM: {e}"
|
||||
db.commit()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Ошибка при обработке {audio_id}: {e}")
|
||||
|
||||
Reference in New Issue
Block a user