rydlrKE commited on
Commit
4ced200
·
1 Parent(s): f4ef391

Space: run native Kimodo UI directly on PORT to avoid iframe recursion

Browse files
Files changed (1) hide show
  1. app.py +15 -116
app.py CHANGED
@@ -1,137 +1,36 @@
1
- """Movimento Space: boot native Kimodo demo UI and embed via proxy."""
2
  from __future__ import annotations
3
 
4
- import importlib.util
5
  import os
6
- import threading
7
  import traceback
 
8
 
9
- import gradio as gr
10
-
11
- try:
12
- import spaces # type: ignore
13
- except Exception:
14
- class _SpacesFallback:
15
- @staticmethod
16
- def GPU(*args, **kwargs):
17
- def _decorator(fn):
18
- return fn
19
-
20
- return _decorator
21
-
22
- spaces = _SpacesFallback()
23
-
24
-
25
- NATIVE_PORT = int(os.environ.get("KIMODO_NATIVE_PORT", "8080"))
26
  os.environ.setdefault("SERVER_NAME", "0.0.0.0")
27
- os.environ.setdefault("SERVER_PORT", str(NATIVE_PORT))
28
  os.environ.setdefault("HF_MODE", "1")
29
  # Avoid local LLM2Vec fallback on Spaces (requires gated Llama weights).
30
  os.environ.setdefault("TEXT_ENCODER_MODE", "api")
31
  # Prefer CPU on ZeroGPU to avoid low-level CUDA init crashes during model load.
32
  os.environ.setdefault("KIMODO_DEVICE", "cpu")
33
 
34
- _state: dict[str, object] = {
35
- "ok": False,
36
- "error": None,
37
- "trace": None,
38
- "demo": None,
39
- }
40
-
41
-
42
- def _boot_native_demo() -> None:
43
  try:
44
- if importlib.util.find_spec("viser") is None:
45
- raise RuntimeError("Missing dependency: viser")
46
-
47
  import kimodo
48
  from kimodo.demo.app import Demo
49
 
50
  print(f"[movimento][boot] kimodo_module={getattr(kimodo, '__file__', 'unknown')}")
51
- print(f"[movimento][boot] demo_module={getattr(importlib.util.find_spec('kimodo.demo.app'), 'origin', 'unknown')}")
52
-
53
- _state["demo"] = Demo()
54
- _state["ok"] = True
55
- _state["error"] = None
56
- _state["trace"] = None
57
- except Exception as exc: # noqa: BLE001
58
- _state["ok"] = False
59
- _state["error"] = str(exc)
60
- _state["trace"] = traceback.format_exc(limit=8)
61
-
62
-
63
- threading.Thread(target=_boot_native_demo, daemon=True).start()
64
-
65
-
66
- # Keep a GPU-decorated function so HF startup checks pass.
67
- @spaces.GPU(duration=60)
68
- def _gpu_healthcheck() -> str:
69
- return "ok"
70
-
71
-
72
- def _viewer_html() -> str:
73
- # Always target the native Viser app on this Space. This avoids serving
74
- # an external fallback UI that can diverge from the deployed code/assets.
75
- src = f"/proxy/{NATIVE_PORT}/"
76
- return (
77
- "<div style='border:1px solid #d9e7ef;border-radius:12px;overflow:hidden;'>"
78
- "<div id='kimodo-proxy-status' style='padding:8px 12px;font-size:12px;color:#37566b;"
79
- "background:#f4f9fc;border-bottom:1px solid #d9e7ef;'>"
80
- "Waiting for native UI to become ready..."
81
- "</div>"
82
- f"<iframe id='kimodo-proxy-iframe' src='{src}' title='Kimodo UI' style='width:100%;border:0' "
83
- "height='920' loading='lazy'></iframe>"
84
- "<script>"
85
- "(function(){"
86
- f"const base='/proxy/{NATIVE_PORT}/';"
87
- "const frame=document.getElementById('kimodo-proxy-iframe');"
88
- "const status=document.getElementById('kimodo-proxy-status');"
89
- "let attached=false;"
90
- "async function tryAttach(){"
91
- "if(attached){return;}"
92
- "try{"
93
- "const res=await fetch(base,{method:'GET',cache:'no-store'});"
94
- "if(res.ok){"
95
- "attached=true;"
96
- "status.textContent='Native UI ready';"
97
- "frame.src=base+'?t='+Date.now();"
98
- "setTimeout(function(){status.style.display='none';}, 1500);"
99
- "return;"
100
- "}"
101
- "status.textContent='Starting native UI...';"
102
- "}catch(e){"
103
- "status.textContent='Starting native UI...';"
104
- "}"
105
- "}"
106
- "tryAttach();"
107
- "const timer=setInterval(tryAttach,3000);"
108
- "setTimeout(function(){clearInterval(timer);},120000);"
109
- "})();"
110
- "</script>"
111
- "</div>"
112
- )
113
-
114
-
115
- def _status_markdown() -> str:
116
- if bool(_state.get("ok")):
117
- return f"Native demo running on /proxy/{NATIVE_PORT}/."
118
- err = _state.get("error")
119
- if err:
120
- return f"Native demo failed to start. Reason: {err}"
121
- return f"Starting native demo on /proxy/{NATIVE_PORT}/..."
122
-
123
-
124
- def _refresh() -> tuple[str, str]:
125
- return _status_markdown(), _viewer_html()
126
-
127
 
128
- with gr.Blocks(title="Movimento") as demo:
129
- gr.Markdown("# Movimento")
130
- status_md = gr.Markdown(_status_markdown())
131
- viewer = gr.HTML(_viewer_html())
132
- refresh_btn = gr.Button("Refresh UI Status")
133
- refresh_btn.click(fn=_refresh, inputs=[], outputs=[status_md, viewer])
 
134
 
135
 
136
  if __name__ == "__main__":
137
- demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", "7860")))
 
1
+ """Movimento Space entrypoint: run native Kimodo demo directly."""
2
  from __future__ import annotations
3
 
 
4
  import os
 
5
  import traceback
6
+ import time
7
 
8
+ PORT = int(os.environ.get("PORT", "7860"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  os.environ.setdefault("SERVER_NAME", "0.0.0.0")
10
+ os.environ["SERVER_PORT"] = str(PORT)
11
  os.environ.setdefault("HF_MODE", "1")
12
  # Avoid local LLM2Vec fallback on Spaces (requires gated Llama weights).
13
  os.environ.setdefault("TEXT_ENCODER_MODE", "api")
14
  # Prefer CPU on ZeroGPU to avoid low-level CUDA init crashes during model load.
15
  os.environ.setdefault("KIMODO_DEVICE", "cpu")
16
 
17
+ def main() -> None:
 
 
 
 
 
 
 
 
18
  try:
 
 
 
19
  import kimodo
20
  from kimodo.demo.app import Demo
21
 
22
  print(f"[movimento][boot] kimodo_module={getattr(kimodo, '__file__', 'unknown')}")
23
+ print(f"[movimento][boot] mode=native_direct port={PORT}")
24
+ Demo()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
+ # Keep the process alive while Viser serves on SERVER_PORT.
27
+ while True:
28
+ time.sleep(3600)
29
+ except Exception: # noqa: BLE001
30
+ print("[movimento][boot][fatal] native demo failed to start")
31
+ print(traceback.format_exc(limit=12))
32
+ raise
33
 
34
 
35
  if __name__ == "__main__":
36
+ main()