Skip to main content

SDK for Chalk sandboxes, containers, and volumes

Project description

Chalk Sandbox SDK

Python SDK for the Chalk Sandbox gRPC service. Create sandboxes, execute commands, and stream output over bidirectional gRPC streams.

Install

pip install grpcio protobuf

Quick start

from sandbox import SandboxClient

client = SandboxClient("localhost:50051")

# Create a sandbox from a pre-built image
sandbox = client.create(image="ubuntu:latest")

# Run a command
result = sandbox.exec("echo", "hello world")
print(result.stdout_text)  # "hello world"
print(result.exit_code)    # 0

# Clean up
sandbox.terminate()

Declarative images

Build custom container images with a fluent API instead of writing Dockerfiles. The image spec is serialized as protobuf and transmitted to the sandbox service, which builds and caches the image before starting the container.

from sandbox import SandboxClient
from image import Image

client = SandboxClient("localhost:50051")

# Build a data-science image declaratively
img = (
    Image.debian_slim()
    .pip_install(["pandas", "numpy", "scikit-learn"])
    .run_commands(
        "apt-get update && apt-get install -y git curl",
    )
    .workdir("/home/user/app")
    .env({"PYTHONDONTWRITEBYTECODE": "1"})
)

sandbox = client.create(image=img)
result = sandbox.exec("python", "-c", "import pandas; print(pandas.__version__)")
print(result.stdout_text)

Base images

# Arbitrary base image
img = Image.base("node:25-trixie-slim")

# Convenience: python + debian slim
img = Image.debian_slim()  # python:3.14-slim-trixie

# From an existing Dockerfile (contents are inlined, so you can chain more steps)
img = Image.from_dockerfile("Dockerfile").pip_install(["extra-dep"])

Build steps

img = (
    Image.debian_slim()
    # Install Python packages
    .pip_install(["requests", "flask"])

    # Install from a requirements.txt (read locally, inlined into the spec)
    .pip_install_from_requirements("requirements.txt")

    # Run shell commands (each becomes a Docker RUN layer)
    .run_commands(
        "apt-get update && apt-get install -y git",
        "mkdir -p /app/data",
    )

    # Add local files into the image
    .add_local_file("config.yaml", "/app/config.yaml")
    .add_local_file("entrypoint.sh", "/app/entrypoint.sh", mode=0o755)
    .add_local_dir("src", "/app/src")

    # Raw Dockerfile instructions
    .dockerfile_commands(["EXPOSE 8080", "HEALTHCHECK CMD curl -f http://localhost:8080/"])

    # Image-level configuration
    .workdir("/app")
    .env({"FLASK_APP": "app:create_app"})
    .entrypoint(["/app/entrypoint.sh"])
    .cmd(["serve"])
)

Immutable composition

Each builder method returns a new Image, so intermediate images can be shared:

base = Image.debian_slim().pip_install(["requests"])

# Two different images that share the same base
api_image = base.pip_install(["flask"]).workdir("/api")
worker_image = base.pip_install(["celery"]).workdir("/worker")

api_sandbox = client.create(image=api_image)
worker_sandbox = client.create(image=worker_image)

Connecting

from sandbox import SandboxClient
import grpc

# Insecure (local dev)
client = SandboxClient("localhost:50051")

# With TLS
creds = grpc.ssl_channel_credentials()
client = SandboxClient("sandbox.example.com:443", credentials=creds)

# As a context manager
with SandboxClient("localhost:50051") as client:
    ...

Sandbox lifecycle

# Create with resource limits
sandbox = client.create(
    image="ubuntu:latest",
    cpu="2",
    memory="4Gi",
    env={"DEBIAN_FRONTEND": "noninteractive"},
)

# List all sandboxes
for info in client.list():
    print(f"{info.id} {info.state} {info.name}")

# Get a handle to an existing sandbox by ID
sandbox = client.get(id="550e8400-e29b-41d4-a716-446655440000")

# Fetch info from server
print(sandbox.info.state)
sandbox.refresh()  # force re-fetch

# Terminate
sandbox.terminate()
sandbox.terminate(grace_period_seconds=30)

Executing commands

Run and wait

result = sandbox.exec("ls", "-la", "/tmp")
for line in result.stdout:
    print(line)
for line in result.stderr:
    print(f"ERR: {line}")
print(f"exit code: {result.exit_code}")

# Or get the full text at once
print(result.stdout_text)
print(result.stderr_text)

Stream output in real time

for event in sandbox.exec_stream("make", "build", workdir="/app"):
    if event.stdout:
        print(event.stdout, end="")
    if event.stderr:
        print(event.stderr, end="", file=sys.stderr)
    if event.is_exited:
        print(f"\nDone: exit code {event.exit_code}")

Interactive processes (stdin + signals)

process = sandbox.exec_start("bash")

process.write_stdin("echo hello\n")
process.write_stdin("exit\n")
process.close_stdin()

for event in process.output():
    if event.stdout:
        print(event.stdout, end="")

Send signals to running processes:

import signal

process = sandbox.exec_start("sleep", "300")
process.send_signal(signal.SIGTERM)
result = process.wait()

Options

All exec methods accept the same keyword arguments:

result = sandbox.exec(
    "python", "train.py",
    workdir="/app",                     # working directory
    timeout_secs=3600,                  # kill after 1 hour
    env={"CUDA_VISIBLE_DEVICES": "0"},  # environment variables
)

Examples

Clone a GitHub repo into a sandbox

from sandbox import SandboxClient

client = SandboxClient("localhost:50051")
sandbox = client.create(image="ubuntu:latest")

# Install git
sandbox.exec("apt-get", "update")
sandbox.exec("apt-get", "install", "-y", "git")

# Clone
result = sandbox.exec(
    "git", "clone", "https://github.com/chalk-ai/chalk.git", "/workspace/chalk"
)
if result.exit_code != 0:
    print(f"Clone failed: {result.stderr_text}")
else:
    # List what we got
    result = sandbox.exec("ls", "-la", "/workspace/chalk")
    for line in result.stdout:
        print(line)

Spawn an OpenCode agent in a sandbox

OpenCode is a terminal-based AI coding agent. You can run it inside a sandbox to give it an isolated environment to work in.

from sandbox import SandboxClient

client = SandboxClient("localhost:50051")
sandbox = client.create(
    image="ubuntu:latest",
    cpu="2",
    memory="4Gi",
    env={
        "ANTHROPIC_API_KEY": "sk-ant-...",
    },
)

# Install dependencies
sandbox.exec("apt-get", "update")
sandbox.exec("apt-get", "install", "-y", "git", "curl", "build-essential")

# Install Go (opencode is a Go binary)
sandbox.exec("bash", "-c", "curl -fsSL https://go.dev/dl/go1.26.3.linux-amd64.tar.gz | tar -C /usr/local -xz")
sandbox.exec("bash", "-c", "echo 'export PATH=$PATH:/usr/local/go/bin:/root/go/bin' >> /root/.bashrc")

# Install opencode
sandbox.exec("bash", "-c", "export PATH=$PATH:/usr/local/go/bin:/root/go/bin && go install github.com/opencode-ai/opencode@latest")

# Clone a repo to work on
sandbox.exec("git", "clone", "https://github.com/your-org/your-repo.git", "/workspace/repo")

# Run opencode non-interactively with a prompt
result = sandbox.exec(
    "bash", "-c",
    "export PATH=$PATH:/usr/local/go/bin:/root/go/bin && cd /workspace/repo && opencode -p 'fix the failing tests in pkg/auth'",
    timeout_secs=600,
)
print(result.stdout_text)

# Or run it interactively and feed it commands
process = sandbox.exec_start(
    "bash", "-c",
    "export PATH=$PATH:/usr/local/go/bin:/root/go/bin && cd /workspace/repo && opencode",
)

# Stream its output
for event in process.output():
    if event.stdout:
        print(event.stdout, end="")
    if event.stderr:
        print(event.stderr, end="", file=sys.stderr)
    if event.is_exited:
        break

Long-running build with real-time output

sandbox = client.create(image="node:25-trixie-slim")

sandbox.exec("git", "clone", "https://github.com/your-org/frontend.git", "/app")
sandbox.exec("npm", "install", workdir="/app")

# Stream the build output as it happens
for event in sandbox.exec_stream("npm", "run", "build", workdir="/app"):
    if event.stdout:
        print(event.stdout, end="")
    if event.stderr:
        print(event.stderr, end="", file=sys.stderr)
    if event.is_exited and event.exit_code != 0:
        print(f"Build failed with exit code {event.exit_code}")

sandbox.terminate()

CLI tools

sandbox_exec.py - Run a command

python sandbox_exec.py --target localhost:50051 --sandbox-id <id> --exec "ls -la"

sandbox_stdout.py - Interactive shell

echo "echo hello" | python sandbox_stdout.py --target localhost:50051 --sandbox-id <id> --exec "bash"

Regenerating proto stubs

If the proto definition changes, regenerate the Python stubs:

pip install grpcio-tools
./generate.sh

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

chalkcompute-1.5.14.tar.gz (193.0 kB view details)

Uploaded Source

Built Distributions

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

chalkcompute-1.5.14-cp314-cp314-manylinux_2_28_x86_64.whl (2.9 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

chalkcompute-1.5.14-cp314-cp314-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

chalkcompute-1.5.14-cp313-cp313-manylinux_2_28_x86_64.whl (2.9 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

chalkcompute-1.5.14-cp313-cp313-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

chalkcompute-1.5.14-cp312-cp312-manylinux_2_28_x86_64.whl (2.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

chalkcompute-1.5.14-cp312-cp312-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

chalkcompute-1.5.14-cp311-cp311-manylinux_2_28_x86_64.whl (2.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

chalkcompute-1.5.14-cp311-cp311-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file chalkcompute-1.5.14.tar.gz.

File metadata

  • Download URL: chalkcompute-1.5.14.tar.gz
  • Upload date:
  • Size: 193.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for chalkcompute-1.5.14.tar.gz
Algorithm Hash digest
SHA256 1bb7caf519c3c553afcc215843b8a93e2b26a538a77ee332075eeabc152a5933
MD5 52d602b99aa47eb298662419b776ece1
BLAKE2b-256 80e6d724da5674ca10db9ebd8cc0d008aedb1cefa907ab58ca88fa4053ed5a0c

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-1.5.14.tar.gz:

Publisher: release.yml on chalk-ai/chalk-sandbox-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chalkcompute-1.5.14-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chalkcompute-1.5.14-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6a9040451fcff4f54d249ccfc0fec52dcbd273103845e1e5c2307b8a2cd0e333
MD5 3ebbe55dfceb44b8da835e0ec92c9fb0
BLAKE2b-256 2c330a4dcc93567f7888173ea184c5fcd66960236fb5bd38fb2e568d532d7191

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-1.5.14-cp314-cp314-manylinux_2_28_x86_64.whl:

Publisher: release.yml on chalk-ai/chalk-sandbox-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chalkcompute-1.5.14-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for chalkcompute-1.5.14-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bc5dbd2e09b8379d76b3aa6439ac8d3e9c88c624dd77d8b28824bccd304a46c7
MD5 48997f438250d39a1f45488486dfb4b5
BLAKE2b-256 e0fdcc25fca86a42f46cbfa873e6bec0b522b185af3704565f32188d657f8ff7

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-1.5.14-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: release.yml on chalk-ai/chalk-sandbox-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chalkcompute-1.5.14-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chalkcompute-1.5.14-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9d6bf9e0a178a7b335492a3a690bb1b2e7f2a73c914432761a45017c5d5edebb
MD5 008b23f49d2307bc6bbfb35e0175cdfc
BLAKE2b-256 c6a229f377439cab05b675ddb7442c8945c7ad8c7b4f39fd32568ab07fd8eba1

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-1.5.14-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: release.yml on chalk-ai/chalk-sandbox-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chalkcompute-1.5.14-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for chalkcompute-1.5.14-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b06d39912a107f8cce2ac4f0243fd514e7a86976e31f6bf2da4e003b30ed41d0
MD5 30ca437f059643a01f2a3a4f41592e73
BLAKE2b-256 c94ae14775bcaef284bb1983dfb83470cb61f570bd52ba5fbba647ab11422268

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-1.5.14-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on chalk-ai/chalk-sandbox-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chalkcompute-1.5.14-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chalkcompute-1.5.14-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 25431be47eb08bfb9f74d77a1419af3d2baa6f93f995e464bafc99605a6ec5a7
MD5 356c744bdb6d79f72d5aa3c26232945b
BLAKE2b-256 42cbc1112e4bdfdf92b1abccfe4155a6591437701c3cc706aca289330fdc4677

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-1.5.14-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: release.yml on chalk-ai/chalk-sandbox-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chalkcompute-1.5.14-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for chalkcompute-1.5.14-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 da807cf34544f4b4279079d7c3db2725457f932c20ba2871fdecf182d320c5a8
MD5 340f94816ec69cd7a514abf322970d57
BLAKE2b-256 882a658090aae551edcf95e159f0d3a4deeabfd2e5f179f5f4ab84dd171362a6

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-1.5.14-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on chalk-ai/chalk-sandbox-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chalkcompute-1.5.14-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chalkcompute-1.5.14-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 decf79a460e9164c66829c778b0e194272b036a7d879c7c9e7264d50ac1b8bbe
MD5 54695723a6ee34e70f05ac2dfded5587
BLAKE2b-256 9022a34ca07e5879865e2804d161ff16af3b717457fc88a9cbf209421de43666

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-1.5.14-cp311-cp311-manylinux_2_28_x86_64.whl:

Publisher: release.yml on chalk-ai/chalk-sandbox-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chalkcompute-1.5.14-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for chalkcompute-1.5.14-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b51d2e8a697ed5956bd1b4966c3221a48865ab36928e1e785e7e4e367d9182ae
MD5 393a30163127eff9d6bb6d022e17ff5d
BLAKE2b-256 d6b9bd5e892374c675c84063f6f92be4caed5d5bf45d7eeecbba30d583910c00

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-1.5.14-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on chalk-ai/chalk-sandbox-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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