cwsandbox Python SDK to launch and manage sandboxes.
Overview
You can set sandbox configuration in three places, listed from broadest to most specific scope:- SandboxDefaults: Shared defaults for all sandboxes in a session.
- Sandbox.run() kwargs: Per-sandbox overrides.
- @session.function() kwargs: Function-specific configuration.
Resources
Configure CPU, memory, and GPU resources using theResourceOptions dataclass or a plain dict. Serverless is the default placement mode and uses equal requests and limits. For unequal requests and limits, use CKS placement with a runner whose policy permits them.
The following examples use equal requests and limits:
ResourceOptions internally.
ResourceOptions separates resource requests from limits. Requests tell the scheduler what the sandbox needs. Limits set the maximum it can use. For background on how Kubernetes uses requests and limits to assign Quality of Service classes, see the Kubernetes documentation.
ResourceOptions fields
All fields are optional in the client and default to
None. The resolved allocation must satisfy the applicable policy. If you omit the resource allocation, complete, positive CPU and memory defaults from that policy supply both requests and limits.
Guaranteed QoS
When requests equal limits, the sandbox receives a Guaranteed Quality of Service class. This reserves exact resources and prevents throttling. Use this for latency-sensitive workloads.Burstable QoS
On a CKS runner whose policy permits unequal requests and limits, lower requests give the sandbox a Burstable Quality of Service class. Lower requests let the scheduler bin-pack more sandboxes, but each sandbox can burst up to its limit if capacity is available. Complete Use your own compute and setCWSANDBOX_API_KEY to a CoreWeave API access token. Replace [RUNNER-ID] with the ID of a CKS runner whose policy permits these requests and limits:
CPU values
Specify CPU in millicores or whole cores. For details, see Resource units in Kubernetes.Memory values
Memory uses standard Kubernetes memory units:GPU
Request GPU resources alongside CPU and memory. A GPU request reserves GPUs only, so set CPU and memory explicitly.type and memory_gb are alternatives. Set at most one of them.
Inspect confirmed resources
After a sandbox starts, inspect the confirmed resource allocation. This example uses unequal requests and limits on CKS. Complete the CKS setup and setCWSANDBOX_API_KEY to a CoreWeave API access token. Replace [RUNNER-ID] with the ID of a CKS runner that has GPU capacity and a policy that permits these resources:
Configuration library interop
All configuration types (NetworkOptions, Secret, ResourceOptions) accept either the dataclass or a plain dict. This means ML configuration libraries that resolve configs to dicts or dict-like objects can pass values directly to the SDK without manual conversion.
SandboxDefaults.from_dict() accepts a plain dict or an OmegaConf DictConfig and coerces nested fields automatically. Dicts become NetworkOptions, Secret, or ResourceOptions as needed, and lists become tuples.
Sandbox.run() or session.sandbox(). The nested dict form for resources maps to ResourceOptions fields. The flat dict form ({"cpu": "1", "memory": "1Gi"}) is also accepted and treated as Guaranteed QoS.
Mounted files
Mounted files let you provide configuration files, scripts, or other read-only assets to the sandbox at startup, without baking them into a container image.Mount options
Mounted files are read-only. Use
write_file() for files that require modification.
Ports
Expose ports so processes inside the sandbox can serve traffic to outside clients:Port configuration
To give a port an internet-reachable address with platform TLS or TLS passthrough, see Public endpoints.
Network
Configure network options using theNetworkOptions dataclass or a plain dict:
NetworkOptions internally.
NetworkOptions fields
All fields are optional and default to
None, which uses backend defaults.
Set network in SandboxDefaults
Set a default network configuration for all sandboxes:Annotations
Add Kubernetes pod annotations to sandboxes. Annotations are key-value string pairs attached to the underlying pod, useful for integrations that read pod metadata, such as schedulers, cost-allocation tools, or external automation.Session-level defaults
Set default annotations for all sandboxes in a session:Merge behavior
When you provide bothSandboxDefaults.annotations and per-sandbox annotations, the SDK merges them. Explicit per-sandbox values win on key collision, matching the same semantics as environment_variables.
SUNK integration
To pass Slurm context as pod annotations for SUNK integration, see the SUNK Pod Scheduler integration guide.Validation
The SDK does not validate annotation keys or values. The server handles validation of reserved key prefixes, value format, and maximum entry count.Secrets
For W&B team secret injection, authentication requirements, and Python and TypeScript examples, see Use W&B secrets.Timeouts
Four settings control how long a sandbox and its operations run. The names are similar, so the following table maps each one to what it bounds.
Only
max_lifetime_seconds terminates a sandbox. The other three bound individual requests and leave the sandbox running.
max_lifetime_seconds
max_lifetime_seconds sets the total wall-clock lifetime of a sandbox. When a sandbox reaches this age, the platform terminates it even if work is still in progress.
If you don’t set max_lifetime_seconds, the runner-policy default applies. If no positive policy default supplies a lifetime, the platform uses 10 minutes. Set the value explicitly for long-running work:
SandboxDefaults:
max_lifetime_seconds argument on Sandbox.run() takes precedence over the value in defaults. Because the argument’s default is None, you can’t use it to remove a lifetime that defaults already sets.
The longest lifetime you can request is 30 days (2,592,000 seconds), for both Serverless and CKS placement. The platform rejects larger requests.
For creation examples and CKS runner-policy defaults, see Run long-running sandboxes.
Behavior when the lifetime expires
The platform enforces the lifetime by terminating the sandbox’s underlying Kubernetes Job, so termination is immediate rather than graceful. Two consequences matter in practice:- Processes inside the sandbox don’t receive the grace period that
stop()provides. Anything not already written out is lost. - The client doesn’t receive a distinct error or reason for the termination. The SDK reports no termination reason on a
Sandbox, so you can’t distinguish lifetime expiry from other failures programmatically. Track the age of long-lived sandboxes yourself.
timeout_seconds
timeout_seconds bounds a single operation on a running sandbox:
SandboxTimeoutError. The sandbox keeps running. The clock starts only after the sandbox reaches RUNNING, so startup time doesn’t count against it.
Keep timeout_seconds below the sandbox’s max_lifetime_seconds. A command whose timeout exceeds the sandbox’s remaining lifetime stops when the sandbox terminates.
max_timeout_seconds
max_timeout_seconds bounds how long the server waits to place a sandbox on a runner before the attempt fails. It’s a server-side placement budget, not a client read timeout, and it doesn’t affect how long the sandbox runs afterward:
max_timeout_seconds is available on Sandbox.run() and session.sandbox(), but not on SandboxDefaults.
request_timeout_seconds
request_timeout_seconds is the client-side HTTP timeout applied to most RPCs, and it’s the fallback when a call doesn’t pass its own timeout_seconds. Set it in SandboxDefaults:
poll_rpc_timeout_seconds instead, so a stalled poll fails fast rather than blocking for the full request timeout. For the full set of client-side tuning options, see the SandboxDefaults reference.