Skip to content

datalayer/code-sandboxes

Repository files navigation

Datalayer

Become a Sponsor

{ } Code Sandboxes

PyPI - Version

Code Sandboxes code_sandboxes is a Python package for safe, isolated environments where an AI system can write, run, and test code without affecting the real world or the user's device.

This package provides a unified API for code execution with features like:

  • Code Execution: Execute Python code with streaming output and rich results
  • Filesystem Operations: Read, write, list, upload, and download files
  • Command Execution: Run shell commands with streaming support
  • Context Management: Maintain state across multiple executions
  • Snapshots: Save and restore sandbox state (Datalayer runtime)
  • GPU Support: Access GPU compute for ML workloads (Datalayer runtime)

Sandbox Variants

Four variants are available:

Canonical variant names are eval, docker, jupyter, and datalayer. The older local-* names are no longer supported.

Variant Isolation Use Case
eval None (Python exec) Development, testing
docker Container (Jupyter Server) isolated execution
jupyter Process (Jupyter kernel) persistent state
datalayer Cloud VM Production, GPU workloads

Module Layout

Sandbox implementations are exposed as top-level modules:

  • code_sandboxes.eval_sandbox
  • code_sandboxes.jupyter_sandbox
  • code_sandboxes.docker_sandbox
  • code_sandboxes.datalayer_sandbox

Example direct imports:

from code_sandboxes.eval_sandbox import EvalSandbox
from code_sandboxes.jupyter_sandbox import JupyterSandbox
from code_sandboxes.docker_sandbox import DockerSandbox
from code_sandboxes.datalayer_sandbox import DatalayerSandbox

Installation

# Basic installation
pip install code-sandboxes

# With Datalayer runtime support
pip install code-sandboxes[datalayer]

# With Docker support
pip install code-sandboxes[docker]

# All features
pip install code-sandboxes[all]

Docker Variant Setup

The docker variant runs a Jupyter Server inside a Docker container and uses jupyter-kernel-client to execute code.

Build the Docker image used by DockerSandbox:

docker build -t code-sandboxes-jupyter:latest -f docker/Dockerfile .

Quick Start

Simple Code Execution

from code_sandboxes import Sandbox

# Create a sandbox with timeout
with Sandbox.create(variant="eval", timeout=60) as sandbox:
    # Execute code
    result = sandbox.run_code("x = 1 + 1")
    result = sandbox.run_code("print(x)")  # prints 2

    # Multi-statement blocks return the last expression
    result = sandbox.run_code("""
x = 10
x * 2
""")
    print(result.text)  # "20"

    # Access results
    print(result.stdout)  # "2"

Cloud Execution with GPU

from code_sandboxes import Sandbox

# Create a cloud sandbox with GPU
with Sandbox.create(
    variant="datalayer",
    gpu="T4",
    environment="python-gpu-env",
    timeout=300,
) as sandbox:
    sandbox.run_code("import torch")
    result = sandbox.run_code("print(torch.cuda.is_available())")

Filesystem Operations

with Sandbox.create() as sandbox:
    # Write files
    sandbox.files.write("/data/test.txt", "Hello World")

    # Read files
    content = sandbox.files.read("/data/test.txt")

    # List directory
    for f in sandbox.files.list("/data"):
        print(f.name, f.size)

    # Upload/download
    sandbox.files.upload("local_file.txt", "/remote/file.txt")
    sandbox.files.download("/remote/file.txt", "downloaded.txt")

Command Execution

with Sandbox.create() as sandbox:
    # Run a command and wait for completion
    result = sandbox.commands.run("ls -la")
    print(result.stdout)

    # Execute with streaming output
    process = sandbox.commands.exec("python", "-c", "print('hello')")
    for line in process.stdout:
        print(line, end="")

    # Install system packages
    sandbox.commands.install_system_packages(["curl", "wget"])

Snapshots (Datalayer Runtime)

with Sandbox.create(variant="datalayer") as sandbox:
    # Set up environment
    sandbox.install_packages(["pandas", "numpy"])
    sandbox.run_code("import pandas as pd; df = pd.DataFrame({'a': [1,2,3]})")

    # Create snapshot
    snapshot = sandbox.create_snapshot("my-setup")
    print(f"Snapshot created: {snapshot.id}")

# Later: restore from snapshot
with Sandbox.create(variant="datalayer", snapshot_name="my-setup") as sandbox:
    # State is restored
    result = sandbox.run_code("print(df)")

Streaming Output

from code_sandboxes import Sandbox, OutputMessage

def handle_stdout(msg: OutputMessage):
    print(f"[stdout] {msg.line}")

def handle_stderr(msg: OutputMessage):
    print(f"[stderr] {msg.line}")

with Sandbox.create() as sandbox:
    result = sandbox.run_code(
        "for i in range(5): print(f'Step {i}')",
        on_stdout=handle_stdout,
        on_stderr=handle_stderr,
    )

API Reference

Sandbox.create()

Factory method to create sandboxes:

sandbox = Sandbox.create(
    variant="datalayer",  # Sandbox type
    timeout=60,                   # Execution timeout (seconds)
    environment="python-cpu-env",  # Runtime environment
    gpu="T4",                     # GPU type (T4, A100, H100, etc.)
    cpu=2.0,                      # CPU cores
    memory=4096,                  # Memory in MB
    env={"MY_VAR": "value"},      # Environment variables
    network_policy="none",        # Network access policy
    allowed_hosts=["localhost"],   # Allowlist when policy is allowlist
    tags={"project": "demo"},     # Metadata tags
)

# Network policies:
# - inherit: default behavior for the sandbox variant
# - none: block all outbound connections
# - allowlist: allow only hosts in allowed_hosts
# - all: allow all outbound connections

Execution Result

result = sandbox.run_code("print('hello')")

result.success    # bool: Whether execution succeeded
result.stdout     # str: Standard output
result.stderr     # str: Standard error
result.text       # str: Main result text
result.results    # list[Result]: Rich results (HTML, images, etc.)
result.code_error # CodeError: Error details if failed
result.execution_ok     # bool: Infrastructure execution status
result.execution_error  # str | None: Infrastructure error details
result.exit_code        # int | None: Exit code if code called sys.exit()

# Error handling
if not result.execution_ok:
    print(f"Sandbox failed: {result.execution_error}")
elif result.exit_code not in (None, 0):
    print(f"Process exited with code: {result.exit_code}")
elif result.code_error:
    print(f"Python error: {result.code_error.name}: {result.code_error.value}")
else:
    print(result.text)

Core Methods

Method Description
Sandbox.create() Create a new sandbox
Sandbox.from_id(id) Reconnect to an existing sandbox
Sandbox.list() List all sandboxes
sandbox.run_code(code) Execute Python code
sandbox.files.read(path) Read file contents
sandbox.files.write(path, content) Write file contents
sandbox.files.list(path) List directory contents
sandbox.commands.run(cmd) Run shell command
sandbox.commands.exec(*args) Execute with streaming output
sandbox.set_timeout(seconds) Update timeout
sandbox.create_snapshot(name) Save sandbox state
sandbox.terminate() / sandbox.kill() Stop sandbox

Configuration

Environment Variables

  • DATALAYER_API_KEY: API key for Datalayer runtime authentication

SandboxConfig

from code_sandboxes import SandboxConfig

config = SandboxConfig(
    timeout=30.0,              # Default execution timeout
    environment="python-cpu-env",
    memory_limit=4 * 1024**3,  # 4GB
    cpu_limit=2.0,
    gpu="T4",
    working_dir="/workspace",
    env_vars={"DEBUG": "1"},
    max_lifetime=3600,         # 1 hour
)

sandbox = Sandbox.create(config=config)

CI Workflows

This repository uses a reusable GitHub Actions workflow at .github/workflows/reusable-python.yml.

The following workflows call it:

  • .github/workflows/build.yml
  • .github/workflows/py-tests.yml
  • .github/workflows/py-code-style.yml
  • .github/workflows/py-typing.yml

Reusable workflow inputs:

  • python-version: Python version to run.
  • install-system-deps: Install Linux dependencies and unlock keyring.
  • install-extras: Extras from pyproject.toml (for example test,typing).
  • extra-packages: Additional packages installed with uv pip install.
  • run-tests: Enable test execution.
  • test-command: Command used for tests.
  • run-mypy: Enable mypy.
  • mypy-target: Package or module passed to mypy.
  • run-pre-commit: Enable pre-commit checks.

License

Copyright (c) 2025-2026 Datalayer, Inc.

BSD 3-Clause License

Sponsor this project

 

Contributors

Languages