arcacolab commited on
Commit
3449543
Β·
verified Β·
1 Parent(s): 260f1a7

Upload launch_neo.py

Browse files
Files changed (1) hide show
  1. mypy/launch_neo.py +258 -0
mypy/launch_neo.py ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import atexit
2
+ import os
3
+ import platform
4
+ import re
5
+ import stat
6
+ import subprocess
7
+ import sys
8
+ import time
9
+ import threading
10
+ from pathlib import Path
11
+ from typing import List, Optional
12
+
13
+ import requests
14
+
15
+ VERSION = "0.2"
16
+ CURRENT_TUNNELS: List["Tunnel"] = []
17
+
18
+ machine = platform.machine()
19
+ if machine == "x86_64":
20
+ machine = "amd64"
21
+
22
+ BINARY_REMOTE_NAME = f"frpc_{platform.system().lower()}_{machine.lower()}"
23
+ EXTENSION = ".exe" if os.name == "nt" else ""
24
+ BINARY_URL = f"https://cdn-media.huggingface.co/frpc-gradio-{VERSION}/{BINARY_REMOTE_NAME}{EXTENSION}"
25
+
26
+ BINARY_FILENAME = f"{BINARY_REMOTE_NAME}_v{VERSION}"
27
+ BINARY_FOLDER = Path(__file__).parent.absolute()
28
+ BINARY_PATH = f"{BINARY_FOLDER / BINARY_FILENAME}"
29
+
30
+ TUNNEL_TIMEOUT_SECONDS = 30
31
+ TUNNEL_ERROR_MESSAGE = (
32
+ "Could not create share URL. "
33
+ "Please check the appended log from frpc for more information:"
34
+ )
35
+
36
+ GRADIO_API_SERVER = "https://api.gradio.app/v2/tunnel-request"
37
+ GRADIO_SHARE_SERVER_ADDRESS = None
38
+
39
+
40
+ class Tunnel:
41
+ def __init__(self, remote_host, remote_port, local_host, local_port, share_token):
42
+ self.proc = None
43
+ self.url = None
44
+ self.remote_host = remote_host
45
+ self.remote_port = remote_port
46
+ self.local_host = local_host
47
+ self.local_port = local_port
48
+ self.share_token = share_token
49
+
50
+ @staticmethod
51
+ def download_binary():
52
+ if not Path(BINARY_PATH).exists():
53
+ resp = requests.get(BINARY_URL)
54
+
55
+ if resp.status_code == 403:
56
+ raise OSError(
57
+ f"Cannot set up a share link as this platform is incompatible. Please "
58
+ f"create a GitHub issue with information about your platform: {platform.uname()}"
59
+ )
60
+
61
+ resp.raise_for_status()
62
+
63
+ with open(BINARY_PATH, "wb") as file:
64
+ file.write(resp.content)
65
+ st = os.stat(BINARY_PATH)
66
+ os.chmod(BINARY_PATH, st.st_mode | stat.S_IEXEC)
67
+
68
+ def start_tunnel(self) -> str:
69
+ self.download_binary()
70
+ self.url = self._start_tunnel(BINARY_PATH)
71
+ return self.url
72
+
73
+ def kill(self):
74
+ if self.proc is not None:
75
+ print(f"Killing tunnel {self.local_host}:{self.local_port} <> {self.url}")
76
+ self.proc.terminate()
77
+ self.proc = None
78
+
79
+ def _start_tunnel(self, binary: str) -> str:
80
+ CURRENT_TUNNELS.append(self)
81
+ command = [
82
+ binary,
83
+ "http",
84
+ "-n",
85
+ self.share_token,
86
+ "-l",
87
+ str(self.local_port),
88
+ "-i",
89
+ self.local_host,
90
+ "--uc",
91
+ "--sd",
92
+ "random",
93
+ "--ue",
94
+ "--server_addr",
95
+ f"{self.remote_host}:{self.remote_port}",
96
+ "--disable_log_color",
97
+ ]
98
+ self.proc = subprocess.Popen(
99
+ command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
100
+ )
101
+ atexit.register(self.kill)
102
+ return self._read_url_from_tunnel_stream()
103
+
104
+ def _read_url_from_tunnel_stream(self) -> str:
105
+ start_timestamp = time.time()
106
+ log = []
107
+ url = ""
108
+
109
+ def _raise_tunnel_error():
110
+ log_text = "\n".join(log)
111
+ raise ValueError(f"{TUNNEL_ERROR_MESSAGE}\n{log_text}")
112
+
113
+ while url == "":
114
+ if time.time() - start_timestamp >= TUNNEL_TIMEOUT_SECONDS:
115
+ _raise_tunnel_error()
116
+
117
+ assert self.proc is not None
118
+ if self.proc.stdout is None:
119
+ continue
120
+
121
+ line = self.proc.stdout.readline()
122
+ line = line.decode("utf-8")
123
+
124
+ if line == "":
125
+ continue
126
+
127
+ log.append(line.strip())
128
+
129
+ if "start proxy success" in line:
130
+ result = re.search("start proxy success: (.+)\n", line)
131
+ if result is None:
132
+ _raise_tunnel_error()
133
+ else:
134
+ url = result.group(1)
135
+ elif "login to server failed" in line:
136
+ _raise_tunnel_error()
137
+
138
+ return url
139
+
140
+
141
+ def setup_tunnel(
142
+ local_host: str,
143
+ local_port: int,
144
+ share_token: str,
145
+ share_server_address: Optional[str],
146
+ ) -> str:
147
+ share_server_address = (
148
+ GRADIO_SHARE_SERVER_ADDRESS
149
+ if share_server_address is None
150
+ else share_server_address
151
+ )
152
+ if share_server_address is None:
153
+ response = requests.get(GRADIO_API_SERVER, timeout=10)
154
+ if not (response and response.status_code == 200):
155
+ raise RuntimeError("Could not get share link from Gradio API Server.")
156
+ payload = response.json()[0]
157
+ remote_host, remote_port = payload["host"], int(payload["port"])
158
+ else:
159
+ remote_host, remote_port = share_server_address.split(":")
160
+ remote_port = int(remote_port)
161
+
162
+ tunnel = Tunnel(remote_host, remote_port, local_host, local_port, share_token)
163
+ address = tunnel.start_tunnel()
164
+ return address
165
+
166
+
167
+ # Cloudflared 터널 μ „μ—­ λ³€μˆ˜
168
+ cloudflared_url = None
169
+ cloudflared_proc = None
170
+
171
+ def start_cloudflared_tunnel(port):
172
+ global cloudflared_url, cloudflared_proc
173
+ try:
174
+ cloudflared_proc = subprocess.Popen(
175
+ ["cloudflared", "tunnel", "--url", f"http://127.0.0.1:{port}"],
176
+ stdout=subprocess.PIPE,
177
+ stderr=subprocess.PIPE
178
+ )
179
+ for line in cloudflared_proc.stderr:
180
+ l = line.decode()
181
+ if "trycloudflare.com " in l:
182
+ cloudflared_url = l[l.find("http"):].strip()
183
+ break
184
+ except Exception as e:
185
+ print(f"⚠️ [Cloudflare] 터널링 쀑 였λ₯˜ λ°œμƒ: {e}", file=sys.stderr)
186
+
187
+
188
+ if __name__ == "__main__":
189
+ import secrets
190
+
191
+ print("\n" + "=" * 60)
192
+ print("πŸš€ WebUI 싀행됨")
193
+ print("=" * 60 + "\n")
194
+
195
+ # 1. Gradio 터널 μ˜ˆμ™Έ 처리 (μ‹€νŒ¨ν•΄λ„ λ¬΄μ‹œ)
196
+ gradio_url = None
197
+ try:
198
+ gradio_url = setup_tunnel(
199
+ "127.0.0.1",
200
+ 7860,
201
+ secrets.token_urlsafe(32),
202
+ None,
203
+ )
204
+ except Exception as e:
205
+ print(f"⚠️ [Gradio] 터널링 쀑 였λ₯˜ λ°œμƒ: Gradio 곡유 μ„œλ²„ 연결에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.", file=sys.stderr)
206
+
207
+ # 2. Cloudflared 터널을 λ°±κ·ΈλΌμš΄λ“œ μŠ€λ ˆλ“œλ‘œ μ‹œμž‘
208
+ cloudflared_thread = threading.Thread(
209
+ target=start_cloudflared_tunnel,
210
+ args=(7860,),
211
+ daemon=True
212
+ )
213
+ cloudflared_thread.start()
214
+
215
+ # Cloudflared URL λŒ€κΈ°
216
+ for _ in range(20):
217
+ if cloudflared_url:
218
+ break
219
+ time.sleep(0.5)
220
+
221
+ if not cloudflared_url:
222
+ print("⚠️ [Cloudflare] 터널링 쀑 였λ₯˜ λ°œμƒ: Cloudflare URL을 κ°€μ Έμ˜€μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.", file=sys.stderr)
223
+
224
+ # URL 정보 좜λ ₯
225
+ print("\n🌐 접속 URL:")
226
+ print(f" β€’ Gradio: {gradio_url if gradio_url else '❌ 생성 μ‹€νŒ¨'}")
227
+ print(f" β€’ Cloudflare: {cloudflared_url if cloudflared_url else '❌ 생성 μ‹€νŒ¨'}")
228
+
229
+ print()
230
+ print("πŸ’‘ 팁:")
231
+ print(" β€’ WebUI μŠ€νƒ€νŠΈμ—…κΉŒμ§€ 쑰금의 μ‹œκ°„μ΄ μ†Œμš”λ©λ‹ˆλŒœ.")
232
+ print(" β€’ 생성 μ„±κ³΅ν•œ URL을 ν΄λ¦­ν•˜μ—¬ 터널링 μ£Όμ†Œμ— μ ‘μ†ν•˜μ„Έμš”.")
233
+ print(" β€’ 이 셀을 쀑단(β– )ν•˜λ©΄ λͺ¨λ“  터널이 μ’…λ£Œλ©λ‹ˆλ‹€.")
234
+ print("\n" + "-" * 60)
235
+ print("πŸ“œ Forge neo μ‹€ν–‰ 둜그:")
236
+ print("-" * 60 + "\n")
237
+
238
+ # 3. μ‹€ν–‰
239
+ comfyui_command = [
240
+ "/content/venv/NEO/bin/python3.13",
241
+ "/content/sd-webui-forge-neo/launch.py",
242
+ #"--listen", "127.0.0.1",
243
+ #"--port", "7860"
244
+ ] + sys.argv[1:]
245
+
246
+ comfyui_proc = subprocess.Popen(comfyui_command)
247
+
248
+ try:
249
+ comfyui_proc.wait()
250
+ except KeyboardInterrupt:
251
+ print("\nπŸ›‘ 터널링을 μ’…λ£Œν•©λ‹ˆλ‹€...")
252
+
253
+ if cloudflared_proc:
254
+ cloudflared_proc.terminate()
255
+ if cloudflared_url:
256
+ print(f"Killing cloudflare tunnel 127.0.0.1:7860 <> {cloudflared_url}")
257
+
258
+ comfyui_proc.terminate()