Update app.py
Browse files
app.py
CHANGED
|
@@ -44,7 +44,7 @@ if GOOGLE_API_KEY:
|
|
| 44 |
except Exception as e:
|
| 45 |
logger.critical(f"Erreur critique lors de l'initialisation du client Gemini: {e}", exc_info=True)
|
| 46 |
else:
|
| 47 |
-
logger.critical("
|
| 48 |
|
| 49 |
task_results = {}
|
| 50 |
|
|
@@ -97,6 +97,52 @@ def save_user_image(image_data, filename, task_id):
|
|
| 97 |
logger.error(f"Erreur lors de la sauvegarde de l'image {filename}: {e}")
|
| 98 |
return None
|
| 99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
def get_all_tasks_info():
|
| 101 |
"""Récupère toutes les informations des tâches pour le centre de gestion."""
|
| 102 |
tasks_info = []
|
|
@@ -251,33 +297,31 @@ def process_files_background(task_id, files_data, resolution_style):
|
|
| 251 |
|
| 252 |
contents = []
|
| 253 |
logger.info(f"[Task {task_id}] Préparation des fichiers pour l'API Gemini.")
|
|
|
|
|
|
|
| 254 |
for file_info in files_data:
|
|
|
|
|
|
|
|
|
|
| 255 |
if file_info['type'].startswith('image/'):
|
| 256 |
-
logger.info(f"[Task {task_id}] Traitement de l'image '{file_info['filename']}'.")
|
| 257 |
-
|
| 258 |
-
# Sauvegarder l'image utilisateur
|
| 259 |
saved_filename = save_user_image(file_info['data'], file_info['filename'], task_id)
|
| 260 |
-
|
| 261 |
-
img = Image.open(io.BytesIO(file_info['data']))
|
| 262 |
-
buffered = io.BytesIO()
|
| 263 |
-
img.save(buffered, format="PNG")
|
| 264 |
-
img_base64_str = base64.b64encode(buffered.getvalue()).decode()
|
| 265 |
-
contents.append({'inline_data': {'mime_type': 'image/png', 'data': img_base64_str}})
|
| 266 |
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
|
|
|
| 274 |
uploaded_file_refs.append(file_ref)
|
| 275 |
contents.append(file_ref)
|
| 276 |
-
|
| 277 |
-
|
|
|
|
| 278 |
|
| 279 |
if not contents:
|
| 280 |
-
raise ValueError("Aucun
|
| 281 |
|
| 282 |
prompt_to_use = get_prompt_for_style(resolution_style)
|
| 283 |
if not prompt_to_use:
|
|
@@ -285,7 +329,8 @@ def process_files_background(task_id, files_data, resolution_style):
|
|
| 285 |
contents.append(prompt_to_use)
|
| 286 |
|
| 287 |
task_results[task_id]['status'] = 'generating_latex'
|
| 288 |
-
logger.info(f"[Task {task_id}] Envoi de la requête à l'API Gemini (modèle gemini-2.5-
|
|
|
|
| 289 |
gemini_response = client.models.generate_content(
|
| 290 |
model="gemini-2.5-flash",
|
| 291 |
contents=contents,
|
|
@@ -325,14 +370,15 @@ def process_files_background(task_id, files_data, resolution_style):
|
|
| 325 |
task_results[task_id]['error'] = str(e)
|
| 326 |
task_results[task_id]['response'] = f"Une erreur est survenue: {str(e)}"
|
| 327 |
finally:
|
|
|
|
| 328 |
if uploaded_file_refs:
|
| 329 |
-
logger.info(f"[Task {task_id}] Nettoyage des {len(uploaded_file_refs)} fichiers temporaires de l'API
|
| 330 |
for file_ref in uploaded_file_refs:
|
| 331 |
try:
|
| 332 |
client.files.delete(file_ref)
|
| 333 |
-
logger.info(f"[Task {task_id}] Fichier temporaire
|
| 334 |
except Exception as del_e:
|
| 335 |
-
logger.warning(f"[Task {task_id}] Échec de la suppression du fichier temporaire
|
| 336 |
|
| 337 |
# --- Routes Flask (API Endpoints) ---
|
| 338 |
|
|
|
|
| 44 |
except Exception as e:
|
| 45 |
logger.critical(f"Erreur critique lors de l'initialisation du client Gemini: {e}", exc_info=True)
|
| 46 |
else:
|
| 47 |
+
logger.critical("GOOGLE_API_KEY non trouvé dans les variables d'environnement. Le service ne fonctionnera pas.")
|
| 48 |
|
| 49 |
task_results = {}
|
| 50 |
|
|
|
|
| 97 |
logger.error(f"Erreur lors de la sauvegarde de l'image {filename}: {e}")
|
| 98 |
return None
|
| 99 |
|
| 100 |
+
def upload_file_to_genai_api(file_data, filename, mime_type):
|
| 101 |
+
"""Upload un fichier vers l'API Files de Google GenAI."""
|
| 102 |
+
try:
|
| 103 |
+
# Déterminer l'extension appropriée
|
| 104 |
+
if mime_type.startswith('image/'):
|
| 105 |
+
if mime_type == 'image/jpeg':
|
| 106 |
+
suffix = '.jpg'
|
| 107 |
+
elif mime_type == 'image/png':
|
| 108 |
+
suffix = '.png'
|
| 109 |
+
elif mime_type == 'image/gif':
|
| 110 |
+
suffix = '.gif'
|
| 111 |
+
elif mime_type == 'image/webp':
|
| 112 |
+
suffix = '.webp'
|
| 113 |
+
else:
|
| 114 |
+
suffix = '.jpg' # Par défaut
|
| 115 |
+
elif mime_type == 'application/pdf':
|
| 116 |
+
suffix = '.pdf'
|
| 117 |
+
else:
|
| 118 |
+
suffix = '.tmp'
|
| 119 |
+
|
| 120 |
+
# Créer un fichier temporaire
|
| 121 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
|
| 122 |
+
temp_file.write(file_data)
|
| 123 |
+
temp_file_path = temp_file.name
|
| 124 |
+
|
| 125 |
+
logger.info(f"Upload du fichier '{filename}' ({len(file_data)} bytes) vers l'API Files de Google GenAI...")
|
| 126 |
+
|
| 127 |
+
# Upload vers l'API Files
|
| 128 |
+
file_ref = client.files.upload(file=temp_file_path)
|
| 129 |
+
|
| 130 |
+
# Nettoyer le fichier temporaire
|
| 131 |
+
os.unlink(temp_file_path)
|
| 132 |
+
|
| 133 |
+
logger.info(f"Fichier '{filename}' uploadé avec succès. Référence: {file_ref.name}")
|
| 134 |
+
return file_ref
|
| 135 |
+
|
| 136 |
+
except Exception as e:
|
| 137 |
+
logger.error(f"Erreur lors de l'upload du fichier '{filename}' vers l'API Files: {e}")
|
| 138 |
+
# Nettoyer le fichier temporaire en cas d'erreur
|
| 139 |
+
try:
|
| 140 |
+
if 'temp_file_path' in locals():
|
| 141 |
+
os.unlink(temp_file_path)
|
| 142 |
+
except:
|
| 143 |
+
pass
|
| 144 |
+
return None
|
| 145 |
+
|
| 146 |
def get_all_tasks_info():
|
| 147 |
"""Récupère toutes les informations des tâches pour le centre de gestion."""
|
| 148 |
tasks_info = []
|
|
|
|
| 297 |
|
| 298 |
contents = []
|
| 299 |
logger.info(f"[Task {task_id}] Préparation des fichiers pour l'API Gemini.")
|
| 300 |
+
|
| 301 |
+
# Traiter tous les fichiers en utilisant l'API Files
|
| 302 |
for file_info in files_data:
|
| 303 |
+
logger.info(f"[Task {task_id}] Traitement du fichier '{file_info['filename']}' ({file_info['type']}).")
|
| 304 |
+
|
| 305 |
+
# Sauvegarder l'image utilisateur si c'est une image
|
| 306 |
if file_info['type'].startswith('image/'):
|
|
|
|
|
|
|
|
|
|
| 307 |
saved_filename = save_user_image(file_info['data'], file_info['filename'], task_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
|
| 309 |
+
# Upload vers l'API Files de Google GenAI
|
| 310 |
+
file_ref = upload_file_to_genai_api(
|
| 311 |
+
file_info['data'],
|
| 312 |
+
file_info['filename'],
|
| 313 |
+
file_info['type']
|
| 314 |
+
)
|
| 315 |
+
|
| 316 |
+
if file_ref:
|
| 317 |
uploaded_file_refs.append(file_ref)
|
| 318 |
contents.append(file_ref)
|
| 319 |
+
logger.info(f"[Task {task_id}] Fichier '{file_info['filename']}' uploadé avec succès. Référence: {file_ref.name}")
|
| 320 |
+
else:
|
| 321 |
+
logger.warning(f"[Task {task_id}] Échec de l'upload du fichier '{file_info['filename']}'. Fichier ignoré.")
|
| 322 |
|
| 323 |
if not contents:
|
| 324 |
+
raise ValueError("Aucun fichier n'a pu être uploadé vers l'API Files de Google GenAI.")
|
| 325 |
|
| 326 |
prompt_to_use = get_prompt_for_style(resolution_style)
|
| 327 |
if not prompt_to_use:
|
|
|
|
| 329 |
contents.append(prompt_to_use)
|
| 330 |
|
| 331 |
task_results[task_id]['status'] = 'generating_latex'
|
| 332 |
+
logger.info(f"[Task {task_id}] Envoi de la requête à l'API Gemini (modèle gemini-2.5-flash) avec {len(uploaded_file_refs)} fichier(s).")
|
| 333 |
+
|
| 334 |
gemini_response = client.models.generate_content(
|
| 335 |
model="gemini-2.5-flash",
|
| 336 |
contents=contents,
|
|
|
|
| 370 |
task_results[task_id]['error'] = str(e)
|
| 371 |
task_results[task_id]['response'] = f"Une erreur est survenue: {str(e)}"
|
| 372 |
finally:
|
| 373 |
+
# Nettoyer tous les fichiers uploadés vers l'API Files
|
| 374 |
if uploaded_file_refs:
|
| 375 |
+
logger.info(f"[Task {task_id}] Nettoyage des {len(uploaded_file_refs)} fichiers temporaires de l'API Files.")
|
| 376 |
for file_ref in uploaded_file_refs:
|
| 377 |
try:
|
| 378 |
client.files.delete(file_ref)
|
| 379 |
+
logger.info(f"[Task {task_id}] Fichier temporaire '{file_ref.name}' supprimé de l'API Files.")
|
| 380 |
except Exception as del_e:
|
| 381 |
+
logger.warning(f"[Task {task_id}] Échec de la suppression du fichier temporaire '{file_ref.name}': {del_e}")
|
| 382 |
|
| 383 |
# --- Routes Flask (API Endpoints) ---
|
| 384 |
|