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

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-2.0.1.tar.gz (217.6 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.0.1-cp314-cp314-manylinux_2_28_x86_64.whl (2.9 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

chalkcompute-2.0.1-cp314-cp314-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

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

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

chalkcompute-2.0.1-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-2.0.1.tar.gz.

File metadata

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

File hashes

Hashes for chalkcompute-2.0.1.tar.gz
Algorithm Hash digest
SHA256 64baa5e7ee8e1915d5d391e17e4651579df1d2abe13adb018e36718eac0e4617
MD5 a734905468607ebbbfcbbe6e23708e19
BLAKE2b-256 f0be39a4665d9af91ee53f986285bfdb4d129f26af8e0243477e1fc5e3891fe4

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.0.1-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 156faf1423323a5072e5635f4fe2af9f9dc03e593bdce44aebd6c237627109e2
MD5 fffd6c14795d88448472e7bb27163092
BLAKE2b-256 640ef637c1d3f41ab916e98054e0e974c9af5ea2e446f7208eb1447d3fd498e7

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.0.1-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 58a7f243479740811f735e0504bd2db962691c39df8b43c3f06fea288faae946
MD5 ae5337e1bcc55631e1790a7009a65eca
BLAKE2b-256 28555f20284e68b7e00a827cc6a004934f4422d1f76c57e9948cf84caecab169

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.0.1-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 657c858a9db3edabfe813564693dd17bf59aaeeae304c220d1a71787328ebc7f
MD5 ebc7068edf02477b93f7a42123045bcc
BLAKE2b-256 d604085d4ddaec72dec4b74877f4db2e19bc800b795fbe91d59a63075d231bcb

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.0.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 99de18a7f74ecf8efd50634c12ff92948e62af29a142888cbf7cb1e089f336b5
MD5 5f8e063d2cf36d28b4e5ffa04a7fed2e
BLAKE2b-256 094368961c44946893a669d1bfff2ed8771b73228cb0249230ea3377308fb379

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.0.1-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3b6b8ae0c628658925379253272cdf53d7c2d42d874e842d0669a996e14c5fb8
MD5 b10521c8c187109cbc4c05b19e7b3e9b
BLAKE2b-256 032fe6c3a06fff7cc807208f2a90227fe4f6d6fc015f5a6f833fad54b75a2b60

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.0.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e48108d468eaede1bac77858510fae145fc4fe95658aa1a4573446dbc77d4b20
MD5 a54582418dd7f926c86d6098efc4141d
BLAKE2b-256 09782db1cfd0f36d0698095ce3b94d6b1afe0a7c0d40f3269da841f7d9a2248f

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.0.1-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 546feb64fa337370713f58d4e97b35de5746a5cef76d06172635ced7d19789fd
MD5 ff97ddb34e3c1684b4b6353c429637b4
BLAKE2b-256 83ac072db0c481d2a478191154715db55637d51c0fefb641cd0cea832832be27

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.0.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5c5160fe24f2c4feca7c220ec7076804aea881c181a52b46dfbd43d87aee45fc
MD5 87249e96668a82f0b9e08246e100b5f0
BLAKE2b-256 6c3cebac05fcb36dd4ca695c2be6bec1ee87aca3a773532d035879e8b5c965b6

See more details on using hashes here.

Provenance

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