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.11.tar.gz (183.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.11-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.11-cp314-cp314-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

chalkcompute-1.5.11-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.11-cp313-cp313-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

chalkcompute-1.5.11-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.11-cp312-cp312-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

chalkcompute-1.5.11-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.11-cp311-cp311-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: chalkcompute-1.5.11.tar.gz
  • Upload date:
  • Size: 183.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.11.tar.gz
Algorithm Hash digest
SHA256 f8553aafd13effd7340260d7bfa6f278fe3d36ee2ca99db932905e53cd4e8376
MD5 71e2704631ae6c07187d78318cd38451
BLAKE2b-256 3925daffd7410be4f4cedfd3fe955c15ab875476cbd5b702daea8ce3ce4d4bdf

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-1.5.11-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 378c567d6cbc94314791b3023de94054673b578db8d2f5fc0d47426d9d14680a
MD5 34957684183952bc05f57a9737ff8e67
BLAKE2b-256 9da1a6d0e3a365d801aed4d16b2e26a013a69c16de49dc7dd96f2e71cc9db153

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-1.5.11-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6195b1e626ca3fe9cb6c30aa14d1c13c958f420c2698a5804b36dd888d28fdc1
MD5 35c770b30570519a365ba289f5ad5246
BLAKE2b-256 a6e33808fe181e93874782e3d973218989a72f152f40aefd25a6a9ab7836affb

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-1.5.11-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 245f1db043b2a6e4f7de07c359f29d92574dddc4972a3443ad03a7652e61b4e3
MD5 a813193d1d3ca926217e27c9c7114943
BLAKE2b-256 793825d32c39a309c2d73b114fb7971e460be0641ecccac3b4b084931c3f3b31

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-1.5.11-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c9031cabf490727094b69efc93257051863ce3ca5478b0ca1599cdc6cb556229
MD5 3fd2fad266216907428904224b0f4724
BLAKE2b-256 9c8abdaf1103838ecab7ef133d08fcfc104138e4d901a25211b23602b8f842f3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-1.5.11-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b53a9de7765a70577b79fdbc52ccf85bee494a5bb493ede273e2ef5fe6df30e2
MD5 479cda7334c81a5d7367a1fa10591317
BLAKE2b-256 f7cf0a2104fc166954977199ab1d157d9b5723f4b04215c7be2d7dc6b3bf2344

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-1.5.11-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5f8037ccd3a0e42b2866f3aae77df448824b3b453d113b370e62bc20dda3875c
MD5 a643f37cbaa2ad281d0a194cc140b8c1
BLAKE2b-256 46e028a7575969cbafc792e2adc9835de08343563c02adcfce13d74a4d95e006

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-1.5.11-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9d21656339d83e2cccd454432d4f683476d74378ad2569fcba9897446f4db162
MD5 77c4059ada5f1b582470ec8876d30d97
BLAKE2b-256 13cab23984b6d592a9ef102676a15aaa3652170be13b640f876449a5147228d1

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-1.5.11-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1748b8c135b9513122302baf33f9eef2370cd1b4d03b3ae92a200be04da0958a
MD5 2a49b6cd78d7163e6137869e8ef04980
BLAKE2b-256 e3929ff4f7b2bd84805e1e1917e638b91d96526e8f344afff030e008863853be

See more details on using hashes here.

Provenance

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