This reference documents the chalkcompute Python SDK for building and deploying containers, sandboxes, volumes, remote functions, and scaling groups on Chalk's managed compute infrastructure. Use it to spin up isolated environments, stash files in persistent volumes, and deploy versioned Python functions and classes that scale on demand.
New to Chalk Compute? Start with the Compute overview for a conceptual tour of sandboxes, containers, scaling groups, and the deployment model. Then dive into Images, Functions, Volumes, and Sandbox design for task-oriented guides. The sections below document every public class and function in the SDK.
A full end-to-end sandbox: build an image with your code baked in, create the sandbox, exec a command inside it, read the output, and tear it down.
from chalkcompute import SandboxClient, Image
client = SandboxClient(target="sandboxes.example.com:443")
img = (
Image.debian_slim("3.12")
.pip_install(["pandas", "requests"])
.add_local_file(
"./analyze.py",
"/app/analyze.py",
)
.workdir("/app")
)
sandbox = client.create(
image=img,
name="analysis-scratchpad",
cpu="2",
memory="4Gi",
)
result = sandbox.exec(
"python",
"/app/analyze.py",
"--input", "/data/in.csv",
)
print(result.stdout_text)
sandbox.terminate()
Declarative, composable container image builder using a fluent API.
Each builder method returns a new Image instance so intermediate images
can be shared and extended. Use class methods like Image.debian_slim()
or Image.base() to start, then chain pip_install, run_commands,
add_local_file, etc.
Declarative, composable container image builder.
Uses a fluent (method-chaining) API. Each method returns a new Image
instance so that intermediate images can be shared and extended.
from chalkcompute import Image
img = (
Image.debian_slim("3.12")
.pip_install(["requests", "pandas"])
.workdir("/home/user/app")
)
Local files deferred for volume-mounting at sandbox start.
set[LazyLocalFile] Copy of the set of lazy local files tracked by this image.
Install Python packages via uv pip install.
Uses the uv resolver instead of pip for significantly faster
installs. Requires a base image that has uv available.
from chalkcompute import Image
img = (
Image.base("ghcr.io/astral-sh/uv:python3.12-bookworm-slim")
.uv_pip_install(["requests", "polars"])
)
from chalkcompute import Image
img = (
Image.debian_slim()
.add_local_file(
"./config.yaml",
"/app/config.yaml",
)
.add_local_file(
"./entrypoint.sh",
"/app/entrypoint.sh",
mode=0o755,
)
)
Add an entire local directory into the image.
Automatically respects .gitignore and .chalkignore files found
at any level within src (each scoped to its directory subtree,
matching go-git's behavior). The .git/ directory is always
excluded. Negation patterns (!) are supported.
"copy" inlines all file contents into the image spec.
"volume" (default) defers each file as a lazy reference
to be mounted at sandbox start.
from chalkcompute import Image
img = (
Image.debian_slim()
.add_local_dir(
"./src",
"/app/src",
exclude=["*.pyc", "__pycache__"],
)
)
Set the container CMD.
The CMD is the default argument list passed to the container's
entrypoint when the container starts. Unlike entrypoint — which
sets the executable that always runs — CMD defines the default
arguments that can be overridden at run time (for example, by a
Container.run(command=[...]) call or a Kubernetes pod spec).
If no entrypoint is set, the first element of CMD is treated as
the executable. If an entrypoint is set, CMD is appended to it.
Run python -m my_app by default, but allow the caller to override
the module at run time:
from chalkcompute import Image
img = (
Image.debian_slim()
.entrypoint(["python"])
.cmd(["-m", "my_app"])
)
Validate lazy local file destinations for volume mounting.
Volume-backed lazy files are grouped by parent directory and mounted at
that directory. Root-level destinations would require mounting at /,
which is not supported by container runtimes.
If a lazy local file would require mounting at the root directory.
Serialize this image definition to a protobuf ImageSpec.
The protobuf representation of this image.
High-level container abstraction backed by the Chalk ContainerService.
Orchestrates image building, local file upload via volumes, and container
lifecycle in a single API. Use Container(image=...).run() to start,
.exec() to run commands, and .stop() to clean up.
A managed container backed by the Chalk ContainerService.
Orchestrates image building, local file upload via volumes, and container lifecycle in a single high-level API.
Build an image, run a container, and exec a command inside it:
from chalkcompute import Container, Image
img = (
Image.debian_slim()
.pip_install(["requests"])
.add_local_file("./script.py", "/app/script.py")
)
c = Container(
image=img,
name="hello-container",
cpu="1",
memory="2Gi",
env={"LOG_LEVEL": "INFO"},
).run()
result = c.exec("python", "/app/script.py")
result.stdout_text
'hello\n'
c.stop()
Opaque container identifier assigned by the service.
None until run (or from_id / from_name)
has resolved the container against the service.
The most recently fetched ContainerInfo snapshot.
None until the container has been started or attached to.
Populated by run, from_id, and from_name.
Call refresh_info to fetch the latest state from the service.
Build the image, upload local files, and start the container.
Walks through three phases and blocks until the container is ready
(or raises): (1) build the image via CustomImageService, (2) if
the Image has add_local_file / add_local_dir entries
registered with strategy="volume", upload them to a managed
volume and attach it, (3) start the container and poll until it
reaches the Running state.
self, to allow chaining.
If the container fails to start or times out.
If the image build fails.
Build an image from scratch, start a container, inspect it, and tear it down:
from chalkcompute import Container, Image
img = (
Image.debian_slim("3.12")
.pip_install(["requests"])
.add_local_file(
"./app.py",
"/app/app.py",
)
.workdir("/app")
)
c = Container(
image=img,
name="hello-container",
cpu="1",
memory="2Gi",
env={"LOG_LEVEL": "INFO"},
)
c.run()
c.info.status
'Running'
c.stop()
Execute a command in the running container.
The command runs as a one-shot process inside the already-started
container (equivalent to docker exec). Output is captured in
full and returned at once; use exec if you need a
streaming interface.
The stdout, stderr, and exit code of the executed command.
If the container is not running or the exec fails.
Build an image, start a container, run a few commands against it, and clean up:
from chalkcompute import Container, Image
img = (
Image.debian_slim("3.12")
.pip_install(["requests"])
.add_local_file(
"./fetch.py",
"/app/fetch.py",
)
)
c = Container(
image=img,
name="fetcher",
cpu="1",
memory="1Gi",
).run()
hello = c.exec("python", "/app/fetch.py", "https://example.com")
hello.exit_code
0
hello.stdout_text.splitlines()[0]
'<!doctype html>'
err = c.exec("ls", "/does-not-exist")
err.exit_code
2
err.stderr_text
"ls: cannot access '/does-not-exist': No such file or directory\n"
c.stop()
Metadata about a running container.
id
Opaque container identifier assigned by the service.
name
DNS-safe container name.
status
Lifecycle state reported by the service (e.g. "Running").
pod_name
Underlying Kubernetes pod name.
web_url
Optional URL exposing the container's port, if one is published.
Result of a completed command execution.
exit_code Exit code of the process, if it exited normally. signal Signal number that terminated the process, if any. pid PID of the process, if known. error Error string if execution failed.
Low-level sandbox management backed by the Chalk SandboxService (gRPC).
Provides bidirectional streaming exec, interactive stdin/signal control, and fine-grained process lifecycle management.
Initialize the gRPC client.
Optional TLS/SSL channel credentials. If None, uses insecure
channel.
Container image to use — either a string reference
(e.g. "ubuntu:latest") or a declarative Image builder.
A sandbox handle.
A handle to a sandbox instance.
Obtain instances from create or
get. Use exec to run commands and
terminate to shut the sandbox down when you're done.
from chalkcompute import SandboxClient, Image
sandbox = SandboxClient().create(
image=Image.debian_slim().pip_install(["numpy"]),
)
result = sandbox.exec(
"python",
"-c",
"import numpy; print(numpy.__version__)",
)
result.stdout_text.strip()
'1.26.4'
sandbox.terminate()
Start a command and return an ExecProcess handle for interactive use.
The caller can write to stdin, send signals, and iterate output.
Handle for interacting with the running process.
Result of a completed command execution.
exit_code Exit code of the process, if it exited normally. signal Signal number that terminated the process, if any. pid PID of the process, if known. error Error string if execution failed.
A single event from a streaming exec call.
stdout Stdout text chunk, if this event carries stdout output. stderr Stderr text chunk, if this event carries stderr output. pid PID of the started process, set on the process-started event. exit_code Exit code of the process, set on the process-exited event. exit_signal Signal number that terminated the process, if any. error_code Error code string, set on error events. error_message Error message string, set on error events.
Handle to a running exec stream, allowing stdin writes and signal sends.
pid PID of the running process once the server reports it.
Persistent named volumes backed by object storage.
VolumeClient manages volume lifecycle; Volume provides file
operations (read, write, list, delete, batch upload).
Initialize the gRPC client.
Optional TLS/SSL channel credentials. If None, uses insecure
channel.
A handle to a named volume, providing file operations.
Volumes are persistent storage backed by object storage. Obtain an
instance via create or get.
Create a volume, upload files, and read them back:
from chalkcompute import VolumeClient
client = VolumeClient(target="volumes.example.com:443")
vol = client.create("models")
vol.put("config.yaml", b"learning_rate: 0.01\n")
vol.get("config.yaml")
b'learning_rate: 0.01\n'
[f.path for f in vol.list()]
['config.yaml']
Batch-upload multiple files atomically:
with vol.batch_upload() as batch:
batch.put("a.txt", b"hello")
batch.put("b.txt", b"world")
Deploy Python functions as versioned, autoscaling remote functions.
Remote functions turn an ordinary Python callable into a managed service. Chalk packages the function into a container image, deploys it as a ScalingGroup, routes incoming calls over gRPC, and handles replica autoscaling, warm-pool management, batching, and retries. Input and output Arrow schemas are inferred from the function's type hints so callers can invoke it with native Python values and the transport layer stays hidden.
The decorator form, function, is the common entrypoint: annotate
any callable with @chalkcompute.function(image=..., cpu=..., memory=...)
and call .deploy() to publish a new version. For the imperative API —
useful when wrapping functions defined elsewhere or deploying
programmatically — construct a RemoteFunction directly.
Use RetryPolicy to configure automatic retries, and catch the
FunctionError / FunctionBuildError hierarchy for
deploy-time and runtime failures.
Decorator that deploys a function as a versioned remote function.
Locally (at decoration time):
ExternalFunctionCatalogServiceCHALK_FUNCTION_LOCAL_SDK_COPY=1, includes local SDK source in
the deploy image for unreleased feature iteration.Remotely (inside the container): The decorator is a no-op — returns the raw function unchanged.
GPU resource request (e.g. "nvidia-l4", "2:nvidia-a100").
Format is "<count>:<type>" or just "<type>" for a single GPU.
Maximum time in milliseconds to buffer incoming items before invoking the handler. Defaults to 1000 ms when batching is enabled. When batching is enabled, handler args are lists or a single pyarrow table.
Maximum number of items to accumulate before invoking the handler. Defaults to 10 when batching is enabled.
Retry policy for handler invocations. Pass an int for simple
max-attempts with default exponential backoff, or a
RetryPolicy for full control.
import chalkcompute
@chalkcompute.function()
def add(x: int, y: int) -> int:
return x + y
add(1, 2)
A versioned remote function backed by ExternalFunctionCatalogService.
Deploys a Python function as a ScalingGroup and registers it with input/output Arrow schemas derived from the function's type hints.
Most users should prefer the function decorator; use
RemoteFunction directly when you need the imperative API (for
example, when wrapping a function defined elsewhere, or when
constructing deployments programmatically).
Decorator form — the most common entrypoint:
import chalkcompute
from chalkcompute import Image
img = (
Image.debian_slim()
.pip_install(["numpy"])
)
@chalkcompute.function(
image=img,
cpu="1",
memory="2Gi",
min_replicas=1,
max_replicas=4,
)
def embed(text: str) -> list[float]:
import numpy as np
return np.ones(8).tolist()
embed.deploy()
embed("hello world")
[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
Imperative form, for constructing a RemoteFunction from an existing
callable:
from chalkcompute import RemoteFunction, Image
def square(x: int) -> int:
return x * x
fn = RemoteFunction(
square,
image=Image.debian_slim(),
name="square",
min_replicas=1,
max_replicas=2,
)
fn.deploy()
fn(7)
49
Metadata about a deployed function version.
id Unique identifier of the function version. function_name Registered function name. version Monotonic version number for this function. scaling_group_name Name of the scaling group backing this version.
Retry configuration for handler invocations.
Construct via the named constructors rather than instantiating directly.
With exponential backoff, wait times grow geometrically
(initial, initial * multiplier, initial * multiplier^2, ...)
capped at max_wait. With linear, wait times are constant between
retries. A plain int passed to function(retries=3) is shorthand
for RetryPolicy.exponential(attempts=3). By default all Exception
subclasses trigger a retry; pass a tuple of exception classes to
retry_on to narrow the set.
max_retries
Maximum number of retry attempts (not counting the initial call).
initial_wait_seconds
Base wait time in seconds before the first retry.
backoff_multiplier
Multiplier applied to wait time on each successive retry.
Use 2.0 for exponential backoff (the default) or 1.0 for fixed delay.
max_wait_seconds
Upper bound on wait time between retries.
jitter
If True, add random jitter to wait times to avoid thundering herd.
retry_on
Tuple of exception types that trigger a retry.
Non-matching exceptions propagate immediately without consuming retry budget.
RetryPolicy.exponential(attempts=5, initial=1.0, max_wait=30.0)
RetryPolicy.linear(attempts=3, delay=2.0)
RetryPolicy.exponential(
attempts=3,
retry_on=(ConnectionError, TimeoutError, OSError),
)
RetryPolicy.exponential(attempts=5, initial=0.5, max_wait=30.0)
RetryPolicy.exponential(attempts=3, retry_on=(TimeoutError,))
RetryPolicy.linear(attempts=3, delay=2.0)
RetryPolicy.linear(
attempts=5,
delay=0.5,
retry_on=(ConnectionError, TimeoutError),
)
Normalize int | RetryPolicy into a RetryPolicy.
An int is treated as RetryPolicy.exponential(attempts=value).
The normalized policy.
Decorator that deploys a class as versioned remote functions.
Locally (at decoration time):
@method(), @before(), @after()ExternalFunctionCatalogServiceCHALK_FUNCTION_LOCAL_SDK_COPY=1, includes local SDK source in
the deploy image for unreleased feature iteration.Remotely (inside the container): The decorator is a no-op — returns an instance of the class.
Retry policy for handler invocations. Pass an int for simple
max-attempts with default exponential backoff, or a
RetryPolicy for full control.
A managed class backed by ExternalFunctionCatalogService.
Deploys each @method() as a separate function version with its own
scaling group, sharing a single container image. Lifecycle hooks
(@before() / @after()) run in every method's container.
Most users should prefer the cls decorator.
Deploy a stateful class with an expensive warm-up step, then call individual methods remotely:
import chalkcompute
from chalkcompute import Image
img = (
Image.debian_slim()
.pip_install(["sentence-transformers"])
)
@chalkcompute.cls(
image=img,
cpu="2",
memory="4Gi",
min_replicas=1,
max_replicas=2,
)
class Embedder:
@chalkcompute.before()
def load(self):
from sentence_transformers import SentenceTransformer
self.model = SentenceTransformer("all-MiniLM-L6-v2")
@chalkcompute.method()
def embed(self, text: str) -> list[float]:
return self.model.encode(text).tolist()
@chalkcompute.method()
def embed_batch(self, texts: list[str]) -> list[list[float]]:
return self.model.encode(texts).tolist()
@chalkcompute.after()
def shutdown(self):
del self.model
Embedder.deploy()
e = Embedder()
vec = e.embed("hello world")
batch = e.embed_batch(["a", "b", "c"])
Attach to an existing remote class by name.
Discovers all function versions whose functionName starts with
{name}. and rebuilds a RemoteClass with callable methods.
A handle bound to the existing versions.
If no function versions are found for the given name.
Fetch latest info for all methods from the server.
Mapping of method name to updated FunctionVersionInfo.
Managed scaling groups for deploying HTTP/gRPC services.
Orchestrates image building, local file upload, and scaling group
lifecycle. Use .call() to make HTTP requests to the deployed service.
A managed scaling group backed by ScalingGroupManagerService.
Orchestrates image building, local file upload via volumes, and scaling-group lifecycle in a single high-level API.
from chalkcompute import ScalingGroup, Image
img = (
Image.debian_slim()
.pip_install(["flask"])
.add_local_file("./app.py", "/app/app.py")
.entrypoint(["python", "/app/app.py"])
)
sg = ScalingGroup(image=img, port=8080).deploy().wait_ready()
resp = sg.call("/health", method="GET")
sg.delete()
Attach to an existing scaling group by ID.
A ScalingGroup handle bound to the existing resource.
If the scaling group cannot be found.
Attach to an existing scaling group by name.
A ScalingGroup handle bound to the existing resource.
If the scaling group cannot be found.
Metadata about a scaling group.
id
Opaque scaling-group identifier assigned by the service.
name
DNS-safe scaling-group name.
status
Lifecycle state reported by the service (e.g. "Running").
web_url
URL to which HTTP traffic should be sent, if ready.
ready_replicas
Number of replicas currently ready to serve traffic.
available_replicas
Number of replicas available behind the service endpoint.
References to secrets available to a sandbox, container, or remote function.
Use Secret.from_name(...) to reference a secret by name; the secret
value is resolved at runtime from the Chalk secret store and injected
as an environment variable.
A reference to a Chalk secret or integration to inject as env vars.
Construct instances via the factory methods rather than instantiating directly.
Secret.from_env("OPENAI_API_TOKEN")
Secret.from_integration("prod_postgres")
Secret.from_local_env("OPENAI_API_KEY")
Secret.from_local_env("OPENAI_API_KEY", env_var_name="API_KEY")
Secret.from_local_env_file(".env")
Inject a local environment variable as a secret into the container.
Reads os.environ[local_env_var] at container start time, upserts it
as a Chalk secret, and injects it as an env var in the container.
A lazy secret reference resolved at Container.run() time.
Inject all variables from a local .env file as secrets.
Reads the file at container start time, upserts each KEY=VALUE
pair as a Chalk secret, and injects them as env vars in the container.
Lines starting with # and blank lines are ignored.
A lazy secret reference resolved at Container.run() time.
A reference to a Chalk secret or integration to inject as env vars.
Construct instances via the factory methods rather than instantiating directly.
Secret.from_env("OPENAI_API_TOKEN")
Secret.from_integration("prod_postgres")
Secret.from_local_env("OPENAI_API_KEY")
Secret.from_local_env("OPENAI_API_KEY", env_var_name="API_KEY")
Secret.from_local_env_file(".env")
Inject a local environment variable as a secret into the container.
Reads os.environ[local_env_var] at container start time, upserts it
as a Chalk secret, and injects it as an env var in the container.
A lazy secret reference resolved at Container.run() time.
Inject all variables from a local .env file as secrets.
Reads the file at container start time, upserts each KEY=VALUE
pair as a Chalk secret, and injects them as env vars in the container.
Lines starting with # and blank lines are ignored.
A lazy secret reference resolved at Container.run() time.