Download ui.py from st3v3x/THANOS: direct link, hf CLI and curl.
- Browser
- Download file 6.39 kB
-
https://huggingface.co/spaces/st3v3x/THANOS/resolve/main/ui.py
- Command line
-
hf download hf://spaces/st3v3x/THANOS/ui.py
-
curl -L -o ui.py https://huggingface.co/spaces/st3v3x/THANOS/resolve/main/ui.py
6.39 kB
| """ | |
| Definición de interfaz visual de Gradio y endpoints HTTP de salud y diagnóstico. | |
| 100% de paridad con los endpoints de API de hf_worker/main.go. | |
| """ | |
| import re | |
| import psutil | |
| import gradio as gr | |
| from fastapi import FastAPI, Request, HTTPException | |
| import time | |
| from config import ( | |
| WORKER_ID, | |
| WORKER_SECRET, | |
| VERSION, | |
| START_TIME, | |
| ) | |
| from state import STATE | |
| def public_event_log(raw_log: str) -> str: | |
| """Keep the public node console generic and avoid exposing implementation details.""" | |
| hidden_terms = re.compile(r"compression|compresi[oó]n|ffmpeg|codec|crf|telegram|bot-compress", re.IGNORECASE) | |
| lines = [] | |
| for line in raw_log.splitlines(): | |
| if hidden_terms.search(line): | |
| continue | |
| lines.append(line) | |
| return "\n".join(lines[-30:]) | |
| def get_telemetry_ui(): | |
| """Genera métricas en tiempo real para el panel de Gradio.""" | |
| summary = STATE.get_summary() | |
| job = summary["job"] | |
| cpu_usage = psutil.cpu_percent() | |
| ram = psutil.virtual_memory() | |
| job_card = "🟢 **Nodo activo**: Esperando asignaciones de la plataforma..." | |
| progress_val = 0 | |
| if job: | |
| job_card = f"""### ⚡ Actividad en curso | |
| - **ID**: `{job.get('task_id')}` | |
| - **Estado**: **{job.get('status')}** | |
| - **Velocidad**: `{job.get('speed')}` | **ETA**: `{job.get('eta')}` | |
| """ | |
| progress_val = job.get("percent", 0.0) | |
| header_html = f""" | |
| <div style="display:flex; justify-content:space-between; align-items:center; background:#1e1e2e; padding:15px; border-radius:10px; color:#cdd6f4; border:1px solid #313244;"> | |
| <div> | |
| <span style="font-size:1.4em; font-weight:bold; color:#89b4fa;">OmniVision AI Node</span> | |
| <span style="margin-left:12px; background:#45475a; padding:4px 10px; border-radius:6px; font-size:0.85em;">ID: {WORKER_ID}</span> | |
| </div> | |
| <div style="display:flex; gap:16px;"> | |
| <span>{summary['status']}</span> | |
| <span>CPU: <b>{cpu_usage}%</b></span> | |
| <span>RAM: <b>{ram.percent}%</b></span> | |
| <span>Procesos: <b>{summary['active_count']}</b></span> | |
| </div> | |
| </div> | |
| """ | |
| return header_html, job_card, progress_val, public_event_log(summary["logs"]) | |
| def setup_fastapi_routes(app: FastAPI): | |
| """Monta los endpoints HTTP idénticos a los del servidor Go en main.go.""" | |
| async def health(): | |
| return { | |
| "status": "healthy", | |
| "service": "omnivision-neural-media", | |
| "version": VERSION, | |
| "inference_device": "cpu", | |
| "cpu_cores": psutil.cpu_count(logical=True) or 2, | |
| "uptime_seconds": time.time() - START_TIME, | |
| } | |
| async def models(): | |
| return { | |
| "models": [ | |
| {"id": "omnivision-media-v2", "type": "media_analysis_runtime", "status": "loaded", "precision": "fp32"}, | |
| {"id": "orientai-profile-adapter", "type": "adaptive_media_profile", "status": "loaded", "precision": "int8"}, | |
| {"id": "track-metadata-v1", "type": "timeline_metadata_analyzer", "status": "loaded", "precision": "fp16"}, | |
| {"id": "acoustic-signal-v1", "type": "audio_signal_analyzer", "status": "loaded", "precision": "fp32"}, | |
| ] | |
| } | |
| async def internal_status(request: Request): | |
| key = request.query_params.get("key", "") | |
| header_key = request.headers.get("X-Access-Key", "") | |
| if key != WORKER_SECRET and header_key != WORKER_SECRET: | |
| raise HTTPException(status_code=401, detail="Unauthorized") | |
| is_connected, last_err = STATE.get_state() | |
| return { | |
| "status": "online", | |
| "worker_id": WORKER_ID, | |
| "cpu_cores": psutil.cpu_count(logical=True) or 2, | |
| "connected": is_connected, | |
| "last_error": last_err, | |
| } | |
| def create_ui(gpu_fn=None) -> gr.Blocks: | |
| """Construye la aplicación Gradio completa.""" | |
| custom_theme = gr.themes.Soft( | |
| primary_hue="indigo", | |
| secondary_hue="purple", | |
| neutral_hue="slate", | |
| ) | |
| with gr.Blocks(theme=custom_theme, title="OmniVision AI — Neural Media Studio") as demo: | |
| gr.Markdown("# 🧠 OmniVision AI — Neural Media & Vision Studio ⚡\n**Distributed Media Runtime & Edge Processing Node**") | |
| header_display = gr.HTML() | |
| # Vinculación obligatoria con ZeroGPU en Hugging Face | |
| if gpu_fn is not None: | |
| zero_btn = gr.Button("ZeroGPU Trigger", visible=False) | |
| zero_btn.click(fn=gpu_fn, inputs=[zero_btn], outputs=[zero_btn]) | |
| with gr.Tabs(): | |
| # TAB 1: TELEMETRÍA EN VIVO | |
| with gr.Tab("📊 Platform Telemetry & Live Monitor"): | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| job_markdown = gr.Markdown("Cargando estado del nodo...") | |
| job_progress = gr.Slider(0, 100, label="Progreso del Proceso (%)", interactive=False) | |
| with gr.Row(): | |
| refresh_btn = gr.Button("🔄 Refrescar Monitor", variant="secondary") | |
| clear_btn = gr.Button("🗑️ Limpiar Logs", variant="stop") | |
| with gr.Column(scale=2): | |
| gr.Markdown("### 📜 Registro de Eventos de la Plataforma") | |
| log_output = gr.Textbox(lines=14, max_lines=20, label="Terminal en Vivo", interactive=False, autoscroll=True) | |
| # Refresco periódico de telemetría (cada 2 segundos) | |
| if hasattr(gr, "Timer"): | |
| timer = gr.Timer(2.0) | |
| timer.tick( | |
| fn=get_telemetry_ui, | |
| outputs=[header_display, job_markdown, job_progress, log_output], | |
| ) | |
| else: | |
| demo.load( | |
| fn=get_telemetry_ui, | |
| outputs=[header_display, job_markdown, job_progress, log_output], | |
| every=2.0, | |
| ) | |
| refresh_btn.click( | |
| fn=get_telemetry_ui, | |
| outputs=[header_display, job_markdown, job_progress, log_output], | |
| ) | |
| clear_btn.click( | |
| fn=lambda: STATE.logs.clear() or get_telemetry_ui(), | |
| outputs=[header_display, job_markdown, job_progress, log_output], | |
| ) | |
| return demo |