Spaces:
Paused
Paused
Update app_relay2.py
Browse files- app_relay2.py +41 -28
app_relay2.py
CHANGED
|
@@ -1,13 +1,12 @@
|
|
| 1 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 2 |
-
# π§
SODA-GEN ANONYMOUS RELAY V1.
|
| 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 |
-
#
|
| 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 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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"
|
| 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
|
| 134 |
|
| 135 |
-
|
| 136 |
-
|
| 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 |
-
|
| 150 |
-
|
| 151 |
self._old_env[key] = os.environ.get(key)
|
| 152 |
-
|
| 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.
|
| 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
|
| 499 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 500 |
|
| 501 |
-
app = FastAPI(title="SODA-GEN Anonymous Relay V1.
|
| 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.
|
| 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.
|
| 623 |
})
|
| 624 |
|
| 625 |
|
| 626 |
@app.get("/api/tor-ip")
|
| 627 |
async def api_tor_ip():
|
| 628 |
-
_last_tor_ip["ip"] = "unknown"
|
| 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.
|
| 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 'β'}")
|