chankhavu commited on
Commit
b95b31c
·
verified ·
1 Parent(s): adf0ffd

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"]