Skip to main content

Chalk Sandbox SDK

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

Contributor note: for testing deployed functions against local chalkcompute or local chalk-remote-call-python changes, see local-sdk-remote-call-testing.md.

Install

pip install grpcio protobuf

Quick start

from chalkcompute import Sandbox

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

# 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 chalkcompute import Image, Sandbox

# 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 = Sandbox(image=img).run()
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:

from chalkcompute import Image, Sandbox

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 = Sandbox(image=api_image).run()
worker_sandbox = Sandbox(image=worker_image).run()

Connecting

from chalkcompute 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

from chalkcompute import Sandbox, SandboxClient

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

client = SandboxClient.from_env()

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

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

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

# 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 chalkcompute import Sandbox

sandbox = Sandbox(image="ubuntu:latest").run()

# 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 chalkcompute import Sandbox

sandbox = Sandbox(
    image="ubuntu:latest",
    cpu="2",
    memory="4Gi",
    env={
        "ANTHROPIC_API_KEY": "sk-ant-...",
    },
).run()

# 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

from chalkcompute import Sandbox

sandbox = Sandbox(image="node:25-trixie-slim").run()

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

Download files

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

Source Distribution

chalkcompute-2.3.5.tar.gz (276.3 kB view details)

Uploaded Source

Built Distributions

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

chalkcompute-2.3.5-cp314-cp314-manylinux_2_28_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

chalkcompute-2.3.5-cp314-cp314-macosx_11_0_arm64.whl (4.5 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

chalkcompute-2.3.5-cp313-cp313-manylinux_2_28_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

chalkcompute-2.3.5-cp313-cp313-macosx_11_0_arm64.whl (4.5 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

chalkcompute-2.3.5-cp312-cp312-manylinux_2_28_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

chalkcompute-2.3.5-cp312-cp312-macosx_11_0_arm64.whl (4.5 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

chalkcompute-2.3.5-cp311-cp311-manylinux_2_28_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

chalkcompute-2.3.5-cp311-cp311-macosx_11_0_arm64.whl (4.5 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: chalkcompute-2.3.5.tar.gz
  • Upload date:
  • Size: 276.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for chalkcompute-2.3.5.tar.gz
Algorithm Hash digest
SHA256 4b48f0e44360772ce7b4df0026861c7197b40b252bbf76c3ccd5675248d3436c
MD5 cb47cc96e28dfafcba975543d75c052e
BLAKE2b-256 066331bdbcff37359c80bb5d4686d9060c2a9d56439cfd05480beac417fdc1e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-2.3.5.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-2.3.5-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chalkcompute-2.3.5-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 63b35c93cceebaf2279b29c0a96e632cc973f27d0d3ca359217f9c93965b3594
MD5 156cc69009a4c8883ee1dbacaeb61e85
BLAKE2b-256 731228d62e3387efb5f823e340c077ea06392e93cda38c1656ab65b9440f94dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-2.3.5-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-2.3.5-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for chalkcompute-2.3.5-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f5af55ccbf9b57b1ce799149c54b5f68e75fcddd0d7237bcdbf33d83ba40dbbf
MD5 24578a4b78cf8c7cea6768dd8d047f9d
BLAKE2b-256 1ddb2ae445090907b8618864715807f36463c4637f221dc268a8c9e8259c7859

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-2.3.5-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-2.3.5-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chalkcompute-2.3.5-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 91e2d1e22efc25a5ec8059fd29d1e660b55fabdf60ae25b1b51012cdf3be9fbc
MD5 8b8c199baaf176f3f469bc138383e831
BLAKE2b-256 11b594a168715183bb2ba4c1b305993c2d204e95cdf48d11d2b689b09d04f8ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-2.3.5-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-2.3.5-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for chalkcompute-2.3.5-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a158f577b7fd1833dc274870d810685162ecbc3ee7da4166590b025224deef5a
MD5 da244be16044ad68cff58d4e7fcc4d6a
BLAKE2b-256 49ae696ed5f9d9605cfd2071db42b06dbc9529ebf1239cf48ee26bda39b2fe75

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-2.3.5-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-2.3.5-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chalkcompute-2.3.5-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 98c4b08642ba373740cdbd30179579e73027609348130d7a57546226e376f1a9
MD5 b70866bb6519c9d8c31d023016b7cd65
BLAKE2b-256 a734188dda5c45273d8ea890304c191d5121f2427ec178b4ea2659f6fdd1d8d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-2.3.5-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-2.3.5-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for chalkcompute-2.3.5-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6bd42ac4567d04ad03da42f5c1cd2f52d5308dfdbc49e992169ecc15cd5b8330
MD5 d6e4e5f8d58c58a1bb834484f321d526
BLAKE2b-256 1b88482100b5d399b933a6a67c25fc64b3d6edb5ce137fe5663f15f41c06a1b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-2.3.5-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-2.3.5-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chalkcompute-2.3.5-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 df44657f345d921ef29a68f40c76b3e3dbb07aa926382e4e1638a944f6a7e218
MD5 ff7360436711bbb4445167159209bc55
BLAKE2b-256 5f4e56043d8f1d0ded49ec382de90238f1e32866c1c2ff34eabe59098cf1920e

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-2.3.5-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-2.3.5-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for chalkcompute-2.3.5-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5aa4099e0eebf4e4c04ed8462c635149c4f928372aff0a56e1c6dec8db9e4bb1
MD5 86e442fc74940153a92ec74033f14d9e
BLAKE2b-256 033ecb1514d3a4e6f6a6784c4091e1172e25ecd10cc45d2c2b207ce2dd33e286

See more details on using hashes here.

Provenance

The following attestation bundles were made for chalkcompute-2.3.5-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.

Release history Release notifications | RSS feed

2.11.8

13 files

2.11.7

13 files

2.11.6

13 files

2.11.5

13 files

2.11.4

13 files

2.11.3

13 files

2.11.2

13 files

2.11.1

13 files

2.9.8

13 files

2.9.7

13 files

2.9.6

13 files

2.9.5

13 files

2.9.4

13 files

2.9.3

13 files

2.9.2

13 files

2.9.1

13 files

2.9.0

13 files

2.8.1

13 files

2.8.0

13 files

2.7.0

13 files

2.6.2

13 files

2.6.1

9 files

2.5.3

9 files

2.5.2

9 files

2.5.1

9 files

2.5.0

9 files

2.4.1

9 files

2.3.9

9 files

2.3.8

9 files

2.3.7

9 files

2.3.6

9 files

This release

2.3.5 This release

9 files

2.3.4

9 files

2.3.3

9 files

2.3.2

9 files

2.3.1

9 files

2.3.0

9 files

2.2.0

9 files

2.1.8

9 files

2.1.3

9 files

2.1.2

9 files

2.1.1

9 files

2.1.0

9 files

2.0.1

9 files

2.0.0

9 files

1.5.17

9 files

1.5.16

9 files

1.5.15

9 files

1.5.14

9 files

1.5.13

9 files

1.5.12

9 files

1.5.11

9 files

1.5.10

9 files

1.5.9

5 files

1.5.6

5 files

1.5.5

2 files

1.5.3

2 files

1.5.2

2 files

1.5.1

2 files

1.5.0

2 files

1.4.2

2 files

1.4.1

2 files

1.4.0

2 files

1.3.0

2 files

1.2.0

2 files

1.1.1

2 files

1.1.0

2 files

1.0.0

2 files

0.1.1

2 files

0.1.0

2 files

0.0.0

9 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page