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 SandboxClient

with SandboxClient.from_env() as client:
    # 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 chalkcompute import Image, SandboxClient

# 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"})
)

with SandboxClient.from_env() as client:
    sandbox = client.create(image=img)
    result = sandbox.exec("python", "-c", "import pandas; print(pandas.__version__)")
    print(result.stdout_text)
    sandbox.terminate()

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)

api_sandbox.terminate()
worker_sandbox.terminate()

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

Rotating workload identity

The SDK can use a directly usable Chalk JWT from a rotating token file instead of a client ID and secret:

export CHALK_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/chalk/identity-token
export CHALK_API_SERVER=https://api.chalk.ai

Each SDK client caches the token for the shorter of one hour or half of the token's remaining lifetime from its exp claim, then re-reads the file on its next authenticated operation. Tokens without exp use the one-hour limit. Changing the configured file path bypasses the cache. The JWT's environment_id claim selects the environment unless CHALK_ENVIRONMENT or CHALK_ENVIRONMENT_ID is set explicitly. Queued function calls additionally require CHALK_GRPC_ENGINE, because identity JWTs do not contain engine-routing data.

Workload identity federation

Use the authenticated Connect client to mint a short-lived OIDC token for a third-party workload identity provider. For example, with Snowflake configured to trust Chalk's issuer and JWKS:

from chalkcompute import ConnectClient

token = ConnectClient().get_workload_identity_token("snowflakecomputing.com")

The token is scoped to the active Chalk environment. Its audience is the value passed to get_workload_identity_token, and its signing key is published by the Chalk API server at /.well-known/jwks.json.

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.status} {info.name}")

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

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

# Terminate, optionally with a grace period
sandbox.terminate()
existing_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 SandboxClient

client = SandboxClient.from_env()
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)

sandbox.terminate()
client.close()

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 SandboxClient

client = SandboxClient.from_env()
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

sandbox.terminate()
client.close()

Long-running build with real-time output

from chalkcompute import SandboxClient

client = SandboxClient.from_env()
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()
client.close()

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.5.2.tar.gz (301.8 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.5.2-cp314-cp314-manylinux_2_28_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

chalkcompute-2.5.2-cp314-cp314-macosx_11_0_arm64.whl (4.6 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

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

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

chalkcompute-2.5.2-cp313-cp313-macosx_11_0_arm64.whl (4.6 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

chalkcompute-2.5.2-cp312-cp312-macosx_11_0_arm64.whl (4.6 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

chalkcompute-2.5.2-cp311-cp311-macosx_11_0_arm64.whl (4.6 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

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

File metadata

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

File hashes

Hashes for chalkcompute-2.5.2.tar.gz
Algorithm Hash digest
SHA256 c3bc57db231dd8c590b3d64bf956574e2705f6227da6546ccfd7239fe4e84e33
MD5 0c05f2cc2dc0c28a03815b4b7a507899
BLAKE2b-256 f44d963f78e37f78cc0d101bec9df5475d27cb2bbc94fd9c5063b9ff52e8c62c

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.5.2-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b7cc73629ee6a4dc60eb549afd466727cec4df86915be95bccee077ba6c78972
MD5 0e771690eba821c7e3e60fc2519551d8
BLAKE2b-256 36e7f5f29af1d79c249f349e843dba5f8182f02a618055a3f070ad02fabe166e

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.5.2-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9d84fdcdd75f6f3f19d34d92adb46cd044d6d3e237ad992ea119ce99147ef914
MD5 725c43a21717e2321814bd2ab3324172
BLAKE2b-256 25c28afc828af223aca1328cf52e94178f567623da7a7588716a1a67b68333b2

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.5.2-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 29ac1a473b917968ddc51149d771fc0c5387d54b326f4beea67487c207329178
MD5 3d48d68e704f2ee8ad737b99f83e0038
BLAKE2b-256 6687f6cdb896b12d8ee793c8f0263ecc5d35ae588bf0a884a37c0e6f076d2fd2

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.5.2-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c60a2c2a13e7a628b7c740196de1e806615bfd32517886d3dcc992223a5fcec2
MD5 bb8758b90bd4256d6169b2d492dbceac
BLAKE2b-256 5810de86a9a751ddb0eacdd13013f76c1f9024e98d577e475601119be7a9a89e

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.5.2-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2c9e5a2566533dd43d784fb6a22c12e52906edc2d9bd7fb87f64782a208a6f69
MD5 9e6ec4ecc7e9ce5e7c926a3c6e958645
BLAKE2b-256 6f734d1252d9f91552a04f49a5c1d5334353db643bdb15229ce899519010f3b8

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.5.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d597a8bea272f1e85cc567c10a2ff6cf21ed86435d15d60e89a64a19d9d629cc
MD5 4d6c03d5e224a6f967d155e0fd8c8b35
BLAKE2b-256 b17c333e7d4a60b12cddd178b8a6e5bd8c161a0eeb6d28ad47e92504ad8d0c13

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.5.2-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d8f19e8d6ff587dcf00b899dd8221ef411c29207e452c2731f8e6a21874853e9
MD5 2f6f33f781982431f4d9fb09246f55c7
BLAKE2b-256 702c793970c6c45de8f6907d42167bf39e553123e07e096257d1e28baf4d8b8c

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.5.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 af1b2bb2baf0ab2f9e109a42e4596330cfb093d3b961d646e3d33c5f51feab06
MD5 a077c56850fc3def397818570d2faa6b
BLAKE2b-256 f542176f286badaee681272b10b558c9cc78a3c994f79984de90194e4ded687b

See more details on using hashes here.

Provenance

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

This release

2.5.2 This release

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

2.3.5

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