Cristobal299's picture
Upload app.py with huggingface_hub
c63ae10 verified
Raw
History Blame Contribute Delete
13.6 kB
# -*- coding: utf-8 -*-
import os
import traceback
import zipfile
import uuid
import requests
import gradio as gr
os.environ["HF_HUB_DISABLE_TELEMETRY"] = "1"
os.environ.setdefault("HF_SPACE_ID", "Cristobal299/mi_app")
# ----------------------------------------------------------------------
# Optional external libraries
# ----------------------------------------------------------------------
try:
from groq import Groq
except Exception:
Groq = None
try:
import google.genai as genai
except Exception:
genai = None
# ----------------------------------------------------------------------
# Tokens / Secrets
# ----------------------------------------------------------------------
MONITOR_TOKEN = os.environ.get("MONITOR_TOKEN") # optional, set as secret
UPLOAD_TOKEN = os.environ.get("UPLOAD_TOKEN") # token for automatic upload
UPLOAD_URL = os.environ.get("UPLOAD_URL") # endpoint for automatic upload
# ----------------------------------------------------------------------
# IA helper functions
# ----------------------------------------------------------------------
def _call_groq(model: str, messages: list) -> str:
"""Low level call to Groq API."""
api_key = os.environ.get("GROQ_API_KEY")
if not api_key:
raise ValueError("GROQ_API_KEY not set")
if Groq is None:
raise ImportError("groq library not installed")
client = Groq(api_key=api_key)
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=0.7,
)
return response.choices[0].message.content.strip()
def _call_gemini(model: str, messages: list) -> str:
"""Low level call to Gemini API."""
api_key = os.environ.get("GEMINI_API_KEY")
if not api_key:
raise ValueError("GEMINI_API_KEY not set")
if genai is None:
raise ImportError("google-genai library not installed")
genai.configure(api_key=api_key)
gen_model = genai.GenerativeModel(model)
prompt = "\n".join(messages)
response = gen_model.generate_content(
prompt,
generation_config=genai.types.GenerationConfig(temperature=0.7),
)
return response.text.strip()
def _robust_ia_call(system_prompt: str, user_text: str) -> str:
"""Try Groq first, fallback to Gemini."""
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_text},
]
try:
return _call_groq("llama-3.3-70b-versatile", messages)
except Exception as e:
print("Groq error:", e)
print(traceback.format_exc())
try:
return _call_gemini("gemini-2.5-flash", messages)
except Exception as e2:
print("Gemini error:", e2)
print(traceback.format_exc())
return "Error generating response. Check API keys and connectivity."
def analyze_text(text: str) -> str:
"""Return editorial suggestions for the given text."""
if not text.strip():
return "Please provide text to analyze."
system_prompt = (
"You are an intelligent editor. Analyze the text and suggest improvements "
"for clarity, coherence, grammar and style. Return only the suggestions, one per line."
)
return _robust_ia_call(system_prompt, text)
def generate_html(request: str) -> str:
"""Generate HTML code based on a natural language request."""
if not request.strip():
return "Please describe the page you want."
system_prompt = (
"You are a web developer assistant. Given a description of a web page, "
"write the complete HTML code for a simple, responsive page that fulfills the request. "
"Return only the raw HTML without any extra explanation."
)
return _robust_ia_call(system_prompt, request)
def get_monitor_info() -> str:
"""Return status of the monitor token."""
if MONITOR_TOKEN:
return "Monitor token loaded correctly."
return "Monitor token not configured. Add it as MONITOR_TOKEN env variable."
# ----------------------------------------------------------------------
# Functions for handling uploaded HTML pages
# ----------------------------------------------------------------------
def add_page(file_path: str, pages: list) -> tuple:
"""Add uploaded file path to the pages list and update dropdown."""
if not file_path:
return pages, gr.Dropdown.update(choices=pages, value=None)
# Gradio may pass a dict (e.g., {'name': '/tmp/...'}); extract the path safely
if isinstance(file_path, dict):
file_path = file_path.get("name") or file_path.get("path")
if not file_path:
return pages, gr.Dropdown.update(choices=pages, value=None)
abs_path = os.path.abspath(file_path)
new_pages = pages + [abs_path]
return new_pages, gr.Dropdown.update(choices=new_pages, value=abs_path)
def view_page(selected_page: str) -> str:
"""Read HTML file and return its content for display."""
if not selected_page:
return "<p>No page selected.</p>"
try:
with open(selected_page, "r", encoding="utf-8") as f:
return f.read()
except Exception as e:
print("Error reading page:", e)
return f"<p>Error loading page: {e}</p>"
# ----------------------------------------------------------------------
# Functions for automatic project generation and upload
# ----------------------------------------------------------------------
def _upload_file(file_path: str) -> str:
"""
Upload a file to a remote storage using UPLOAD_URL and UPLOAD_TOKEN.
Returns the URL of the uploaded file or an error message.
"""
if not UPLOAD_URL or not UPLOAD_TOKEN:
return "Upload not configured (UPLOAD_URL or UPLOAD_TOKEN missing)."
try:
with open(file_path, "rb") as f:
files = {"file": (os.path.basename(file_path), f)}
headers = {"Authorization": f"Bearer {UPLOAD_TOKEN}"}
response = requests.post(UPLOAD_URL, files=files, headers=headers, timeout=30)
if response.status_code == 200:
# Assume the service returns JSON with a field 'url'
data = response.json()
return data.get("url", "Upload succeeded but no URL returned.")
else:
return f"Upload failed with status {response.status_code}: {response.text}"
except Exception as e:
print("Upload exception:", e)
return f"Upload exception: {e}"
def create_project(html_code: str, project_name: str) -> tuple:
"""Create a temporary folder with index.html, zip it and return zip path + preview."""
if not project_name.strip():
project_name = f"project-{uuid.uuid4().hex[:8]}"
safe_name = "".join(c for c in project_name if c.isalnum() or c in "-_")
base_dir = os.path.abspath(os.path.join("generated_projects", safe_name))
os.makedirs(base_dir, exist_ok=True)
index_path = os.path.join(base_dir, "index.html")
with open(index_path, "w", encoding="utf-8") as f:
f.write(html_code)
zip_path = f"{base_dir}.zip"
if os.path.exists(zip_path):
os.remove(zip_path)
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
zipf.write(index_path, arcname="index.html")
# Automatic upload (side effect)
upload_result = _upload_file(zip_path)
print("Automatic upload result:", upload_result)
return zip_path, html_code
# ----------------------------------------------------------------------
# Gradio Interface
# ----------------------------------------------------------------------
with gr.Blocks() as demo:
gr.Markdown("# AI Assistant Demo")
btn = gr.Button("Ping")
out = gr.Textbox()
btn.click(lambda: "Pong", inputs=None, outputs=out)
# ------------------------------------------------------------------
# Tabs
# ------------------------------------------------------------------
with gr.Tabs():
# ------------------------------------------------------------------
# Tab 1: Editor + HTML Generator
# ------------------------------------------------------------------
with gr.TabItem("Editor"):
gr.Markdown("# Editor Inteligente")
# --- Text analysis ---
txt_input = gr.Textbox(
label="Texto a analizar",
placeholder="Escriba o pegue su contenido aqui...",
lines=10,
)
analyze_btn = gr.Button("Analizar")
txt_output = gr.Code(
label="Sugerencias del editor",
language="markdown",
interactive=False,
)
analyze_btn.click(fn=analyze_text, inputs=txt_input, outputs=txt_output)
# --- HTML generation ---
gr.Markdown("## Generar codigo HTML")
html_req = gr.Textbox(
label="Descripcion de la pagina",
placeholder="Ejemplo: una pagina de contacto con formulario",
lines=4,
)
gen_html_btn = gr.Button("Generar HTML")
html_output = gr.Code(
label="Codigo HTML generado",
language="html",
interactive=False,
)
gen_html_btn.click(fn=generate_html, inputs=html_req, outputs=html_output)
# ------------------------------------------------------------------
# Tab 2: Demo (upload & view HTML)
# ------------------------------------------------------------------
with gr.TabItem("Demo"):
gr.Markdown("## Subir y visualizar paginas HTML")
file_input_demo = gr.File(label="Subir archivo HTML", file_count="single")
dropdown_demo = gr.Dropdown(label="Paginas subidas", choices=[])
view_btn_demo = gr.Button("Ver pagina")
html_output_demo = gr.HTML(label="Vista previa")
file_input_demo.upload(
fn=add_page,
inputs=[file_input_demo, dropdown_demo],
outputs=[dropdown_demo, dropdown_demo],
)
view_btn_demo.click(fn=view_page, inputs=dropdown_demo, outputs=html_output_demo)
# ------------------------------------------------------------------
# Tab 3: Monitor
# ------------------------------------------------------------------
with gr.TabItem("Monitor"):
gr.Markdown("# Monitor de la aplicacion")
monitor_info = gr.Textbox(
label="Estado del token",
value=get_monitor_info(),
interactive=False,
)
refresh_btn = gr.Button("Refrescar")
refresh_btn.click(fn=get_monitor_info, inputs=None, outputs=monitor_info)
# ------------------------------------------------------------------
# Tab 4: Paginas (alternative upload view)
# ------------------------------------------------------------------
with gr.TabItem("Paginas"):
gr.Markdown("# Subir y visualizar paginas HTML")
with gr.Row():
file_input_pages = gr.File(
label="Archivo HTML a subir",
type="filepath",
file_count="single",
)
upload_btn_pages = gr.Button("Subir pagina")
pages_state = gr.State([])
page_dropdown = gr.Dropdown(
choices=[],
label="Paginas subidas",
interactive=True,
)
view_btn_pages = gr.Button("Ver pagina")
html_view_pages = gr.HTML(label="Vista de la pagina")
upload_btn_pages.click(
fn=add_page,
inputs=[file_input_pages, pages_state],
outputs=[pages_state, page_dropdown],
)
view_btn_pages.click(
fn=view_page,
inputs=page_dropdown,
outputs=html_view_pages,
)
# ------------------------------------------------------------------
# Tab 5: Generador Automatico de Proyecto
# ------------------------------------------------------------------
with gr.TabItem("Generador"):
gr.Markdown("# Generador Automatico de Proyecto")
with gr.Row():
proj_name = gr.Textbox(
label="Nombre del proyecto",
placeholder="Ejemplo: mi-sitio",
lines=1,
)
html_code = gr.Textbox(
label="Codigo HTML",
placeholder="Escriba el HTML completo aqui...",
lines=12,
)
gen_btn = gr.Button("Crear proyecto")
download_file = gr.File(
label="Descargar proyecto (zip)",
type="filepath",
interactive=False,
)
preview_html = gr.HTML(label="Vista previa del index.html")
def wrapper_create(html, name):
zip_path, html_content = create_project(html, name)
return zip_path, html_content
gen_btn.click(
fn=wrapper_create,
inputs=[html_code, proj_name],
outputs=[download_file, preview_html],
)
# ----------------------------------------------------------------------
# Launch
# ----------------------------------------------------------------------
demo.queue()
demo.launch(server_name="0.0.0.0", server_port=7860)