stanley-00 commited on
Commit
fb79641
·
verified ·
1 Parent(s): 6194b3e

Restore real app (Blocks + mount + uvicorn 7860); space now public

Browse files
Files changed (1) hide show
  1. app.py +41 -122
app.py CHANGED
@@ -1,138 +1,57 @@
1
- import spaces # MUST be first
 
 
 
 
 
 
 
2
 
3
- import os
4
  import gradio as gr
5
 
 
 
6
 
 
 
 
 
 
7
  @spaces.GPU(duration=10)
8
  def _gpu_probe():
9
  return None
10
 
11
 
12
- with gr.Blocks(title="DIAG") as demo:
13
- gr.Markdown("DIAG MODE")
14
- demo.load(fn=_gpu_probe)
15
-
16
-
17
- def _fmt_ino():
18
- ino = {}
19
- for pid in os.listdir("/proc"):
20
- if not pid.isdigit():
21
- continue
22
- try:
23
- for fd in os.listdir(f"/proc/{pid}/fd"):
24
- try:
25
- t = os.readlink(f"/proc/{pid}/fd/{fd}")
26
- except OSError:
27
- continue
28
- if t.startswith("socket:["):
29
- ino[t[8:-1]] = pid
30
- except OSError:
31
- continue
32
- return ino
33
-
34
-
35
- def _procinfo(pid):
36
- try:
37
- with open(f"/proc/{pid}/comm") as f:
38
- comm = f.read().strip()
39
- except OSError:
40
- return None
41
- try:
42
- with open(f"/proc/{pid}/cmdline") as f:
43
- cmd = f.read().replace("\x00", " ").strip()[:200]
44
- except OSError:
45
- cmd = ""
46
- try:
47
- with open(f"/proc/{pid}/stat") as f:
48
- ppid = f.read().split()[3]
49
- except OSError:
50
- ppid = "?"
51
- return f"{pid}:{comm}(pp={ppid})|{cmd}"
52
-
53
-
54
- def _dump_env(pid):
55
- try:
56
- with open(f"/proc/{pid}/environ") as f:
57
- env = f.read().replace("\x00", "\n")
58
- except OSError:
59
- return
60
- picks = {}
61
- for line in env.splitlines():
62
- k, _, v = line.partition("=")
63
- if k in (
64
- "GRADIO_SSR_MODE", "PORT", "GRADIO_SERVER_PORT", "GRADIO_SERVER_NAME",
65
- "SPACES_ZERO_GPU", "SPACES_ZERO_DEVICE_API_URL", "ZEROGPU_V2",
66
- "GRADIO_NODE_PATH", "GRADIO_OFFICIAL_EXAMPLE", "SSH_CONNECTION",
67
- ):
68
- picks[k] = v
69
- print(f"DIAGENV{pid} " + " ".join(f"{k}={v}" for k, v in picks.items()))
70
-
71
-
72
- def _dump_env_diff():
73
  try:
74
- e1 = open("/proc/1/environ").read().replace("\x00", "\n").splitlines()
75
- e2 = open("/proc/224/environ").read().replace("\x00", "\n").splitlines()
76
- d1, d2 = dict(l.split("=", 1) for l in e1 if "=" in l), dict(l.split("=", 1) for l in e2 if "=" in l)
77
- only1 = sorted(set(d1) - set(d2))
78
- only2 = sorted(set(d2) - set(d1))
79
- print("DIAGDIFF only1=" + ",".join(only1) if only1 else "DIAGDIFF only1=none")
80
- print("DIAGDIFF only2=" + ",".join(only2) if only2 else "DIAGDIFF only2=none")
81
- except OSError:
 
82
  pass
83
 
84
 
85
- def _listeners():
86
- ino = _fmt_ino()
87
- import socket as sk
88
- out = []
89
- for proto in ("/proc/net/tcp", "/proc/net/tcp6"):
90
- try:
91
- with open(proto) as f:
92
- next(f)
93
- for line in f:
94
- p = line.split()
95
- if len(p) < 10 or p[3] != "0A":
96
- continue
97
- ip_hex, port_hex = p[1].split(":")
98
- af = sk.AF_INET6 if proto.endswith("6") else sk.AF_INET
99
- ip = sk.inet_ntop(af, bytes.fromhex(ip_hex))
100
- port = int(port_hex, 16)
101
- out.append((ip, port, ino.get(p[9], "?")))
102
- except OSError:
103
- continue
104
- return out
105
-
106
-
107
- def _dump():
108
- print("DIAGENV " + " ".join(
109
- f"{k}={os.environ.get(k)}" for k in (
110
- "GRADIO_SSR_MODE", "PORT", "GRADIO_SERVER_PORT",
111
- "GRADIO_SERVER_NAME", "GRADIO_NODE_PATH", "SPACES_ZERO_GPU",
112
- "SPACES_ZERO_DEVICE_API_URL", "ZEROGPU_V2",
113
- "GRADIO_NUM_WORKERS", "NODE_PATH", "HOME",
114
- )
115
- ))
116
- print("DIAGPROC " + " | ".join(x for x in (
117
- _procinfo(p) for p in ("1", "2", "224", "239", "7860")
118
- ) if x))
119
- _dump_env("1")
120
- _dump_env("224")
121
- print("DIAGL " + " | ".join(f"{ip}:{port}={owner}" for ip, port, owner in _listeners()))
122
-
123
 
124
- demo.launch(server_name="0.0.0.0", prevent_thread_lock=True)
 
 
 
 
 
 
125
 
126
- _dump()
127
- _dump_env_diff()
128
 
129
- import time
130
- time.sleep(20)
131
- print("DIAGL2 " + " | ".join(
132
- f"{ip}:{port}={owner}" for ip, port, owner in _listeners()
133
- ))
134
- if os.path.exists("/proc/224"):
135
- print("DIAG224 alive after 20s")
136
- else:
137
- print("DIAG224 EXITED")
138
- time.sleep(3600)
 
1
+ """
2
+ HF Playground — code-driven model playground.
3
+ Enter any HuggingFace model ID in a code template and run.
4
+ """
5
+ import spaces # MUST be first — signals ZeroGPU infrastructure
6
+
7
+ import sys
8
+ import asyncio
9
 
 
10
  import gradio as gr
11
 
12
+ from api import build_fastapi_app
13
+ from ui import build_app, theme, CSS
14
 
15
+ # ZeroGPU startup probe. The runtime scans Gradio's *registered event handlers*
16
+ # for a @spaces.GPU-marked function and refuses to start if none is found, so this
17
+ # probe is wired to demo.load() below. The real work (run_custom_code) stays
18
+ # undecorated so it runs in-process — models are CPU-bound and the sandbox needs
19
+ # threads + queues that would break inside a forked ZeroGPU worker.
20
  @spaces.GPU(duration=10)
21
  def _gpu_probe():
22
  return None
23
 
24
 
25
+ # Python 3.10 asyncio cleanup fix: suppress "Invalid file descriptor: -1" on shutdown
26
+ if sys.version_info >= (3, 10) and sys.platform == 'linux':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  try:
28
+ _cls = asyncio.selector_events.BaseSelectorEventLoop
29
+ _orig = _cls._close_self_pipe
30
+ def _safe_close_self_pipe(self):
31
+ try:
32
+ _orig(self)
33
+ except ValueError:
34
+ pass
35
+ _cls._close_self_pipe = _safe_close_self_pipe
36
+ except Exception:
37
  pass
38
 
39
 
40
+ with gr.Blocks(title="HF Model Playground") as demo:
41
+ build_app()
42
+ demo.load(fn=_gpu_probe, trigger_mode="once")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
+ # ZeroGPU client registration happens on the first Blocks.launch() call
45
+ # (spaces.zero wraps gr.Blocks.launch to send the startup report to the device
46
+ # API). Launch once on a throwaway port to trigger that registration, then
47
+ # immediately close it. The real server starts below via uvicorn on 7860 and
48
+ # serves both the Gradio UI and the OpenAI-compatible /v1 routes.
49
+ demo.launch(prevent_thread_lock=True, server_name=None, server_port=8000, quiet=True)
50
+ demo.close()
51
 
52
+ fastapi_app = build_fastapi_app()
53
+ app = gr.mount_gradio_app(fastapi_app, demo, path="/", theme=theme, css=CSS)
54
 
55
+ if __name__ == "__main__":
56
+ import uvicorn
57
+ uvicorn.run(app, host="0.0.0.0", port=7860)