File size: 6,819 Bytes
17a3958
f1ebcf1
 
 
 
 
17a3958
f1ebcf1
 
 
17a3958
f1ebcf1
 
 
 
 
 
 
 
17a3958
f1ebcf1
 
17a3958
f1ebcf1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17a3958
f1ebcf1
90a8cd5
 
 
 
f1ebcf1
 
90a8cd5
 
f1ebcf1
90a8cd5
f1ebcf1
17a3958
f1ebcf1
 
90a8cd5
 
f1ebcf1
90a8cd5
 
 
 
 
 
 
 
f1ebcf1
90a8cd5
 
 
 
 
 
 
17a3958
f1ebcf1
 
 
 
 
 
 
 
203c68f
 
 
 
52c98dd
7f876c1
52c98dd
7f876c1
2cd32af
52c98dd
203c68f
 
c064060
203c68f
52c98dd
7f876c1
52c98dd
 
 
c064060
 
7f876c1
 
17a3958
 
f1ebcf1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
"""
FLUX Image Generator - Nineteen.ai API (Versione HF Spaces)
--------------------------------------
Questo script utilizza l'API di Nineteen.ai per generare immagini
con il modello FLUX.1-schnell, offrendo un'interfaccia grafica intuitiva.
Versione ottimizzata per Hugging Face Spaces con autenticazione.

Autore: Utente
Data: 09/03/2025
"""

import os
import io
import time
import base64
import requests
import gradio as gr
from PIL import Image
from dotenv import load_dotenv

# Carica le variabili d'ambiente (se presenti)
load_dotenv()

class FluxNineteenGenerator:
    """
    Classe per generare immagini utilizzando il modello FLUX.1-schnell
    attraverso l'API di Nineteen.ai.
    """
    
    def __init__(self):
        """
        Inizializza il generatore di immagini FLUX tramite API Nineteen.ai.
        """
        print("Inizializzazione del generatore di immagini FLUX Nineteen.ai...")
        
        # Ottieni l'API key da variabile d'ambiente o usa quella predefinita
        self.api_key = os.getenv("NINETEEN_API_KEY", "rayon_6nzcBRzaq8f7iRzFUX2IsscMBGKgmJcO")
        
        # Configurazione dell'API
        self.api_endpoint = "https://api.nineteen.ai/v1/text-to-image"
        self.headers = {
            "Authorization": f"Bearer {self.api_key}",
            "accept": "application/json",
            "Content-Type": "application/json"
        }
        
        # Modelli disponibili
        self.models = ["black-forest-labs/FLUX.1-schnell", "black-forest-labs/FLUX.1-dev"]
        self.default_model = "black-forest-labs/FLUX.1-schnell"
        
        print(f"Generatore inizializzato con modello predefinito: {self.default_model}")
    
    def generate_image(self, prompt, model=None, steps=8, cfg_scale=3, 
                      height=1024, width=1024, negative_prompt=""):
        """
        Genera un'immagine utilizzando l'API di Nineteen.ai.
        
        Args:
            prompt (str): Descrizione testuale dell'immagine da generare
            model (str, optional): Modello da utilizzare
            steps (int): Numero di passi di inferenza
            cfg_scale (float): Scala di guidance per la generazione
            height (int): Altezza dell'immagine in pixel
            width (int): Larghezza dell'immagine in pixel
            negative_prompt (str): Prompt negativo per escludere elementi indesiderati
            
        Returns:
            PIL.Image: L'immagine generata
            str: Messaggio di stato
        """
        if not model:
            model = self.default_model
            
        try:
            # Prepara il payload
            data = {
                "prompt": prompt,
                "model": model,
                "steps": steps,
                "cfg_scale": cfg_scale,
                "height": height,
                "width": width,
                "negativePrompt": negative_prompt
            }
            
            # Log della richiesta
            print(f"Generazione immagine con prompt: '{prompt}'")
            print(f"Parametri: modello={model}, steps={steps}, cfg_scale={cfg_scale}, dimensioni={width}x{height}")
            
            # Effettua la chiamata API
            start_time = time.time()
            response = requests.post(self.api_endpoint, headers=self.headers, json=data)
            end_time = time.time()
            
            # Gestione degli errori
            if response.status_code != 200:
                error_message = f"Errore API: {response.status_code} - {response.text}"
                print(error_message)
                return None, error_message
            
            # Estrai l'immagine in formato base64 dalla risposta
            try:
                image_b64 = response.json()["image_b64"]
                image_data = base64.b64decode(image_b64)
                image = Image.open(io.BytesIO(image_data))
                
                print(f"Immagine generata in {end_time - start_time:.2f} secondi")
                return image, f"Immagine generata in {end_time - start_time:.2f} secondi"
            except KeyError:
                return None, f"Errore: La risposta API non contiene il campo 'image_b64'. Risposta: {response.json()}"
            except Exception as e:
                return None, f"Errore nel decodificare l'immagine: {str(e)}"
                
        except Exception as e:
            error_message = f"Errore durante la generazione dell'immagine: {str(e)}"
            print(error_message)
            return None, error_message

def create_ui(generator):
    """Crea l'interfaccia utente Gradio"""
    with gr.Blocks(title="FLUX Image Generator") as interface:
        gr.Markdown("# 🎨 FLUX Image Generator")
        gr.Markdown("Genera immagini creative utilizzando il modello FLUX.1-schnell di Nineteen.ai")
        
        with gr.Row():
            with gr.Column(scale=4):
                prompt = gr.Textbox(
                    label="Prompt",
                    placeholder="Descrivi l'immagine che vuoi generare...",
                    lines=3
                )
                
                with gr.Row():
                    submit_btn = gr.Button("🎨 Genera", variant="primary")
                    clear_btn = gr.Button("🗑️ Pulisci")
            
            with gr.Column(scale=6):
                image_output = gr.Image(label="Immagine Generata", type="filepath")
                
        # Eventi
        submit_btn.click(
            fn=generator.generate_image,
            inputs=prompt,
            outputs=image_output
        )
        clear_btn.click(
            fn=lambda: (None, ""),
            inputs=None,
            outputs=[image_output, prompt]
        )
        
        return interface

def main():
    """Funzione principale"""
    # Crea il generatore
    generator = FluxNineteenGenerator()
    
    # Crea l'interfaccia
    interface = create_ui(generator)
    
    # Ottieni le credenziali dalle variabili d'ambiente
    username = os.getenv("GRADIO_USERNAME")
    password = os.getenv("GRADIO_PASSWORD")
    
    # Parametri di base per il lancio
    launch_kwargs = {
        "server_name": "0.0.0.0",
    }
    
    # Verifica le credenziali e configura l'autenticazione se necessario
    if username and password:
        print(f"Autenticazione configurata con username: {username}")
        launch_kwargs["auth"] = [(username, password)]
    else:
        print("Autenticazione disabilitata. Su HF Spaces, imposta GRADIO_USERNAME e GRADIO_PASSWORD.")
    
    # Rileva se siamo su Hugging Face Spaces
    if os.getenv("SPACE_ID") is None:
        # Non siamo su HF Spaces, aggiungi share per renderlo accessibile
        launch_kwargs["share"] = True
    
    # Avvia l'interfaccia
    interface.launch(**launch_kwargs)

if __name__ == "__main__":
    main()