Batuto_chalanIA / app.py
BATUTO-ART's picture
Update app.py
8477739 verified
import os
import gradio as gr
import asyncio
from typing import Optional
from PIL import Image
import base64
import io
import requests
# --- Configuración de claves ---
class Config:
def __init__(self):
self.SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY")
self.BRIA_API_TOKEN = os.getenv("BRIA_API_TOKEN")
self.validate()
def validate(self):
print("🔍 Verificando claves de API...")
if self.SAMBANOVA_API_KEY:
print("✅ SAMBANOVA_API_KEY configurada")
else:
print("❌ SAMBANOVA_API_KEY no encontrada")
if self.BRIA_API_TOKEN:
print("✅ BRIA_API_TOKEN configurado")
else:
print("⚠️ BRIA_API_TOKEN no configurado → generación de imágenes desactivada")
config = Config()
# --- Cliente SambaNova (usando SDK oficial) ---
SambaNova = None
sn_client = None
try:
from sambanova import SambaNova
if config.SAMBANOVA_API_KEY:
sn_client = SambaNova(api_key=config.SAMBANOVA_API_KEY)
print("✅ Cliente SambaNova inicializado")
except Exception as e:
print(f"❌ Error al inicializar SambaNova: {e}")
sn_client = None
# --- Herramientas ---
class AI_Tools:
def __init__(self):
self.sn_client = sn_client
def generate_text(self, prompt: str) -> str:
if not self.sn_client:
return "❌ SambaNova no disponible. Verifica tu clave API."
try:
# ⚠️ Usa un modelo REAL de tu cuenta en SambaNova Cloud
# Ejemplos comunes: "Meta-Llama-3.1-8B-Instruct", "Llama-3.2-3B-Instruct"
# Reemplaza "Maverick" por un modelo válido que veas en tu dashboard
response = self.sn_client.chat.completions.create(
model="Meta-Llama-3.1-8B-Instruct", # ✅ CAMBIA ESTO si usas otro modelo
messages=[{"role": "user", "content": prompt}],
temperature=0.7,
max_tokens=500
)
return response.choices[0].message.content.strip()
except Exception as e:
return f"❌ Error en SambaNova: {e}"
def generate_image(self, prompt: str) -> Optional[Image.Image]:
if not config.BRIA_API_TOKEN:
return None
try:
url = "https://api.bria.ai/v1/generate" # ✅ sin espacio
headers = {"Authorization": f"Bearer {config.BRIA_API_TOKEN}"}
json_data = {"prompt": prompt, "options": {"resolution": "512x512"}}
response = requests.post(url, headers=headers, json=json_data, timeout=30)
if response.status_code == 200:
img_b64 = response.json().get("image_base64")
if img_b64:
img_bytes = base64.b64decode(img_b64)
return Image.open(io.BytesIO(img_bytes))
except Exception as e:
print(f"⚠️ Error en Bria: {e}")
return None
tools = AI_Tools()
# --- Procesamiento (síncrono para Gradio) ---
def process_input(message: str, history: list) -> list:
msg_lower = message.lower()
# Generar imagen
if any(kw in msg_lower for kw in ["imagen", "foto", "genera imagen", "dibuja"]):
img = tools.generate_image(message)
if img:
return history + [(message, ("", img))]
return history + [(message, "❌ No se pudo generar la imagen. ¿Tienes BRIA_API_TOKEN?")]
# Generar texto con SambaNova
response = tools.generate_text(message)
return history + [(message, response)]
# --- Interfaz Gradio ---
with gr.Blocks(title="AI Assistant", theme=gr.themes.Soft()) as app:
gr.Markdown("# 🤖 AI Assistant (SambaNova + Bria)")
samba_status = "✅ SambaNova activo" if tools.sn_client else "❌ SambaNova inactivo"
bria_status = "✅ Bria activo" if config.BRIA_API_TOKEN else "❌ Bria inactivo"
gr.Markdown(f"**Estado**: {samba_status} | {bria_status}")
chatbot = gr.Chatbot(height=450)
msg = gr.Textbox(
label="Escribe tu mensaje",
placeholder="Ej: 'Explica la relatividad' o 'Genera una imagen de un dragón en Marte'",
lines=2
)
gr.Examples([
"¿Qué es el aprendizaje automático?",
"Genera una imagen de un bosque encantado al atardecer",
"Escribe un breve cuento sobre un robot solitario"
], inputs=msg)
def clear(): return []
gr.Button("Limpiar chat").click(clear, outputs=chatbot)
# Con queue=True, evita bloqueos
msg.submit(process_input, [msg, chatbot], chatbot, queue=True)
gr.Button("Enviar").click(process_input, [msg, chatbot], chatbot, queue=True)
# --- Ejecución ---
if __name__ == "__main__":
app.queue().launch(server_name="0.0.0.0", server_port=7860)