Spaces:
Running
Running
daemon: handle put/get file transfers
Browse files
daemon/__pycache__/client.cpython-311.pyc
CHANGED
|
Binary files a/daemon/__pycache__/client.cpython-311.pyc and b/daemon/__pycache__/client.cpython-311.pyc differ
|
|
|
daemon/client.py
CHANGED
|
@@ -21,13 +21,14 @@ import sys
|
|
| 21 |
import time
|
| 22 |
import signal
|
| 23 |
import socket
|
|
|
|
| 24 |
import getpass
|
| 25 |
import threading
|
| 26 |
import subprocess
|
| 27 |
import uuid
|
| 28 |
import queue as queuelib
|
| 29 |
|
| 30 |
-
from gradio_client import Client
|
| 31 |
|
| 32 |
|
| 33 |
def _primary_ip() -> str:
|
|
@@ -61,6 +62,7 @@ CLIENT_ID = os.environ.get("CLIENT_ID") or _default_client_id()
|
|
| 61 |
POLL_INTERVAL = float(os.environ.get("POLL_INTERVAL", "5"))
|
| 62 |
DEFAULT_TIMEOUT = int(os.environ.get("CMD_TIMEOUT", "120"))
|
| 63 |
MAX_OUTPUT_CHARS = 200_000
|
|
|
|
| 64 |
|
| 65 |
_log_lock = threading.Lock()
|
| 66 |
|
|
@@ -207,7 +209,65 @@ def _meta() -> str:
|
|
| 207 |
return f"{os.uname().sysname} {os.uname().release} pid={os.getpid()}"
|
| 208 |
|
| 209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
def handle(client: Client, cmd: dict):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
cid = cmd["id"]
|
| 212 |
session = cmd.get("session") or "main"
|
| 213 |
command = cmd["command"]
|
|
|
|
| 21 |
import time
|
| 22 |
import signal
|
| 23 |
import socket
|
| 24 |
+
import shutil
|
| 25 |
import getpass
|
| 26 |
import threading
|
| 27 |
import subprocess
|
| 28 |
import uuid
|
| 29 |
import queue as queuelib
|
| 30 |
|
| 31 |
+
from gradio_client import Client, handle_file
|
| 32 |
|
| 33 |
|
| 34 |
def _primary_ip() -> str:
|
|
|
|
| 62 |
POLL_INTERVAL = float(os.environ.get("POLL_INTERVAL", "5"))
|
| 63 |
DEFAULT_TIMEOUT = int(os.environ.get("CMD_TIMEOUT", "120"))
|
| 64 |
MAX_OUTPUT_CHARS = 200_000
|
| 65 |
+
MAX_FILE_BYTES = 100 * 1024 * 1024 # 100 MB cap on transfers
|
| 66 |
|
| 67 |
_log_lock = threading.Lock()
|
| 68 |
|
|
|
|
| 209 |
return f"{os.uname().sysname} {os.uname().release} pid={os.getpid()}"
|
| 210 |
|
| 211 |
|
| 212 |
+
def _expand(p: str) -> str:
|
| 213 |
+
return os.path.expanduser(os.path.expandvars(p or ""))
|
| 214 |
+
|
| 215 |
+
|
| 216 |
+
def _result_path(ret) -> str:
|
| 217 |
+
"""gradio_client returns a File output as a path str, or a FileData dict."""
|
| 218 |
+
if isinstance(ret, dict):
|
| 219 |
+
return ret.get("path") or ret.get("name") or ""
|
| 220 |
+
if isinstance(ret, (list, tuple)) and ret:
|
| 221 |
+
return _result_path(ret[0])
|
| 222 |
+
return ret
|
| 223 |
+
|
| 224 |
+
|
| 225 |
+
def do_put(client: Client, cmd: dict):
|
| 226 |
+
"""Server -> client: download the payload from the relay and write it to dest."""
|
| 227 |
+
cid = cmd["id"]
|
| 228 |
+
dest = _expand(cmd.get("dest") or cmd.get("filename") or "downloaded.bin")
|
| 229 |
+
log(f"[file] put → {dest}")
|
| 230 |
+
try:
|
| 231 |
+
ret = client.predict(cmd["file_id"], SECRET, api_name="/fetch_file")
|
| 232 |
+
src = _result_path(ret)
|
| 233 |
+
if os.path.isdir(dest) or dest.endswith(os.sep):
|
| 234 |
+
dest = os.path.join(dest, cmd.get("filename") or os.path.basename(src))
|
| 235 |
+
parent = os.path.dirname(os.path.abspath(dest))
|
| 236 |
+
os.makedirs(parent, exist_ok=True)
|
| 237 |
+
shutil.copy(src, dest)
|
| 238 |
+
size = os.path.getsize(dest)
|
| 239 |
+
out, code = (f"wrote {size} bytes to {dest}", 0)
|
| 240 |
+
except Exception as e:
|
| 241 |
+
out, code = (f"[relay: put failed: {e!r}]", 1)
|
| 242 |
+
client.predict(cid, CLIENT_ID, SECRET, code, out, "file", api_name="/result")
|
| 243 |
+
log(f"[file] put → exit {code}")
|
| 244 |
+
|
| 245 |
+
|
| 246 |
+
def do_get(client: Client, cmd: dict):
|
| 247 |
+
"""Client -> server: read a local file and upload it to the relay."""
|
| 248 |
+
cid = cmd["id"]
|
| 249 |
+
remote = _expand(cmd.get("remote_path"))
|
| 250 |
+
log(f"[file] get {remote}")
|
| 251 |
+
try:
|
| 252 |
+
if not os.path.isfile(remote):
|
| 253 |
+
raise FileNotFoundError(f"not a file: {remote}")
|
| 254 |
+
size = os.path.getsize(remote)
|
| 255 |
+
if size > MAX_FILE_BYTES:
|
| 256 |
+
raise ValueError(f"{size} bytes exceeds the {MAX_FILE_BYTES}-byte limit")
|
| 257 |
+
client.predict(cid, CLIENT_ID, SECRET, handle_file(remote), "",
|
| 258 |
+
api_name="/upload_result")
|
| 259 |
+
log(f"[file] get → sent {size} bytes")
|
| 260 |
+
except Exception as e:
|
| 261 |
+
client.predict(cid, CLIENT_ID, SECRET, None, f"{e}", api_name="/upload_result")
|
| 262 |
+
log(f"[file] get → error: {e}")
|
| 263 |
+
|
| 264 |
+
|
| 265 |
def handle(client: Client, cmd: dict):
|
| 266 |
+
typ = cmd.get("type", "exec")
|
| 267 |
+
if typ == "put":
|
| 268 |
+
return do_put(client, cmd)
|
| 269 |
+
if typ == "get":
|
| 270 |
+
return do_get(client, cmd)
|
| 271 |
cid = cmd["id"]
|
| 272 |
session = cmd.get("session") or "main"
|
| 273 |
command = cmd["command"]
|