Bl4ckSpaces commited on
Commit
9f3a0c6
Β·
verified Β·
1 Parent(s): 1a0607f

Update app_relay2.py

Browse files
Files changed (1) hide show
  1. app_relay2.py +41 -28
app_relay2.py CHANGED
@@ -1,13 +1,12 @@
1
  # ═══════════════════════════════════════════════════════════════════════════════
2
- # πŸ§… SODA-GEN ANONYMOUS RELAY V1.2 β€” HF SPACE CPU (BACKEND ONLY)
3
  #
4
  # MODE: Anonymous + Tor IP Rotation
5
  # QUOTA: 120s per Tor exit node (auto-rotate on exhaustion)
6
  # TARGET: https://r3gm-wan2-2-fp8da-aoti-preview-2.hf.space
7
  # PLATFORM: Hugging Face Spaces (Docker / CPU Basic)
8
  #
9
- # INI BACKEND ONLY β€” Relay 1 (HF Space) tetap full stack dengan UI
10
- # V1.2: Adapted for HF Space (no ngrok, Docker-native Tor)
11
  # ═══════════════════════════════════════════════════════════════════════════════
12
 
13
  import json
@@ -36,10 +35,15 @@ import threading
36
  # ═══════════════════════════════════════════════════════════════════════════════
37
 
38
  TARGET_URL = "https://r3gm-wan2-2-fp8da-aoti-preview-2.hf.space"
39
- TOR_PROXY = "socks5h://127.0.0.1:9050"
40
- PREDICT_TIMEOUT = 300 # 5 minutes for full generation
41
- MAX_TOR_RETRIES = 5 # Max circuit rotations per request
42
- GPU_RETRY_DELAY = 15 # Wait before GPU cold retry
 
 
 
 
 
43
 
44
  WAN_NEG = (
45
  "色调艳丽, 过曝, 静态, η»†θŠ‚ζ¨‘η³ŠδΈζΈ…, ε­—εΉ•, 风格, δ½œε“, η”»δ½œ, 画青, 静歒, "
@@ -54,7 +58,6 @@ UPLOAD_DIR.mkdir(exist_ok=True)
54
 
55
  TASKS: Dict[str, Dict[str, Any]] = {}
56
 
57
- # Track last known Tor IP for caching
58
  _last_tor_ip = {"ip": "unknown", "time": 0}
59
 
60
  # ═══════════════════════════════════════════════════════════════════════════════
@@ -62,7 +65,6 @@ _last_tor_ip = {"ip": "unknown", "time": 0}
62
  # ═══════════════════════════════════════════════════════════════════════════════
63
 
64
  def ensure_tor_running():
65
- """Ensure Tor daemon is active"""
66
  try:
67
  result = subprocess.run(
68
  ["service", "tor", "status"],
@@ -78,7 +80,6 @@ def ensure_tor_running():
78
 
79
 
80
  def get_tor_ip() -> str:
81
- """Get current Tor exit node IP (cached for 10s)"""
82
  now = time.time()
83
  if now - _last_tor_ip["time"] < 10 and _last_tor_ip["ip"] != "unknown":
84
  return _last_tor_ip["ip"]
@@ -95,18 +96,16 @@ def get_tor_ip() -> str:
95
 
96
 
97
  def rotate_tor_circuit() -> str:
98
- """Request new Tor circuit β†’ new exit node β†’ new IP"""
99
  try:
100
  with Controller.from_port(port=9051) as controller:
101
  controller.authenticate()
102
  controller.signal(Signal.NEWNYM)
103
  time.sleep(5)
104
- _last_tor_ip["ip"] = "unknown" # Force refresh
105
  new_ip = get_tor_ip()
106
  print(f"πŸ”„ Tor rotated β†’ {new_ip}")
107
  return new_ip
108
  except Exception as e:
109
- # Fallback: restart Tor entirely
110
  print(f"⚠️ Tor rotation method 1 failed: {e}, trying restart...")
111
  try:
112
  subprocess.run(["service", "tor", "restart"], capture_output=True, timeout=15)
@@ -130,10 +129,10 @@ def rotate_tor_circuit() -> str:
130
 
131
  class GradioClientWithProxy:
132
  """
133
- Wrapper untuk gradio_client yang route traffic via Tor proxy.
134
 
135
- gradio_client internal menggunakan httpx, yang respect env vars.
136
- Kita set HTTP_PROXY/HTTPS_PROXY sebelum Client() dibuat.
137
  """
138
 
139
  def __init__(self, base_url: str, proxy: str = None):
@@ -144,20 +143,21 @@ class GradioClientWithProxy:
144
  self._setup_client()
145
 
146
  def _setup_client(self):
147
- """Setup gradio_client dengan proxy"""
148
  if self.proxy:
149
- # Save old values
150
- for key in ["HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy"]:
151
  self._old_env[key] = os.environ.get(key)
152
- # Set proxy
153
  os.environ["HTTP_PROXY"] = self.proxy
154
  os.environ["HTTPS_PROXY"] = self.proxy
155
  os.environ["http_proxy"] = self.proxy
156
  os.environ["https_proxy"] = self.proxy
 
 
157
 
158
  self.client = Client(
159
  self.base_url,
160
- headers={"User-Agent": "SodaGen-Anonymous/1.2"}
161
  )
162
 
163
  def submit(self, **kwargs):
@@ -167,7 +167,6 @@ class GradioClientWithProxy:
167
  return self.client.predict(**kwargs)
168
 
169
  def _restore_env(self):
170
- """Restore original env vars"""
171
  for key, val in self._old_env.items():
172
  if val is None:
173
  os.environ.pop(key, None)
@@ -289,9 +288,21 @@ def run_generation_task(
289
  task["log"] += f"🎬 [ANONYMOUS MODE] Prompt: {prompt[:80]}...\n"
290
  task["log"] += f"⏱️ Duration: {duration}s | Steps: {steps} | FPS Mult: {frame_mult}\n"
291
  task["log"] += f"⏱️ Timeout: {PREDICT_TIMEOUT}s | Max Tor retries: {MAX_TOR_RETRIES}\n"
 
292
 
293
  ensure_tor_running()
294
 
 
 
 
 
 
 
 
 
 
 
 
295
  img1_resized = resize_image_for_video(img1_path) if img1_path else None
296
  img2_resized = resize_image_for_video(img2_path) if img2_path else None
297
 
@@ -495,10 +506,10 @@ def stream_video(video_path: str, request: Request):
495
 
496
 
497
  # ═══════════════════════════════════════════════════════════════════════════════
498
- # 🌐 FASTAPI APPLICATION (BACKEND ONLY β€” NO UI)
499
  # ═══════════════════════════════════════════════════════════════════════════════
500
 
501
- app = FastAPI(title="SODA-GEN Anonymous Relay V1.2")
502
 
503
  app.add_middleware(
504
  CORSMiddleware,
@@ -516,9 +527,10 @@ async def health_check():
516
  return JSONResponse({
517
  "status": "ok",
518
  "mode": "anonymous",
519
- "version": "1.2",
520
  "tor_ip": ip,
521
  "tor_active": tor_ok,
 
522
  "ffmpeg": shutil.which("ffmpeg") is not None,
523
  })
524
 
@@ -619,13 +631,13 @@ async def api_stats():
619
  "total_tokens": "infinity (Tor rotation)",
620
  "active_tokens": "∞",
621
  "cooldown_tokens": 0,
622
- "version": "1.2",
623
  })
624
 
625
 
626
  @app.get("/api/tor-ip")
627
  async def api_tor_ip():
628
- _last_tor_ip["ip"] = "unknown" # Force fresh check
629
  return JSONResponse({"ip": get_tor_ip()})
630
 
631
 
@@ -640,10 +652,11 @@ async def on_startup():
640
  ensure_tor_running()
641
  ip = get_tor_ip()
642
  print("=" * 60)
643
- print("πŸ§… SODA-GEN Anonymous Relay V1.2 β€” HF Space CPU")
644
  print(f" 🌐 Tor IP: {ip}")
645
  print(f" πŸ“‘ Target: {TARGET_URL}")
646
  print(f" πŸ§… Proxy: {TOR_PROXY}")
 
647
  print(f" ⏱️ Timeout: {PREDICT_TIMEOUT}s")
648
  print(f" 🎬 ffmpeg: {'βœ…' if shutil.which('ffmpeg') else '❌'}")
649
  print(f" 🎬 ffprobe: {'βœ…' if shutil.which('ffprobe') else '❌'}")
 
1
  # ═══════════════════════════════════════════════════════════════════════════════
2
+ # πŸ§… SODA-GEN ANONYMOUS RELAY V1.3 β€” HF SPACE CPU (BACKEND ONLY)
3
  #
4
  # MODE: Anonymous + Tor IP Rotation
5
  # QUOTA: 120s per Tor exit node (auto-rotate on exhaustion)
6
  # TARGET: https://r3gm-wan2-2-fp8da-aoti-preview-2.hf.space
7
  # PLATFORM: Hugging Face Spaces (Docker / CPU Basic)
8
  #
9
+ # V1.3 FIX: socks5h:// β†’ socks5:// (httpx compatibility)
 
10
  # ═══════════════════════════════════════════════════════════════════════════════
11
 
12
  import json
 
35
  # ═══════════════════════════════════════════════════════════════════════════════
36
 
37
  TARGET_URL = "https://r3gm-wan2-2-fp8da-aoti-preview-2.hf.space"
38
+
39
+ # ═══════════════════════════════════════════════════════════
40
+ # πŸ”§ FIX V1.3: socks5h β†’ socks5 (httpx only supports socks5://)
41
+ # ═══════════════════════════════════════════════════════════
42
+ TOR_PROXY = "socks5://127.0.0.1:9050"
43
+
44
+ PREDICT_TIMEOUT = 300
45
+ MAX_TOR_RETRIES = 5
46
+ GPU_RETRY_DELAY = 15
47
 
48
  WAN_NEG = (
49
  "色调艳丽, 过曝, 静态, η»†θŠ‚ζ¨‘η³ŠδΈζΈ…, ε­—εΉ•, 风格, δ½œε“, η”»δ½œ, 画青, 静歒, "
 
58
 
59
  TASKS: Dict[str, Dict[str, Any]] = {}
60
 
 
61
  _last_tor_ip = {"ip": "unknown", "time": 0}
62
 
63
  # ═══════════════════════════════════════════════════════════════════════════════
 
65
  # ═══════════════════════════════════════════════════════════════════════════════
66
 
67
  def ensure_tor_running():
 
68
  try:
69
  result = subprocess.run(
70
  ["service", "tor", "status"],
 
80
 
81
 
82
  def get_tor_ip() -> str:
 
83
  now = time.time()
84
  if now - _last_tor_ip["time"] < 10 and _last_tor_ip["ip"] != "unknown":
85
  return _last_tor_ip["ip"]
 
96
 
97
 
98
  def rotate_tor_circuit() -> str:
 
99
  try:
100
  with Controller.from_port(port=9051) as controller:
101
  controller.authenticate()
102
  controller.signal(Signal.NEWNYM)
103
  time.sleep(5)
104
+ _last_tor_ip["ip"] = "unknown"
105
  new_ip = get_tor_ip()
106
  print(f"πŸ”„ Tor rotated β†’ {new_ip}")
107
  return new_ip
108
  except Exception as e:
 
109
  print(f"⚠️ Tor rotation method 1 failed: {e}, trying restart...")
110
  try:
111
  subprocess.run(["service", "tor", "restart"], capture_output=True, timeout=15)
 
129
 
130
  class GradioClientWithProxy:
131
  """
132
+ Wrapper gradio_client yang route traffic via Tor SOCKS5 proxy.
133
 
134
+ V1.3: Menggunakan socks5:// (bukan socks5h://) agar compatible dengan httpx.
135
+ httpx internal gradio_client hanya recognize socks5:// scheme.
136
  """
137
 
138
  def __init__(self, base_url: str, proxy: str = None):
 
143
  self._setup_client()
144
 
145
  def _setup_client(self):
 
146
  if self.proxy:
147
+ for key in ["HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy",
148
+ "ALL_PROXY", "all_proxy"]:
149
  self._old_env[key] = os.environ.get(key)
150
+
151
  os.environ["HTTP_PROXY"] = self.proxy
152
  os.environ["HTTPS_PROXY"] = self.proxy
153
  os.environ["http_proxy"] = self.proxy
154
  os.environ["https_proxy"] = self.proxy
155
+ os.environ["ALL_PROXY"] = self.proxy
156
+ os.environ["all_proxy"] = self.proxy
157
 
158
  self.client = Client(
159
  self.base_url,
160
+ headers={"User-Agent": "SodaGen-Anonymous/1.3"}
161
  )
162
 
163
  def submit(self, **kwargs):
 
167
  return self.client.predict(**kwargs)
168
 
169
  def _restore_env(self):
 
170
  for key, val in self._old_env.items():
171
  if val is None:
172
  os.environ.pop(key, None)
 
288
  task["log"] += f"🎬 [ANONYMOUS MODE] Prompt: {prompt[:80]}...\n"
289
  task["log"] += f"⏱️ Duration: {duration}s | Steps: {steps} | FPS Mult: {frame_mult}\n"
290
  task["log"] += f"⏱️ Timeout: {PREDICT_TIMEOUT}s | Max Tor retries: {MAX_TOR_RETRIES}\n"
291
+ task["log"] += f"πŸ”§ Proxy scheme: socks5:// (V1.3 fix)\n"
292
 
293
  ensure_tor_running()
294
 
295
+ # Verify Tor is actually working
296
+ test_ip = get_tor_ip()
297
+ task["log"] += f"πŸ§… Initial Tor IP: {test_ip}\n"
298
+ if test_ip == "unknown":
299
+ task["log"] += f"⚠️ WARNING: Could not determine Tor IP. Tor may not be routing.\n"
300
+ task["log"] += f" Attempting to restart Tor...\n"
301
+ subprocess.run(["service", "tor", "restart"], capture_output=True, timeout=15)
302
+ time.sleep(5)
303
+ test_ip = get_tor_ip()
304
+ task["log"] += f" After restart: {test_ip}\n"
305
+
306
  img1_resized = resize_image_for_video(img1_path) if img1_path else None
307
  img2_resized = resize_image_for_video(img2_path) if img2_path else None
308
 
 
506
 
507
 
508
  # ═══════════════════════════════════════════════════════════════════════════════
509
+ # 🌐 FASTAPI APPLICATION
510
  # ═══════════════════════════════════════════════════════════════════════════════
511
 
512
+ app = FastAPI(title="SODA-GEN Anonymous Relay V1.3")
513
 
514
  app.add_middleware(
515
  CORSMiddleware,
 
527
  return JSONResponse({
528
  "status": "ok",
529
  "mode": "anonymous",
530
+ "version": "1.3",
531
  "tor_ip": ip,
532
  "tor_active": tor_ok,
533
+ "proxy_scheme": "socks5://",
534
  "ffmpeg": shutil.which("ffmpeg") is not None,
535
  })
536
 
 
631
  "total_tokens": "infinity (Tor rotation)",
632
  "active_tokens": "∞",
633
  "cooldown_tokens": 0,
634
+ "version": "1.3",
635
  })
636
 
637
 
638
  @app.get("/api/tor-ip")
639
  async def api_tor_ip():
640
+ _last_tor_ip["ip"] = "unknown"
641
  return JSONResponse({"ip": get_tor_ip()})
642
 
643
 
 
652
  ensure_tor_running()
653
  ip = get_tor_ip()
654
  print("=" * 60)
655
+ print("πŸ§… SODA-GEN Anonymous Relay V1.3 β€” HF Space CPU")
656
  print(f" 🌐 Tor IP: {ip}")
657
  print(f" πŸ“‘ Target: {TARGET_URL}")
658
  print(f" πŸ§… Proxy: {TOR_PROXY}")
659
+ print(f" πŸ”§ Scheme: socks5:// (V1.3 fix)")
660
  print(f" ⏱️ Timeout: {PREDICT_TIMEOUT}s")
661
  print(f" 🎬 ffmpeg: {'βœ…' if shutil.which('ffmpeg') else '❌'}")
662
  print(f" 🎬 ffprobe: {'βœ…' if shutil.which('ffprobe') else '❌'}")