Modal-style sandbox API on top of Hugging Face Jobs.
from hf_sandbox import Sandbox
sb = Sandbox.create(image="python:3.12")
proc = sb.exec("python", "-c", "print(1+1)") # → CompletedProcess(stdout='2\n', returncode=0, ...)
sb.write_file("/tmp/foo.txt", "hello")
print(sb.read_file("/tmp/foo.txt")) # → 'hello'
sb.terminate()Sandbox.create() launches an HF Job that:
pip installs a tiny FastAPI RPC server (FastAPI + uvicorn)- starts the server on
localhost:8000 - opens a free Cloudflare Tunnel so the master process can reach it
The client polls the job logs for the tunnel URL, then talks to the sandbox over plain HTTPS.
exec, write_file, read_file are simple authenticated POSTs.
terminate() cancels the job.
pip install hf-sandboxRequires hf auth login (the same token is forwarded to the sandbox so it can access HF Hub).
- Image must have Python +
pip(used to install the RPC server and downloadcloudflared). - Cloudflare's free
trycloudflare.comURLs are best-effort — fine for benchmarks, not production.
The sandbox runs untrusted code by design. A few things to be aware of:
- HF token forwarding is opt-in. By default, your HF token is not exposed to the sandbox. Pass
forward_hf_token=TruetoSandbox.create()if your workload needs it. With it enabled, anything running inside the sandbox can read the token from/proc/self/environand use it to act as you on the Hub. - Cloudflare sees all tunnel traffic. Requests, responses, and the auth token transit Cloudflare's infrastructure (via
trycloudflare.com). They state they don't log it, but it's a trust relationship. Don't run sensitive workloads through it. - Auth token is a 256-bit random URL-safe string per sandbox, sent as
Beareron every authenticated endpoint. The tunnel URL alone gets you nothing.
hf-sandbox reports anonymous usage data to help us understand how the library is used. Two events are sent per sandbox:
hf-sandbox/create— flavor, timeout, whetherforward_hf_tokenwas set, and a random per-sandbox session idhf-sandbox/terminate— same session id, duration in seconds, and termination reason
We never send: the image name, commands, file paths, file contents, the tunnel URL, the auth token, your HF token, your username, or anything from inside the sandbox.
Disable by setting HF_HUB_DISABLE_TELEMETRY=1 (or DO_NOT_TRACK=1).