"""
Pixal3D HF Space Proxy
======================
This is a lightweight proxy app for HF Space that redirects users to a
locally deployed Gradio share link.
Setup:
1. Deploy this as your HF Space app.py
2. Set HF Space Secret: REMOTE_URL = your local share link (e.g. https://xxxxx.gradio.live)
3. Users visiting the HF Space will be seamlessly redirected to your local instance.
To update the share link:
- Go to HF Space Settings -> Variables and secrets -> Update REMOTE_URL
"""
import os
import gradio as gr
REMOTE_URL = os.environ.get("REMOTE_URL", "")
GPU_NAME = os.environ.get("GPU_NAME", "")
# Multi-instance support: REMOTE_URL as #0, REMOTE_URL_1, REMOTE_URL_2, REMOTE_URL_3
REMOTE_URLS = []
if REMOTE_URL:
name0 = os.environ.get("REMOTE_NAME", "Instance 0")
REMOTE_URLS.append({"url": REMOTE_URL, "name": name0})
for i in range(1, 4):
url = os.environ.get(f"REMOTE_URL_{i}", "")
name = os.environ.get(f"REMOTE_NAME_{i}", f"Instance {i}")
if url:
REMOTE_URLS.append({"url": url, "name": name})
PROXY_HTML = """
Pixal3D | AI Image-to-3D
{content}
"""
def build_page():
# If multi-instance URLs are configured, show cards
if REMOTE_URLS:
status_color = "#10b981"
status_anim = "pulse 2s infinite"
status_text = f"{len(REMOTE_URLS)} instance(s) available"
cards_html = ""
for i, inst in enumerate(REMOTE_URLS):
cards_html += f"""
🖥️ {inst['name']}
⚡ Shared GPU — requests are queued
Checking...
Open Instance {i}
{inst['url']}
"""
# Build JS array of instance URLs for direct polling (Gradio share links support CORS natively)
urls_js = ", ".join(['"' + inst["url"].rstrip("/") + '"' for inst in REMOTE_URLS])
content = f"""
🚀 Choose a Pixal3D Instance
⚠️ Due to a temporary HuggingFace error, this Space is currently unavailable. Please use one of the instances below.
💡 Choose the instance with the shortest queue!
{cards_html}
"""
poll_script = f"""
const INSTANCE_URLS = [{urls_js}];
async function pollQueues() {{
for (let i = 0; i < INSTANCE_URLS.length; i++) {{
try {{
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
const resp = await fetch(INSTANCE_URLS[i] + '/queue?session_id=', {{
signal: controller.signal
}});
clearTimeout(timeout);
if (resp.ok) {{
const data = await resp.json();
const total = data.total_waiting + (data.gpu_busy ? 1 : 0);
const el = document.getElementById('queue-text-' + i);
const status = document.getElementById('queue-status-' + i);
if (total === 0) {{
el.textContent = 'Idle — no queue';
status.className = 'queue-status idle';
}} else {{
el.textContent = total + ' in queue';
status.className = 'queue-status busy';
}}
}} else {{
const el = document.getElementById('queue-text-' + i);
const status = document.getElementById('queue-status-' + i);
if (el) {{
el.textContent = 'Offline';
status.className = 'queue-status offline';
}}
}}
}} catch (e) {{
const el = document.getElementById('queue-text-' + i);
const status = document.getElementById('queue-status-' + i);
if (el) {{
el.textContent = 'Offline';
status.className = 'queue-status offline';
}}
}}
}}
}}
pollQueues();
setInterval(pollQueues, 5000);
"""
else:
status_color = "#ef4444"
status_anim = "pulse 1.5s infinite"
status_text = "Remote instance not configured"
poll_script = ""
content = """
⚡ Remote GPU Instance Not Connected
This Space acts as a proxy to a locally-deployed Pixal3D instance running on a dedicated GPU.
To connect, set the REMOTE_URL secret in this Space's settings to your Gradio share link.
Example: https://abcdef123456.gradio.live
"""
html = PROXY_HTML.format(
status_color=status_color,
status_anim=status_anim,
status_text=status_text,
gpu_name=GPU_NAME,
content=content,
)
return html, poll_script
# Use a simple Gradio Blocks app with HTML component
page_html, page_script = build_page()
with gr.Blocks(
title="Pixal3D | AI Image-to-3D",
css="footer {display:none !important;} .gradio-container {padding:0 !important; max-width:100% !important; height:100vh !important; overflow:hidden !important;} #proxy-frame {height:100%; max-height:100vh; padding:0; overflow:hidden;}",
theme=gr.themes.Base(),
) as demo:
gr.HTML(page_html, elem_id="proxy-frame", js_on_load=page_script if page_script else None)
if __name__ == "__main__":
demo.launch(share=True)