ivanoctaviogaitansantos commited on
Commit
23eb041
·
verified ·
1 Parent(s): 0e995ea

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +119 -110
app.py CHANGED
@@ -1,124 +1,133 @@
1
- // VALIDACIÓN DE SEGURIDAD - Lovable debe implementar esto
2
- function validateHFOnly(endpoint) {
3
- const allowedDomains = [
4
- 'api-inference.huggingface.co',
5
- 'huggingface.co'
6
- ];
7
-
8
- const url = new URL(endpoint);
9
- if (!allowedDomains.includes(url.hostname)) {
10
- throw new Error('BLOQUEO: Intento de usar plataforma no autorizada');
11
- }
12
- }
13
 
14
- // USO EN TODAS LAS LLAMADAS
15
- async function secureHFRequest(model, payload) {
16
- const endpoint = `https://api-inference.huggingface.co/models/${model}`;
17
- validateHFOnly(endpoint); // Bloquea si no es HF
18
-
19
- // Proceder con la solicitud...
20
- }// MODELOS PERMITIDOS - LISTA BLANCA
21
- const ALLOWED_MODELS = {
22
- chat: ['gpt2', 'gpt2-medium', 'gpt2-large', 'gpt2-xl'],
23
- image: [
24
- 'black-forest-labs/FLUX.1-dev',
25
- 'black-forest-labs/FLUX.1-schnell',
26
- 'black-forest-labs/FLUX.1-schnell-4bit'
27
- ]
28
- };function isHuggingFaceEndpoint(url) {
29
- return url.includes('huggingface.co') &&
30
- !url.includes('replicate') &&
31
- !url.includes('openai') &&
32
- !url.includes('stability');
33
- "Error: Solo usamos Hugging Face.""Modelos actuales: FLUX.1-dev, FLUX.1-schnell, FLUX.1-schnell-4bit"
34
- Todos gratuitos con tu token de HF."Usuario: "Genera un paisaje"
35
- → GTP-FLUX-BAT detecta necesidad de imagen
36
- → SOLO consulta modelos HF de la lista blanca
37
- → Si falla FLUX.1-dev, intenta FLUX.1-schnell
38
- → Si falla FLUX.1-schnell, intenta FLUX.1-schnell-4bit
39
- → Si todos fallan: "Hugging Face no disponible, intenta más tarde"
40
- → NUNCA: "Usando DALL-E..." o "Conectando a Replicate...""Crear un chatbot llamado 'GTP-FLUX-BAT' que integre conversación natural con generación automática de imágenes usando EXCLUSIVAMENTE modelos gratuitos de Hugging Face.
41
 
42
- BLOQUEO ABSOLUTO: NO usar APIs de pago, NO usar Replicate, NO usar OpenAI, NO usar Stability AI directo, SOLO Hugging Face Inference API.
 
 
 
 
 
43
 
44
- ARQUITECTURA TÉCNICA:
 
 
 
 
 
 
45
 
46
- 1. **MOTOR DE CHAT (Hugging Face):**
47
- - Modelo: 'gpt2-large' de Hugging Face
48
- - Endpoint: https://api-inference.huggingface.co/models/gpt2-large
49
-
50
- 2. **MOTORES DE IMAGEN (Hugging Face EXCLUSIVO):**
51
- - PRIMARIO: 'black-forest-labs/FLUX.1-dev'
52
- - SECUNDARIO: 'black-forest-labs/FLUX.1-schnell'
53
- - TERCIARIO: 'black-forest-labs/FLUX.1-schnell-4bit'
54
- - Endpoint: https://api-inference.huggingface.co/models/[MODELO]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
- 3. **LÓGICA DE GENERACIÓN BLOQUEADA:**
57
- - SOLO usar Hugging Face Inference API
58
- - NUNCA redirigir a otras plataformas
59
- - Si un modelo falla, intentar el siguiente modelo de HF
60
- - MOSTRAR ERROR si todos los modelos de HF fallan
61
 
62
- CÓDIGO DE IMPLEMENTACIÓN:
 
63
 
64
- const HF_CHAT_MODEL = 'gpt2-large';
65
- const HF_IMAGE_MODELS = [
66
- 'black-forest-labs/FLUX.1-dev',
67
- 'black-forest-labs/FLUX.1-schnell',
68
- 'black-forest-labs/FLUX.1-schnell-4bit'
69
- ];
 
70
 
71
- // SOLO Hugging Face - BLOQUEAR otras APIs
72
- async function generateImageHFOnly(prompt) {
73
- for (const model of HF_IMAGE_MODELS) {
74
- try {
75
- const response = await fetch(
76
- `https://api-inference.huggingface.co/models/${model}`,
77
- {
78
- method: 'POST',
79
- headers: {
80
- 'Authorization': `Bearer ${process.env.HF_TOKEN}`,
81
- 'Content-Type': 'application/json'
82
- },
83
- body: JSON.stringify({
84
- inputs: prompt,
85
- parameters: {
86
- num_inference_steps: 20,
87
- guidance_scale: 7.5,
88
- width: 1024,
89
- height: 1024
90
- }
91
- })
92
- }
93
- );
94
-
95
- if (response.ok) {
96
- return await response.blob();
97
- }
98
- } catch (error) {
99
- continue; // Intentar siguiente modelo de HF
100
- }
101
- }
102
- throw new Error('Todos los modelos de Hugging Face están temporalmente no disponibles');
103
- }
104
 
105
- INTERFAZ Y FLUJO:
 
 
 
 
 
 
 
106
 
107
- - Chat conversacional natural
108
- - Detección automática de solicitudes de imágenes
109
- - Generación con modelos HF sin interacción del usuario
110
- - Mensajes de error específicos: 'Servicio Hugging Face no disponible'
111
- - Diseño unificado donde imágenes aparecen en la conversación
112
 
113
- VALIDACIÓN DE IMPLEMENTACIÓN:
 
 
 
 
 
114
 
115
- - Verificar que TODAS las llamadas sean a 'api-inference.huggingface.co'
116
- - Confirmar que los modelos sean EXACTAMENTE los especificados
117
- - Rechazar cualquier alternativa de pago o otras plataformas
118
- - Usar SOLO el token de Hugging Face para autenticación
 
 
 
119
 
120
- PALABRAS CLAVE BLOQUEADAS:
121
- NO 'replicate', NO 'openai', NO 'stabilityai', NO 'midjourney',
122
- NO 'dall-e', NO 'commercial API', SOLO 'huggingface', SOLO 'inference API'
 
123
 
124
- ESTE SISTEMA DEBE SER 100% GRATUITO USANDO EXCLUSIVAMENTE HUGGING FACE."
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ GTP-FLUX-BAT: Chat + Imágenes con Hugging Face (100% GRATIS)
4
+ - Solo modelos HF permitidos
5
+ - Bloqueo total a otras APIs
6
+ - Genera imágenes con FLUX.1
7
+ - Chat con gpt2-large
8
+ """
 
 
 
 
9
 
10
+ import gradio as gr
11
+ import requests
12
+ import io
13
+ from PIL import Image
14
+ import os
15
+ from urllib.parse import urlparse
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ # --- VALIDACIÓN DE SEGURIDAD ---
18
+ def validate_hf_only(endpoint: str):
19
+ allowed = ["api-inference.huggingface.co", "huggingface.co"]
20
+ hostname = urlparse(endpoint).hostname
21
+ if hostname not in allowed:
22
+ raise ValueError("BLOQUEO: Solo se permite Hugging Face")
23
 
24
+ # --- MODELOS PERMITIDOS ---
25
+ HF_CHAT_MODEL = "gpt2-large"
26
+ HF_IMAGE_MODELS = [
27
+ "black-forest-labs/FLUX.1-dev",
28
+ "black-forest-labs/FLUX.1-schnell",
29
+ "black-forest-labs/FLUX.1-schnell-4bit"
30
+ ]
31
 
32
+ # --- GENERAR TEXTO CON HF ---
33
+ def generate_text_hf(prompt: str, hf_token: str):
34
+ validate_hf_only("https://api-inference.huggingface.co")
35
+ url = f"https://api-inference.huggingface.co/models/{HF_CHAT_MODEL}"
36
+ headers = {"Authorization": f"Bearer {hf_token}"}
37
+ payload = {"inputs": prompt, "parameters": {"max_length": 100}}
38
+ try:
39
+ response = requests.post(url, headers=headers, json=payload, timeout=30)
40
+ if response.status_code == 200:
41
+ return response.json()[0]["generated_text"]
42
+ except:
43
+ pass
44
+ return "No pude generar texto. Intenta más tarde."# --- GENERAR IMAGEN CON HF (solo lista blanca) ---
45
+ def generate_image_hf_only(prompt: str, hf_token: str):
46
+ validate_hf_only("https://api-inference.huggingface.co")
47
+ for model in HF_IMAGE_MODELS:
48
+ try:
49
+ url = f"https://api-inference.huggingface.co/models/{model}"
50
+ headers = {"Authorization": f"Bearer {hf_token}"}
51
+ payload = {
52
+ "inputs": prompt,
53
+ "parameters": {
54
+ "num_inference_steps": 20,
55
+ "guidance_scale": 7.5,
56
+ "width": 1024,
57
+ "height": 1024
58
+ }
59
+ }
60
+ response = requests.post(url, headers=headers, json=payload, timeout=60)
61
+ if response.status_code == 200:
62
+ return response.content # bytes
63
+ except Exception as e:
64
+ print(f"Modelo {model} falló: {e}")
65
+ continue
66
+ raise RuntimeError("Todos los modelos de imagen HF están temporalmente no disponibles")# --- DETECCIÓN DE IMAGEN ---
67
+ def needs_image(user_input: str) -> bool:
68
+ keywords = ["imagen", "genera", "dibuja", "foto", "paisaje", "retrato", "crea"]
69
+ return any(k in user_input.lower() for k in keywords)
70
 
71
+ # --- RESPUESTA COMPLETA ---
72
+ def respond_to_user(message: str, history: list, hf_token: str):
73
+ if not hf_token or not hf_token.startswith("hf_"):
74
+ return history + [(message, "Ingresa un token válido de Hugging Face.")], None
 
75
 
76
+ bot_response = generate_text_hf(message, hf_token)
77
+ image_bytes = None
78
 
79
+ if needs_image(message):
80
+ try:
81
+ bot_response += "\n\nGenerando imagen..."
82
+ image_bytes = generate_image_hf_only(message, hf_token)
83
+ bot_response = bot_response.replace("Generando imagen...", "Imagen generada:")
84
+ except Exception as e:
85
+ bot_response += f"\n\n{str(e)}"
86
 
87
+ history.append((message, bot_response))
88
+ return history, image_bytes# --- INTERFAZ GRADIO ---
89
+ with gr.Blocks(title="GTP-FLUX-BAT", theme=gr.themes.Soft()) as demo:
90
+ gr.Markdown("""
91
+ # GTP-FLUX-BAT
92
+ **Chat + Imágenes 100% GRATIS con Hugging Face**
93
+ Modelos: `gpt2-large` + `FLUX.1-dev/schnell`
94
+ **SOLO Hugging Face · Nunca Replicate/OpenAI**
95
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
+ with gr.Row():
98
+ token_input = gr.Textbox(
99
+ label="Token de Hugging Face",
100
+ placeholder="hf_xxxxxxxxxxxxxxxxxxxxx",
101
+ type="password",
102
+ scale=3
103
+ )
104
+ gr.Markdown("**Obtén tu token en [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens)**")
105
 
106
+ chatbot = gr.Chatbot(height=500)
107
+ msg = gr.Textbox(label="Tu mensaje", placeholder="Escribe aquí...", scale=4)
108
+ clear = gr.Button("Limpiar chat")
109
+ img_out = gr.Image(label="Imagen generada", height=400)
 
110
 
111
+ # --- EVENTOS ---
112
+ def submit(message, history, token):
113
+ if not message.strip():
114
+ return history, None
115
+ new_history, img = respond_to_user(message, history, token)
116
+ return new_history, "", img
117
 
118
+ msg.submit(submit, [msg, chatbot, token_input], [chatbot, msg, img_out])
119
+ clear.click(lambda: ([], None), outputs=[chatbot, img_out])# --- MENSAJE DE INICIO ---
120
+ gr.Markdown("""
121
+ ### Instrucciones:
122
+ 1. Pega tu **token de Hugging Face** arriba
123
+ 2. Escribe: _"Genera un paisaje al atardecer"_
124
+ 3. ¡El bot responde y genera la imagen automáticamente!
125
 
126
+ **Modelos usados:**
127
+ - Texto: `gpt2-large`
128
+ - Imagen: `FLUX.1-dev` `schnell` `4bit` (solo HF)
129
+ """)
130
 
131
+ # --- LANZAR ---
132
+ if __name__ == "__main__":
133
+ demo.launch(share=True)