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"},
    chalk_identity=True,
)

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

Set chalk_identity=True to give the sandbox a platform-managed Chalk identity. The sandbox receives CHALK_WEB_IDENTITY_TOKEN_FILE and the Chalk API/environment settings it needs to authenticate without caller credentials being copied into the workload.

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

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.14macOS 11.0+ ARM64

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

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

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

File metadata

  • Download URL: chalkcompute-2.6.1.tar.gz
  • Upload date:
  • Size: 290.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.6.1.tar.gz
Algorithm Hash digest
SHA256 e518fe67d37c8235a4b2656367dc58b34dc7276b3290ba0e68cf3dd9f8d661a4
MD5 c86bf469a03fb5db41cdb43e8fda9001
BLAKE2b-256 39a6b79862b199f6b540dae24ae6cb1268169f2a6aca3fbfb626866255c031cd

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.6.1-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 59b9c4f59c4d023fd22f9a570c025dfc9c0caa273a11748815d2ee37759a7e4e
MD5 3a3705441e2c047e4ecf0dd3f1d0afbd
BLAKE2b-256 af0144af397845fd2568e40e937ca7a5ddc1a157fcc2ef5496823f92ab13d06a

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.6.1-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 611c1523ededd03099ea1f1c5c2f958a707591ed060dddb22581e69d9d28044d
MD5 00be31a251df04870d5a87d1eee8464d
BLAKE2b-256 bf7815c328e6071b8bb71ab0eee299f5a30c4f91eb4827d3a221413ac529fe12

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.6.1-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 341b07233e6d18d3aa0a97a8ce25ee1c6327112bd1f81730820159334f42fc6e
MD5 de8e13ff056986ccb79d94cb8f5d647a
BLAKE2b-256 a55820b95054553e9b0e12b9cb2d4b8337dce4dd7348679f3a4015af0639001b

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.6.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f8ce22a2e9e6443245d89734fc3fc5c6df9deb7ce386e742c51073a0f78e7a68
MD5 497473c2fb3d5e1ab48d8e869d3ccf6e
BLAKE2b-256 1e371d2123e32ba3a0da0348f2a9687b513f200545ac4b790ebc96efd6eabf9f

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.6.1-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f912a2f6c24f96a2ae9c849f1092cdaf79912397f67bcee6fdd0e4fbc6b2cd40
MD5 2cf0618717344b2ffd956933f99901de
BLAKE2b-256 85fefac37d86ab5d217af51e259800f530b1b0c4c9e99f077be4d571eec2611c

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.6.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 55fb49ab6dbbcef9fd802981631eba4f827bae9e62b09ac9103d106ff625744b
MD5 5d1dbe92277aad4313e738ee76b35454
BLAKE2b-256 6c07121299c6ba99285c5e433be75e2ea7151c47d30d2d010eaf0fd01b41ffc0

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.6.1-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 be9c8b32df8f1c4c24cc637d50bed2dca9ee00bea4437e9d0643ab26f2f3ff35
MD5 0a3a1b4799d279af0f96d19480658b3b
BLAKE2b-256 f4af90aa03856e01a4bb88423b7160a8b7c0a4b605511e5f4e863e28f8eed630

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for chalkcompute-2.6.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cb24f96b55e7218fbddde6f210338243983e34d1f400d194dfb7b5cfcf09b9bd
MD5 795d30a7092db3913aa6e47111740216
BLAKE2b-256 2f74cc21b0d1f1f10f4740b68a3f99e1b69ebb8fd535f515160e017e51e947fd

See more details on using hashes here.

Provenance

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

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

This release

2.6.1 This release

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

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