Skip to main content

A Python SDK for interacting with the Sandbox Orchestrator.

Project description

Sandbox SDK

A Python SDK for interacting with the Sandbox Orchestrator. Supports both gRPC and HTTP transports with an identical public interface, so you can swap protocols without changing application logic.

Installation

pip install flash-sandbox

The package pulls in grpcio, protobuf, and requests automatically.

Quick Start

HTTP transport (recommended for simplicity)

from flash_sandbox import HTTPClient

client = HTTPClient(host="localhost", port=8080)

# Start a Docker sandbox
sandbox_id = client.start_sandbox(
    type="docker",
    image="alpine:latest",
    command=["tail", "-f", "/dev/null"],
    memory_mb=128,
    cpu_cores=0.5,
)
print(f"Sandbox ID: {sandbox_id}")

# Execute a command
result = client.exec_command(sandbox_id, ["echo", "Hello from HTTP!"])
print(f"Output: {result.stdout.strip()}")
print(f"Exit code: {result.exit_code}")

# Check status
status = client.get_status(sandbox_id)
print(f"Status: {status}")

# Get resource metrics
metrics = client.get_metrics(sandbox_id)
print(f"Memory: {metrics.memory_usage_bytes} / {metrics.memory_limit_bytes}")
print(f"CPU: {metrics.cpu_percent}%")

# Execute arbitrary Python code
py_out = client.run_python(sandbox_id, "print('Hello Python in Sandbox')")
print(f"Python Output: {py_out.strip()}")

# Get Platform Information
plat_info = client.get_platform_info(sandbox_id)
print(f"Platform Info: {plat_info}")

# Snapshot and resume
snap = client.snapshot_sandbox(sandbox_id)
print(f"Snapshot: {snap['snapshot_path']}")
client.resume_sandbox(sandbox_id)

# Stop
client.stop_sandbox(sandbox_id)
client.close()

gRPC transport

from flash_sandbox import SandboxClient

client = SandboxClient(host="localhost", port=50051)

# Start a Docker sandbox
docker_id = client.start_sandbox(
    type="docker",
    image="alpine:latest",
    command=["tail", "-f", "/dev/null"],
    memory_mb=128,
    cpu_cores=0.5,
)
print(f"Docker Sandbox ID: {docker_id}")

# Start a Firecracker sandbox
fc_id = client.start_sandbox(
    type="firecracker",
    image="alpine:latest",
    command=["tail", "-f", "/dev/null"],
    memory_mb=512,
    cpu_cores=1.0,
)
print(f"Firecracker Sandbox ID: {fc_id}")

# Start a gVisor sandbox
gvisor_id = client.start_sandbox(
    type="gvisor",
    image="alpine:latest",
    command=["tail", "-f", "/dev/null"],
    memory_mb=256,
    cpu_cores=1.0,
)
print(f"gVisor Sandbox ID: {gvisor_id}")

# Check status
status = client.get_status(fc_id)
print(f"Firecracker Status: {status}")

# Snapshot and Resume
snap_res = client.snapshot_sandbox(fc_id)
print(f"Snapshot Data: {snap_res}")
client.resume_sandbox(fc_id)

# Execute commands
exec_res = client.exec_command(gvisor_id, ["echo", "Hello from gVisor!"])
print(f"gVisor Output: {exec_res.stdout.strip()}")
print(f"gVisor Exit Code: {exec_res.exit_code}")

# Stop sandboxes
client.stop_sandbox(docker_id)
client.stop_sandbox(fc_id)
client.stop_sandbox(gvisor_id)
client.close()

API Reference

Both HTTPClient and SandboxClient expose the same set of methods:

Method Description
start_sandbox(type, image, command, memory_mb, cpu_cores, ...) Start a new sandbox and return its ID.
stop_sandbox(sandbox_id) Stop and remove a running sandbox.
exec_command(sandbox_id, command) Execute a command in a sandbox. Returns an object with stdout, stderr, and exit_code.
get_status(sandbox_id) Return the status string ("running", "stopped", etc.).
get_metrics(sandbox_id) Return point-in-time resource-usage metrics (memory, CPU, network, block I/O).
snapshot_sandbox(sandbox_id) Create a snapshot. Returns {"snapshot_path": ..., "mem_file_path": ...}.
resume_sandbox(sandbox_id) Resume a paused / snapshotted sandbox.
run_python(sandbox_id, code) Execute arbitrary Python code inside the sandbox. Returns the stdout output.
get_platform_info(sandbox_id) Get platform information from the sandbox. Returns a JSON string of platform data.
close() Release the underlying connection / session.

Constructor options

HTTPClient

HTTPClient(
    host="localhost",       # Orchestrator hostname
    port=8080,              # HTTP port (default 8080)
    address=None,           # Full URL, overrides host/port (e.g. "http://proxy:9090/v1/service/sandbox")
    timeout=30.0,           # Request timeout in seconds (None = no timeout)
    session=None,           # Optional requests.Session for custom TLS / auth / retries
)

SandboxClient (gRPC)

SandboxClient(
    host="localhost",       # Orchestrator hostname
    port=50051,             # gRPC port (default 50051)
    address=None,           # Full address for proxy routing (e.g. "localhost:8092/v1/service/sandbox")
)

HTTPClient-only extras

The HTTP transport includes a few additional features:

  • Firecracker fields on start_sandbox: kernel_image, initrd_path, snapshot_path, mem_file_path.
  • Custom timeouts per-client via the timeout parameter.
  • Session injection – pass your own requests.Session for connection pooling, mutual TLS, retry policies, or authentication headers.
  • Typed exceptions: SandboxHTTPError (with .status_code and .detail) and the more specific SandboxNotFoundError for 404 responses.

Response types (HTTP client)

Class Fields
ExecResult stdout: str, stderr: str, exit_code: int
MetricsResult memory_usage_bytes, memory_limit_bytes, memory_percent, cpu_percent, pids_current, net_rx_bytes, net_tx_bytes, block_read_bytes, block_write_bytes
SnapshotResult snapshot_path: str, mem_file_path: str

All response dataclasses are frozen (immutable).

Context manager

Both clients support the context-manager protocol:

from flash_sandbox import HTTPClient

with HTTPClient(host="localhost") as client:
    sid = client.start_sandbox(type="docker", image="alpine:latest")
    client.stop_sandbox(sid)
# Connection is automatically closed here.

Proxy / reverse-proxy support

Both clients support routing through a reverse proxy that uses path-based routing. Pass the full address including the path prefix:

# HTTP through a proxy
http_client = HTTPClient(address="http://proxy.example.com:8092/v1/service/sandbox")

# gRPC through a proxy
grpc_client = SandboxClient(address="proxy.example.com:8092/v1/service/sandbox")

Running tests

pip install -e ".[dev]"
pytest tests/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flash_sandbox-0.1.1.tar.gz (18.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flash_sandbox-0.1.1-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

Details for the file flash_sandbox-0.1.1.tar.gz.

File metadata

  • Download URL: flash_sandbox-0.1.1.tar.gz
  • Upload date:
  • Size: 18.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for flash_sandbox-0.1.1.tar.gz
Algorithm Hash digest
SHA256 afa03074f870c8b97f277a088e95c2126ff3ae4467c08b15024fe9484acce7db
MD5 c217dae12a739e36832653c05cd5d9a1
BLAKE2b-256 849560bfaa34bd968d131fec228c79ca8f76d19d50930d5c0938e67feb563bc5

See more details on using hashes here.

File details

Details for the file flash_sandbox-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: flash_sandbox-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for flash_sandbox-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ae35370c3b619950e38d8642ebac35baef7cb3fc3ca100ef722b65bd3a4ff117
MD5 e29ea11fe34ff82943c157c5472052e4
BLAKE2b-256 d59595f6d676e0d8cdd9013e571f7eab5089751f9bb00d78b41bf795a173820c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page