Mise a jour media: gestion dynamique HF et securisation payant OpenRouter
Build and Push Docker Image / build-and-push (push) Successful in 37s

This commit is contained in:
xavier committed 2026-08-27 20:37:05 +02:00
1 parent aa0190d218
commit c2c35542d7
1 file changed
+44 -17
+44 -17
View File
@@ -5,6 +5,26 @@ import concurrent.futures
import base64
from modules.logger import log_event
def obtenir_modele_image_hf_dynamique(api_key: str) -> str:
"""Interroge le Hub HF pour trouver le modèle image gratuit le plus populaire ET actif (warm)."""
url = "https://huggingface.co/api/models"
params = {
"pipeline_tag": "text-to-image",
"sort": "downloads",
"direction": -1,
"inference": "warm", # GARANTIT que le modèle est gratuit et en ligne
"limit": 3
}
headers = {"Authorization": f"Bearer {api_key}"} if api_key else {}
try:
resp = requests.get(url, headers=headers, params=params, timeout=5)
if resp.status_code == 200 and len(resp.json()) > 0:
return resp.json()[0]["id"]
except Exception:
pass
# Secours absolu si l'API de liste ne répond pas
return "runwayml/stable-diffusion-v1-5"
def generer_image_cloudflare(prompt: str) -> bytes:
account_id = os.getenv("CLOUDFLARE_ACCOUNT_ID")
api_token = os.getenv("CLOUDFLARE_API_TOKEN")
@@ -36,9 +56,12 @@ def generer_image_openrouter(prompt: str) -> tuple:
"HTTP-Referer": "https://aethas38.duckdns.org",
"X-Title": "Aethas38"
}
modele = "bytedance-seed/seedream-4.5"
payload = {"prompt": prompt, "model": modele}
# LISTE DE REPLI (Fallback) : Maîtrise des coûts tout en évitant les crashs
modeles_payants = ["bytedance-seed/seedream-4.5", "openai/dall-e-3"]
for modele in modeles_payants:
payload = {"prompt": prompt, "model": modele}
try:
resp = requests.post(url, headers=headers, json=payload, timeout=120)
if resp.status_code == 200:
@@ -47,25 +70,29 @@ def generer_image_openrouter(prompt: str) -> tuple:
img_bytes = base64.b64decode(data["data"][0]["b64_json"])
return img_bytes, modele
except Exception as e:
log_event("WARNING", "MEDIA", f"Échec OpenRouter Image : {e}")
log_event("WARNING", "MEDIA", f"Échec OpenRouter ({modele}) : {e}")
continue # Passe au modèle de secours suivant
return None, None
def generer_image_huggingface(prompt: str) -> tuple:
api_key = os.getenv("HUGGINGFACE_API_KEY")
if not api_key: return None, "Clé API manquante"
if not api_key: return None, "Clé API manquante", None
url = "https://router.huggingface.co/hf-inference/models/black-forest-labs/FLUX.1-schnell"
# Sélection dynamique HF + Utilisation de la passerelle de secours réseau (router)
modele_cible = obtenir_modele_image_hf_dynamique(api_key)
url = f"https://router.huggingface.co/hf-inference/models/{modele_cible}"
headers = {"Authorization": f"Bearer {api_key}"}
try:
resp = requests.post(url, headers=headers, json={"inputs": prompt}, timeout=120)
if resp.status_code == 200:
return resp.content, "Succès"
return resp.content, "Succès", modele_cible
else:
return None, f"Erreur HTTP {resp.status_code} : {resp.text}"
return None, f"Erreur HTTP {resp.status_code} : {resp.text}", modele_cible
except Exception as e:
log_event("WARNING", "MEDIA", f"Échec HF : {e}")
return None, f"Exception système : {str(e)}"
return None, f"Exception système : {str(e)}", "Inconnu"
def generer_les_images(prompt: str, fichiers: list, premium: bool) -> tuple:
trace = []
@@ -75,7 +102,6 @@ def generer_les_images(prompt: str, fichiers: list, premium: bool) -> tuple:
trace.append(f"🟢 Lancement Text-to-Image (Premium: {premium})")
# Exécution en parallèle (OpenRouter n'est lancé QUE si premium est True)
with concurrent.futures.ThreadPoolExecutor() as executor:
future_or = executor.submit(generer_image_openrouter, prompt) if premium else None
future_cf = executor.submit(generer_image_cloudflare, prompt)
@@ -83,7 +109,7 @@ def generer_les_images(prompt: str, fichiers: list, premium: bool) -> tuple:
img_or, nom_modele_or = future_or.result() if future_or else (None, None)
img_cf = future_cf.result()
img_hf, msg_hf = future_hf.result()
img_hf, msg_hf, nom_modele_hf = future_hf.result() if future_hf else (None, None, None)
dossier_media = "/DATA/AppData/MULTI-IA-AETHAS38/RAG/Media"
os.makedirs(dossier_media, exist_ok=True)
@@ -91,7 +117,7 @@ def generer_les_images(prompt: str, fichiers: list, premium: bool) -> tuple:
reponse_md = f"**Prompt analysé :** {prompt}\n\n"
fournisseurs_actifs = []
# Traitement OpenRouter
# --- Rendu OpenRouter ---
if future_or is None:
trace.append("⚪ OR : Ignoré (Mode Gratuit)")
elif img_or:
@@ -100,11 +126,11 @@ def generer_les_images(prompt: str, fichiers: list, premium: bool) -> tuple:
reponse_md += f"### 🌐 OpenRouter ({nom_modele_or})\n![OpenRouter](/Media/{nom_or})\n"
reponse_md += f"**[📥 Télécharger l'image OR](/Media/{nom_or})**\n\n---\n\n"
fournisseurs_actifs.append("OpenRouter")
trace.append("🟢 OR : Succès")
trace.append(f"🟢 OR ({nom_modele_or}) : Succès")
else:
trace.append("🔴 OR : Échec")
# Traitement Cloudflare
# --- Rendu Cloudflare ---
if img_cf:
nom_cf = f"img_cf_{int(time.time())}.png"
with open(os.path.join(dossier_media, nom_cf), 'wb') as f: f.write(img_cf)
@@ -115,18 +141,19 @@ def generer_les_images(prompt: str, fichiers: list, premium: bool) -> tuple:
else:
trace.append("🔴 CF : Échec")
# Traitement HuggingFace
# --- Rendu HuggingFace Dynamique ---
if img_hf:
nom_hf = f"img_hf_{int(time.time())}.png"
with open(os.path.join(dossier_media, nom_hf), 'wb') as f: f.write(img_hf)
reponse_md += f"### 🤗 HuggingFace (FLUX.1)\n![HuggingFace](/Media/{nom_hf})\n"
nom_propre = nom_modele_hf.split('/')[-1] if nom_modele_hf else "Générateur"
reponse_md += f"### 🤗 HuggingFace ({nom_propre})\n![HuggingFace](/Media/{nom_hf})\n"
reponse_md += f"**[📥 Télécharger l'image HF](/Media/{nom_hf})**\n\n"
fournisseurs_actifs.append("HuggingFace")
trace.append("🟢 HF : Succès")
trace.append(f"🟢 HF ({nom_propre}) : Succès")
else:
erreur_courte = str(msg_hf)[:50] + "..." if len(str(msg_hf)) > 50 else str(msg_hf)
trace.append(f"🔴 HF : Échec ({erreur_courte})")
reponse_md += f"### 🤗 HuggingFace (FLUX.1)\n*⚠️ Échec de la génération : {msg_hf}*\n\n"
reponse_md += f"### 🤗 HuggingFace\n*⚠️ Échec de la génération : {msg_hf}*\n\n"
if not img_or and not img_cf and not img_hf:
return "*Échec critique : Aucune API n'a pu générer d'image.*", "#ff4444", "Système", "Erreur", trace