Thunder Sandbox for Python
Create short-lived GPU sandboxes, run commands over SSH, and move files with a small, typed Python API.
Thunder Sandbox uses the same account and credentials as the Thunder CLI. It handles sandbox lifecycle, SSH key creation, readiness polling, command execution, uploads, and downloads without adding any runtime Python dependencies.
Installation
Thunder Sandbox requires Python 3.10 or newer and the system ssh, scp, and
ssh-keygen executables.
pip install thunder-sandbox
Until a release is available on PyPI, install the current repository directly:
pip install git+https://github.com/Thunder-Compute/thunder-sandbox.git
Authenticate with the Thunder CLI before using the library:
tnr login
Alternatively, set TNR_API_TOKEN and, when using a non-default API endpoint,
TNR_API_URL.
Quick start
import thunder_sandbox as thunder
sandbox = thunder.Sandbox.create(
cpu=4,
memory=32,
storage=50,
gpu="A6000",
timeout=900,
)
try:
sandbox.wait_until_running()
process = sandbox.exec("nvidia-smi")
stdout = process.stdout.read()
exit_code = process.wait()
if exit_code != 0:
raise RuntimeError(process.stderr.read())
print(stdout)
finally:
sandbox.terminate()
Sandboxes receive an internal name from Thunder. Sandbox.create() generates
an Ed25519 key pair and stores it under
~/.thunder/sandbox_keys/<sandbox-name>. The public key is immutable for the
lifetime of the sandbox.
Run commands
Pass command arguments separately to avoid local shell interpretation:
process = sandbox.exec("python3", "-c", "print('hello from Thunder')")
print(process.stdout.read())
exit_code = process.wait()
Commands can set a working directory, environment variables, a timeout, or a pseudo-terminal:
process = sandbox.exec(
"python3",
"train.py",
workdir="/home/ubuntu/project",
env={"MODEL": "llama", "DEBUG": "1"},
timeout=600,
)
Transfer files
sandbox.upload("model.py", "/home/ubuntu/model.py")
sandbox.upload("dataset", "/home/ubuntu/dataset", recursive=True)
sandbox.download("/home/ubuntu/results.json", "results.json")
sandbox.download("/home/ubuntu/checkpoints", "checkpoints", recursive=True)
Network policies
Sandboxes have unrestricted outbound access by default. Restriction is always explicit:
# No outbound internet access.
closed = thunder.Sandbox.create(block_network=True)
# Only the specified CIDRs and domains are permitted.
restricted = thunder.Sandbox.create(
outbound_cidr_allowlist=["203.0.113.0/24"],
outbound_domain_allowlist=["pypi.org", "files.pythonhosted.org"],
)
CIDR and domain allowlists are independent. Supply both when restricted workloads need both direct IP and DNS-based access.
Environment and lifetime
sandbox = thunder.Sandbox.create(
env={"EXPERIMENT": "baseline"},
timeout=3600,
)
timeout is the sandbox lifetime in seconds. Set it to None to create a
sandbox without an enforced TTL.
Work with existing sandboxes
with thunder.Client.from_cli() as client:
for sandbox in client.list_sandboxes():
print(sandbox.id, sandbox.status.value)
sandbox = client.get_sandbox("sbx-0123456789abcdef")
sandbox.wait_until_running(timeout=300)
print(" ".join(sandbox.ssh_command))
The private SSH key must still exist locally to execute commands or transfer files against an existing sandbox.
Async API
AsyncSandbox exposes the same lifecycle and remote-operation primitives for
async applications:
import asyncio
import thunder_sandbox as thunder
async def main() -> None:
sandbox = await thunder.AsyncSandbox.create(gpu="A6000")
try:
await sandbox.wait_until_running()
process = await sandbox.exec("nvidia-smi")
exit_code = await process.wait()
if exit_code != 0:
raise RuntimeError(process.stderr.read())
print(process.stdout.read())
finally:
await sandbox.terminate()
asyncio.run(main())
Configuration
Configuration is resolved from the following sources:
- Explicit
ClientConfigvalues. TNR_API_TOKENandTNR_API_URLenvironment variables.- Thunder CLI state in
~/.thunder/cli_config.json. - The default Thunder API endpoint.
Set TNR_HOME to use a different directory for CLI state and sandbox SSH keys.
License
Thunder Sandbox is available under the Apache License 2.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file thunder_sandbox-0.1.0.tar.gz.
File metadata
- Download URL: thunder_sandbox-0.1.0.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54c514386feb6a041b3d6fc8bff35ba352ff60681896d9243fa80b81c47ad7a9
|
|
| MD5 |
4bd1db3a800060db4981b547019214c8
|
|
| BLAKE2b-256 |
325a875dbfa3a844a1b5282411395919d77f61949730d45a3475000c2b1d9b6f
|
File details
Details for the file thunder_sandbox-0.1.0-py3-none-any.whl.
File metadata
- Download URL: thunder_sandbox-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69a9eb8e339d9864b05207c4c201ff60e85795b4a57e5cc1cf721d4c61920604
|
|
| MD5 |
e85b7848967c63973631399a1fb00b41
|
|
| BLAKE2b-256 |
870ff980721f61666e7b7c551b55538376d808c62b53eba7983aa69df74ca36f
|