First commit

This commit is contained in:
2025-07-09 02:12:06 +02:00
parent 1a7946495c
commit a5e044d747
23 changed files with 1967 additions and 0 deletions

228
api/app/tasks.py Normal file
View File

@@ -0,0 +1,228 @@
"""
Tâches de traitement pour l'API Cheque Scanner
"""
import os
import sys
import time
import json
import logging
import traceback
from datetime import datetime
import redis
from rq import get_current_job
# Ajouter le module d'extraction au path
sys.path.append('/app/shared')
# Importer les fonctions d'extraction
from extraction import (
extraire_infos_cheque,
get_tessdata_path
)
from .config import settings
# Configuration du logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("cheque_scanner_tasks")
def update_job_status(job_id, status, message=None, progress=None, result=None, texte_brut=None, erreur=None, methode=None):
"""
Met à jour le statut d'une tâche dans Redis
"""
try:
# Connexion à Redis
redis_conn = redis.Redis.from_url(settings.REDIS_URL)
# Préparer les données à mettre à jour
update_data = {
"status": status,
"updated_at": datetime.now().isoformat()
}
if message:
update_data["message"] = message
if progress:
update_data["progress"] = str(progress)
if result:
update_data["result"] = str(result)
if texte_brut:
update_data["texte_brut"] = texte_brut
if erreur:
update_data["erreur"] = erreur
if methode:
update_data["methode"] = methode
if status == "completed":
update_data["completed_at"] = datetime.now().isoformat()
# Mettre à jour les données dans Redis
redis_conn.hset(f"job:{job_id}", mapping=update_data)
logger.info(f"Statut de la tâche {job_id} mis à jour: {status}")
return True
except Exception as e:
logger.error(f"Erreur lors de la mise à jour du statut de la tâche {job_id}: {str(e)}")
return False
def process_cheque_image(job_id, file_path):
"""
Traite une image de chèque pour en extraire les informations
Args:
job_id (str): Identifiant de la tâche
file_path (str): Chemin vers l'image à traiter
Returns:
dict: Résultat de l'extraction
"""
job = get_current_job()
logger.info(f"Début du traitement de l'image: {file_path} (Tâche: {job_id})")
# Mettre à jour le statut
update_job_status(
job_id=job_id,
status="processing",
message="Traitement en cours",
progress=10
)
try:
# Vérifier que le fichier existe
if not os.path.exists(file_path):
raise FileNotFoundError(f"L'image {file_path} n'existe pas")
# Récupérer le chemin vers tessdata
tessdata_path = settings.TESSERACT_DATA_PATH
if not os.path.exists(tessdata_path):
# Essayer de trouver automatiquement
tessdata_path = get_tessdata_path()
# Mise à jour intermédiaire
update_job_status(
job_id=job_id,
status="processing",
message="Extraction des informations en cours",
progress=30
)
# Première tentative avec la langue par défaut
try:
logger.info(f"Tentative d'extraction avec la langue: {settings.DEFAULT_OCR_LANGUAGE}")
update_job_status(
job_id=job_id,
status="processing",
message=f"Extraction avec langue {settings.DEFAULT_OCR_LANGUAGE}",
progress=50
)
infos, texte = extraire_infos_cheque(
chemin_image=file_path,
methode="ocr",
language=settings.DEFAULT_OCR_LANGUAGE,
tessdata=tessdata_path
)
methode = "ocr"
except Exception as e:
logger.warning(f"Échec de la première tentative: {str(e)}")
# Deuxième tentative avec la langue alternative
try:
logger.info(f"Tentative d'extraction avec la langue: {settings.ALTERNATIVE_OCR_LANGUAGE}")
update_job_status(
job_id=job_id,
status="processing",
message=f"Extraction avec langue {settings.ALTERNATIVE_OCR_LANGUAGE}",
progress=60
)
infos, texte = extraire_infos_cheque(
chemin_image=file_path,
methode="ocr",
language=settings.ALTERNATIVE_OCR_LANGUAGE,
tessdata=tessdata_path
)
methode = "ocr"
except Exception as e2:
logger.warning(f"Échec de la deuxième tentative: {str(e2)}")
# Troisième tentative avec la méthode CV
logger.info("Tentative d'extraction avec la méthode CV (sans OCR)")
update_job_status(
job_id=job_id,
status="processing",
message="Extraction par détection de zones (sans OCR)",
progress=70
)
infos, texte = extraire_infos_cheque(
chemin_image=file_path,
methode="cv"
)
methode = "cv"
# Mise à jour finale
update_job_status(
job_id=job_id,
status="processing",
message="Finalisation des résultats",
progress=90
)
# Sauvegarder les résultats dans Redis
update_job_status(
job_id=job_id,
status="completed",
message="Extraction terminée avec succès",
progress=100,
result=infos,
texte_brut=texte,
methode=methode
)
logger.info(f"Traitement terminé pour la tâche {job_id}")
return {
"job_id": job_id,
"status": "completed",
"result": infos,
"methode": methode
}
except Exception as e:
# Capturer l'erreur
error_trace = traceback.format_exc()
logger.error(f"Erreur lors du traitement de l'image: {str(e)}\n{error_trace}")
# Mettre à jour le statut avec l'erreur
update_job_status(
job_id=job_id,
status="failed",
message="Échec du traitement",
erreur=str(e)
)
# Retourner l'erreur
return {
"job_id": job_id,
"status": "failed",
"error": str(e)
}