API Reference
Sandbox Class​
The main class for creating and managing sandboxes.
Class Methods​
Sandbox.create()​
Creates a new sandbox instance.
@classmethod
def create(
variant: str = "datalayer",
timeout: float | None = None,
environment: str | None = None,
gpu: str | None = None,
cpu: float | None = None,
memory: int | None = None,
env: dict[str, str] | None = None,
tags: dict[str, str] | None = None,
name: str | None = None,
network_policy: str | None = None,
allowed_hosts: list[str] | None = None,
examples: list[tuple[str, str]] | None = None,
config: SandboxConfig | None = None,
**kwargs,
) -> Sandbox
Parameters:
| Parameter | Type | Description |
|---|---|---|
variant | str | Sandbox type: "cloudflare", "coreweave", "datalayer", "daytona", "docker", "e2b", "eval", "google-colab", "jupyter-server", "kaggle", "modal", or "monty". Defaults to "datalayer". |
timeout | float | Execution timeout in seconds |
environment | str | Runtime environment name |
gpu | str | GPU type (e.g., "T4", "A100", "H100") |
cpu | float | Number of CPU cores |
memory | int | Memory in MB |
env | dict | Environment variables |
tags | dict | Metadata tags |
name | str | Sandbox name |
network_policy | str | Network access policy: "inherit", "none", "allowlist", "all" |
allowed_hosts | list[str] | Hosts reachable when the policy is "allowlist" |
examples | list[tuple[str, str]] | (title, code) pairs the REPL lists under :examples |
config | SandboxConfig | Full configuration object |
**kwargs | dict | Variant-specific arguments handed to the sandbox constructor — template= (e2b), container_image= (coreweave), api_url= (cloudflare), snapshot_name= (datalayer), and the rest documented on each variant's page |
Sandbox.from_id()​
Reconnects to an existing sandbox.
@classmethod
def from_id(sandbox_id: str, **kwargs) -> Sandbox
Datalayer only — it reconnects to a Datalayer runtime whatever else is
running. **kwargs are that variant's: token=, run_url=.
Sandbox.list()​
Lists running sandboxes, as sandbox objects.
@classmethod
def list(tags: dict[str, str] | None = None, **kwargs) -> Iterator[Sandbox]
Datalayer only. For any other variant, ask its manager:
get_manager(variant).list(), which answers with list[SandboxInfo] — see
the CLI page.
Sandbox.list_environments()​
Lists available environments for a sandbox variant.
@classmethod
def list_environments(
variant: str = "datalayer",
**kwargs,
) -> list[SandboxEnvironment]
Parameters:
| Parameter | Type | Description |
|---|---|---|
variant | str | Sandbox type: "cloudflare", "coreweave", "datalayer", "daytona", "docker", "e2b", "eval", "google-colab", "jupyter-server", "kaggle", "modal", or "monty" |
**kwargs | dict | Variant-specific arguments (e.g., credentials, run URL) |
Legacy local-eval, local-docker, and local-jupyter variant names are not supported.
Instance Methods​
run_code()​
Executes Python code in the sandbox.
def run_code(
code: str,
language: str = "python",
context: Context | None = None,
on_stdout: Callable[[OutputMessage], None] | None = None,
on_stderr: Callable[[OutputMessage], None] | None = None,
on_result: Callable[[Result], None] | None = None,
on_error: Callable[[CodeError], None] | None = None,
envs: dict[str, str] | None = None,
timeout: float | None = None,
) -> ExecutionResult
run_code_streaming()​
Executes Python code and yields output/result/error events as they arrive.
def run_code_streaming(
code: str,
language: str = "python",
context: Context | None = None,
envs: dict[str, str] | None = None,
timeout: float | None = None,
) -> Iterator[OutputMessage | Result | CodeError]
run_code_streaming_async()​
Async version of run_code_streaming().
async def run_code_streaming_async(
code: str,
language: str = "python",
context: Context | None = None,
envs: dict[str, str] | None = None,
timeout: float | None = None,
) -> AsyncIterator[OutputMessage | Result | CodeError]
start()​
Starts the sandbox.
def start() -> None
stop()​
Stops the sandbox gracefully.
def stop() -> None
terminate() / kill()​
Datalayer only; both are aliases for stop(). Every other variant is stopped
with stop() — or by leaving its with block.
def terminate() -> None
def kill() -> None
set_timeout()​
Extends the life of a running sandbox. Only two variants offer it, and the argument is not spelled the same in both.
def set_timeout(timeout_seconds: float) -> None # datalayer
def set_timeout(seconds: float) -> None # e2b
Properties​
| Property | Type | Description |
|---|---|---|
sandbox_id | str | None | Unique sandbox identifier — None until start() has run |
files | SandboxFilesystem | Filesystem interface |
commands | SandboxCommands | Command execution interface |
tags | dict[str, str] | Metadata tags |
CodeSandboxClient​
CodeSandboxClient is a high-level, variant-agnostic facade over a sandbox.
It normalizes one-shot outcomes and streaming events across all variants.
Methods​
execute_code()​
def execute_code(
code: str,
language: str = "python",
timeout: float | None = None,
envs: dict[str, str] | None = None,
) -> CodeExecutionOutcome
execute_code_async()​
async def execute_code_async(
code: str,
language: str = "python",
timeout: float | None = None,
envs: dict[str, str] | None = None,
) -> CodeExecutionOutcome
execute_code_streaming()​
def execute_code_streaming(
code: str,
language: str = "python",
timeout: float | None = None,
envs: dict[str, str] | None = None,
) -> Iterator[OutputMessage | Result | CodeError]
execute_code_streaming_async()​
async def execute_code_streaming_async(
code: str,
language: str = "python",
timeout: float | None = None,
envs: dict[str, str] | None = None,
) -> AsyncIterator[OutputMessage | Result | CodeError]
Compatibility-free execution facade​
Consumers that need a Jupyter-shaped reply can stay on the sandbox client without accessing a variant's underlying kernel implementation:
reply = client.execute(code, timeout=60)
reply = client.execute_interactive(code, output_hook=handle_output)
The client also exposes variant-neutral lifecycle and variable operations:
client.start()
client.interrupt()
client.restart()
client.set_variable("name", value)
client.set_variables({"one": 1, "two": 2})
value = client.get_variable("name")
client.stop()
Properties​
| Property | Description |
|---|---|
id | Active backend identifier, including a remote kernel ID when applicable |
variant | Configured sandbox variant |
config | Variant-neutral sandbox configuration |
info | Runtime sandbox information after startup |
kernel_info | Language metadata without exposing the underlying kernel client |
is_started | Whether the sandbox has been started |
Outcome model​
CodeExecutionOutcome includes normalized fields such as:
successexecution_okstdoutstderrresultsexecution_errorcode_errorexit_codeinterrupted
Kaggle and Colab Clients​
Code Sandboxes owns the provider-specific clients used by its managed notebook
variants. They are exported from code_sandboxes:
from code_sandboxes import (
GoogleColabKernelClient,
KaggleExecutionResult,
KaggleKernelClient,
KaggleKernelExecutor,
parse_google_colab_channels_url,
parse_kaggle_channels_url,
)
KaggleKernelClientconnects to an interactive Kaggle notebook kernel.KaggleKernelExecutorsubmits and monitors Kaggle batch notebook jobs.KaggleExecutionResultnormalizes batch output into a Jupyter-like reply.GoogleColabKernelClientconnects to an already-running Google Colab kernel.- The parser helpers extract connection details from browser channels URLs.
See Kaggle and Google Colab for authentication and complete examples.
SandboxFilesystem​
File operations interface.
Methods​
read()​
def read(path: str) -> str
Reads file contents as a string.
read_bytes()​
def read_bytes(path: str) -> bytes
Reads file contents as bytes.
write()​
def write(path: str, content: str, make_dirs: bool = True) -> None
Writes text to a file, creating parent directories unless told not to.
write_bytes()​
def write_bytes(path: str, content: bytes, make_dirs: bool = True) -> None
Writes bytes to a file. write() handles text only.
list()​
def list(path: str = "/") -> list[FileInfo]
Lists directory contents.
mkdir()​
def mkdir(path: str, parents: bool = True) -> None
Creates a directory.
rm()​
def rm(path: str, recursive: bool = False) -> None
Removes a file or directory.
exists() / is_file() / is_dir()​
def exists(path: str) -> bool
def is_file(path: str) -> bool
def is_dir(path: str) -> bool
Asks about a path without reading it.
copy() / move()​
def copy(src: str, dst: str) -> None
def move(src: str, dst: str) -> None
get_info()​
def get_info(path: str) -> FileInfo
One entry's metadata, without listing its directory.
upload()​
def upload(local_path: str, remote_path: str) -> None
Uploads a local file to the sandbox.
download()​
def download(remote_path: str, local_path: str) -> None
Downloads a file from the sandbox.
FileInfo​
What list() and get_info() answer with.
@dataclass
class FileInfo:
name: str
path: str
type: FileType = FileType.FILE # FILE, DIRECTORY, SYMLINK
size: int = 0 # bytes, for files
modified: float = 0.0 # Unix timestamp
permissions: str = ""
# Convenience properties
@property
def is_file(self) -> bool: ...
@property
def is_directory(self) -> bool: ...
SandboxCommands​
Command execution interface.
Methods​
run()​
def run(
command: str,
cwd: str | None = None,
env: dict[str, str] | None = None,
timeout: float | None = None,
shell: bool = True,
) -> CommandResult
Runs a command and waits for completion.
exec()​
def exec(*args: str, **kwargs) -> ProcessHandle
Executes a command with streaming output.
spawn()​
def spawn(command: str, **kwargs) -> ProcessHandle
Starts a background process.
CommandResult​
@dataclass
class CommandResult:
exit_code: int = 0
stdout: str = ""
stderr: str = ""
duration: float = 0.0
@property
def success(self) -> bool: ... # exit_code == 0
ProcessHandle​
A process still running. stdout and stderr are iterators that yield as
output arrives.
@dataclass
class ProcessHandle:
command: str
pid: int | None = None
@property
def stdout(self) -> Iterator[str]: ...
@property
def stderr(self) -> Iterator[str]: ...
@property
def returncode(self) -> int | None: ...
def read_stdout(self) -> str: ...
def read_stderr(self) -> str: ...
def wait(self, timeout: float | None = None) -> int: ...
def poll(self) -> int | None: ...
def terminate(self) -> None: ...
def kill(self) -> None: ...
Data Models (Pydantic)​
ExecutionResult​
Complete result of a code execution with detailed status information.
class ExecutionResult(BaseModel):
# Results and logs
results: list[Result]
logs: Logs
# Execution-level (infrastructure) status
execution_ok: bool = True # Did sandbox infrastructure work?
execution_error: str | None = None # Infrastructure failure details
# Code-level (user code) status
code_error: CodeError | None = None # Python exception info
# Process exit status (sys.exit)
exit_code: int | None = None # Exit code if code calls sys.exit()
# Metadata
execution_count: int = 0
context_id: str | None = None
started_at: float | None = None
completed_at: float | None = None
interrupted: bool = False
# Properties
@property
def success(self) -> bool:
"""True if execution_ok and no code_error and not interrupted and exit_code is 0 or None"""
@property
def duration(self) -> float | None:
"""Execution duration in seconds"""
@property
def text(self) -> str | None:
"""Main text result"""
@property
def stdout(self) -> str:
"""All stdout as single string"""
@property
def stderr(self) -> str:
"""All stderr as single string"""
Usage:
result = sandbox.run_code("x = 1 + 1; print(x)")
# Check infrastructure success
if not result.execution_ok:
print(f"Sandbox failed: {result.execution_error}")
# Check explicit process exit
elif result.exit_code not in (None, 0):
print(f"Process exited with code: {result.exit_code}")
# Check code-level error
elif result.code_error:
print(f"Python error: {result.code_error.name}: {result.code_error.value}")
# Success!
else:
print(f"Result: {result.text}")
print(f"Duration: {result.duration:.2f}s")
# Or use convenience property
if result.success:
print("Everything worked!")
CodeError​
Error information when Python code raises an exception.
class CodeError(BaseModel):
name: str # Error class name (e.g., "ValueError")
value: str # Error message
traceback: str = "" # Full traceback
SandboxEnvironment​
class SandboxEnvironment(BaseModel):
name: str
title: str
language: str = "python"
owner: str = "local"
visibility: str = "local"
burning_rate: float = 0.0
metadata: dict[str, Any] | None = None
cpu: str | None = None
memory: str | None = None
gpu: str | None = None
gpu_count: int | None = None
gpu_memory: int | None = None
Result​
A single execution result with multiple representations.
class Result(BaseModel):
data: dict[str, Any] # MIME type to content mapping
is_main_result: bool = False
extra: dict[str, Any] # Additional metadata
# Convenience properties
@property
def text(self) -> str | None: ... # text/plain
@property
def html(self) -> str | None: ... # text/html
@property
def json(self) -> Any: ... # application/json
@property
def png(self) -> str | None: ... # image/png (base64)
@property
def jpeg(self) -> str | None: ... # image/jpeg (base64)
@property
def svg(self) -> str | None: ... # image/svg+xml
@property
def markdown(self) -> str | None: ... # text/markdown
OutputMessage​
class OutputMessage(BaseModel):
line: str
timestamp: float = 0.0
error: bool = False # True for stderr
Logs​
class Logs(BaseModel):
stdout: list[OutputMessage]
stderr: list[OutputMessage]
@property
def stdout_text(self) -> str: ... # All stdout as string
@property
def stderr_text(self) -> str: ... # All stderr as string
Context​
class Context(BaseModel):
id: str
language: str = "python"
cwd: str | None = None
env: dict[str, str]
SandboxConfig​
class SandboxConfig(BaseModel):
timeout: float = 30.0
memory_limit: int | None = None
cpu_limit: float | None = None
environment: str = "ai-agents-env"
working_dir: str | None = None
env_vars: dict[str, str]
gpu: str | None = None
name: str | None = None
network_policy: str = "inherit" # "inherit", "none", "allowlist", "all"
allowed_hosts: list[str]
idle_timeout: float | None = None
max_lifetime: float = 86400.0 # 24 hours
examples: list[tuple[str, str]] # (title, code) pairs for the REPL
SandboxInfo​
class SandboxInfo(BaseModel):
id: str
variant: str
status: SandboxStatus = SandboxStatus.RUNNING
created_at: float = 0.0
end_at: float | None = None
config: SandboxConfig | None = None
name: str | None = None
metadata: dict[str, Any]
resources: ResourceConfig | None = None
@property
def remaining_time(self) -> float | None: ... # Seconds until termination
SnapshotInfo​
What create_snapshot() and list_snapshots() answer with — datalayer only.
class SnapshotInfo(BaseModel):
id: str
name: str
sandbox_id: str
created_at: float = 0.0
size: int = 0
description: str = ""
JupyterServerOptions​
What prepare_jupyter_server() is asked for — see
Jupyter over Provider Ingress.
class JupyterServerOptions(BaseModel):
port: int = 8888
token: str | None = None # generated when omitted
install_if_missing: bool = True
install_timeout: float = 180.0
JupyterServerEndpoint​
What it answers with. headers authenticate the provider ingress and query
authenticates Jupyter itself; both are secrets, and both are kept out of the
repr.
class JupyterServerEndpoint(BaseModel):
port: int
http_url: str
websocket_url: str
headers: dict[str, str]
query: dict[str, str]
ResourceConfig​
class ResourceConfig(BaseModel):
cpu: float | None = None # CPU cores
memory: int | None = None # Memory in MB
gpu: str | None = None # GPU type ("T4", "A100", etc.)
gpu_count: int = 1 # Number of GPUs
disk: int | None = None # Disk in GB
Management API​
The verbs the CLI runs on, from Python. A manager exists per variant, and states what it can do rather than failing late.
from code_sandboxes import get_manager, manageable_variants
manageable_variants() # the variants a manager exists for
manager = get_manager("modal")
manager.capabilities # frozenset of the verbs this variant answers
manager.list() # list[SandboxInfo]
manager.get(sandbox_id) # SandboxInfo | None
manager.create(**kwargs) # SandboxInfo
manager.update(sandbox_id, **changes)
manager.delete(sandbox_id) # bool
A verb outside capabilities raises SandboxManagementError. See
the CLI page for what each variant
answers.
Provider Registry​
What a variant needs before it can run anything — credentials, and the extra that installs it. It reports what is present; it starts nothing and reads no secret's value.
from code_sandboxes import PROVIDERS, available_providers, get_provider
PROVIDERS # every provider declared
available_providers() # those whose credentials are on this machine
get_provider("daytona") # one, or None
Exceptions​
| Exception | Description |
|---|---|
SandboxError | Base exception for all sandbox errors |
SandboxTimeoutError | Execution timed out |
SandboxExecutionError | Code execution failed |
SandboxNotStartedError | The sandbox was used before start() |
SandboxConnectionError | Connection to sandbox failed |
SandboxConfigurationError | The variant cannot be used as configured — a missing extra, or a setting it refuses |
ContextNotFoundError | No such execution context |
VariableNotFoundError | No such variable in the context |
SandboxSnapshotError | Snapshot operation failed |
SandboxResourceError | Resource limit exceeded |
SandboxAuthenticationError | Authentication failed |
SandboxQuotaExceededError | Usage quota exceeded |