generart / app.py
Equityone's picture
Update app.py
3adc659 verified
raw
history blame
8.32 kB
import gradio as gr
import os
from PIL import Image
import requests
import io
import gc
import json
from typing import Tuple, Optional, Dict, Any
import logging
from dotenv import load_dotenv
# Configuration du logging détaillé
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Chargement des variables d'environnement
load_dotenv()
# Styles pour la génération
ART_STYLES = {
"Art Moderne": {
"prompt_prefix": "modern art style poster, professional design",
"negative_prompt": "traditional, photorealistic, cluttered, busy design"
},
"Neo Vintage": {
"prompt_prefix": "vintage style advertising poster, retro design",
"negative_prompt": "modern, digital, contemporary style"
},
"Pop Art": {
"prompt_prefix": "pop art style poster, bold design",
"negative_prompt": "subtle, realistic, traditional art"
},
"Minimaliste": {
"prompt_prefix": "minimalist design poster, clean composition",
"negative_prompt": "complex, detailed, ornate, busy"
}
}
class ImageGenerator:
def __init__(self):
self.API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0"
token = os.getenv('HUGGINGFACE_TOKEN')
if not token:
logger.error("HUGGINGFACE_TOKEN non trouvé dans les variables d'environnement!")
self.headers = {"Authorization": f"Bearer {token}"}
logger.info("ImageGenerator initialisé")
def _build_prompt(self, params: Dict[str, Any]) -> str:
style_info = ART_STYLES.get(params["style"], ART_STYLES["Neo Vintage"])
prompt = f"{style_info['prompt_prefix']}, {params['subject']}"
if params.get("title"):
prompt += f", with text saying '{params['title']}'"
logger.debug(f"Prompt construit: {prompt}")
return prompt
def _get_negative_prompt(self, style: str) -> str:
return ART_STYLES.get(style, ART_STYLES["Neo Vintage"])["negative_prompt"]
def generate(self, params: Dict[str, Any]) -> Tuple[Optional[Image.Image], str]:
try:
# Log des paramètres
logger.info(f"Début de génération avec paramètres: {json.dumps(params, indent=2)}")
# Vérification du token
if 'Bearer None' in self.headers['Authorization']:
return None, "⚠️ Erreur: Token Hugging Face non configuré"
# Construction du prompt
prompt = self._build_prompt(params)
logger.debug(f"Prompt final: {prompt}")
# Configuration de la requête
payload = {
"inputs": prompt,
"parameters": {
"negative_prompt": self._get_negative_prompt(params["style"]),
"num_inference_steps": min(int(35 * (params["quality"]/100)), 40),
"guidance_scale": min(7.5 * (params["creativity"]/10), 10.0),
"width": 768,
"height": 768 if params["orientation"] == "Portrait" else 512
}
}
logger.debug(f"Payload de la requête: {json.dumps(payload, indent=2)}")
# Requête API
logger.info("Envoi de la requête à l'API...")
response = requests.post(
self.API_URL,
headers=self.headers,
json=payload,
timeout=30
)
logger.debug(f"Statut de la réponse: {response.status_code}")
logger.debug(f"Contenu de la réponse: {response.text[:200]}...") # Premiers 200 caractères
if response.status_code == 200:
image = Image.open(io.BytesIO(response.content))
logger.info("Image générée avec succès")
return image, "✨ Création réussie!"
else:
error_msg = f"⚠️ Erreur API {response.status_code}: {response.text}"
logger.error(error_msg)
return None, error_msg
except Exception as e:
error_msg = f"⚠️ Erreur: {str(e)}"
logger.exception("Erreur pendant la génération:")
return None, error_msg
def create_interface():
"""Crée l'interface utilisateur Gradio avec logging"""
logger.info("Création de l'interface Gradio")
css = """
.container { max-width: 1200px; margin: auto; }
.welcome { text-align: center; margin: 20px 0; padding: 20px; background: #1e293b; border-radius: 10px; }
.controls-group { background: #2d3748; padding: 15px; border-radius: 5px; margin: 10px 0; }
"""
generator = ImageGenerator()
with gr.Blocks(css=css) as app:
gr.HTML("""
<div class="welcome">
<h1>🎨 Equity Artisan 3.0</h1>
<p>Assistant de création d'affiches professionnelles</p>
</div>
""")
with gr.Column(elem_classes="container"):
with gr.Group(elem_classes="controls-group"):
with gr.Row():
format_size = gr.Dropdown(
choices=["A4", "A3", "A2", "A1", "A0"],
value="A4",
label="Format"
)
orientation = gr.Radio(
choices=["Portrait", "Paysage"],
value="Portrait",
label="Orientation"
)
with gr.Group(elem_classes="controls-group"):
style = gr.Dropdown(
choices=list(ART_STYLES.keys()),
value="Neo Vintage",
label="Style artistique"
)
with gr.Group(elem_classes="controls-group"):
subject = gr.Textbox(
label="Description",
placeholder="Décrivez votre vision..."
)
title = gr.Textbox(
label="Titre",
placeholder="Titre de l'affiche..."
)
with gr.Group(elem_classes="controls-group"):
with gr.Row():
quality = gr.Slider(
minimum=30,
maximum=50,
value=35,
label="Qualité"
)
creativity = gr.Slider(
minimum=5,
maximum=15,
value=7.5,
label="Créativité"
)
with gr.Row():
generate_btn = gr.Button("✨ Générer", variant="primary")
clear_btn = gr.Button("🗑️ Effacer", variant="secondary")
image_output = gr.Image(label="Aperçu")
status = gr.Textbox(label="Statut", interactive=False)
def generate(*args):
logger.info("Démarrage d'une nouvelle génération")
params = {
"format_size": args[0],
"orientation": args[1],
"style": args[2],
"subject": args[3],
"title": args[4],
"quality": args[5],
"creativity": args[6]
}
result = generator.generate(params)
logger.info(f"Génération terminée avec statut: {result[1]}")
return result
generate_btn.click(
generate,
inputs=[
format_size,
orientation,
style,
subject,
title,
quality,
creativity
],
outputs=[image_output, status]
)
clear_btn.click(
lambda: (None, "🗑️ Image effacée"),
outputs=[image_output, status]
)
logger.info("Interface créée avec succès")
return app
if __name__ == "__main__":
app = create_interface()
logger.info("Démarrage de l'application")
app.launch()