Skip to main content

Python SDK for Sandforge hypervisor sandbox platform

Project description

Sandforge Python SDK

The Sandforge Python SDK provides a client library for interacting with the Sandforge hypervisor sandbox platform. It enables you to create, manage, and execute commands in isolated sandboxes programmatically.

Installation

Install the SDK from the repository:

pip install -e .

Or with development dependencies:

pip install -e ".[dev]"

Quick Start

Basic Usage

from sandforge import Client, SandboxSpec

# Create a client pointing to your Sandforge control plane
client = Client("http://localhost:8080")

# Create a sandbox with default configuration
sandbox = client.create_sandbox()

# Run a command
result = sandbox.commands.run(["echo", "Hello, Sandforge!"])
print(result.stdout)  # "Hello, Sandforge!\n"

# Clean up
sandbox.kill()

Custom Sandbox Configuration

from sandforge import Client, SandboxSpec, WorkspaceMount

spec = SandboxSpec(
    cpu=4,
    memory_mb=2048,
    disk_gb=20,
    timeout_sec=3600,
    network_mode="fetch",  # Allow package downloads
    mounts=[
        WorkspaceMount(
            host_path="/path/to/project",
            guest_path="/workspace",
            read_only=False,
        ),
    ],
)

client = Client("http://localhost:8080")
sandbox = client.create_sandbox(spec)

# Work with the mounted directory
result = sandbox.commands.run(["ls", "-la", "/workspace"])
print(result.stdout)

sandbox.kill()

Command Execution with Environment Variables

from sandforge import Client

client = Client("http://localhost:8080")
sandbox = client.create_sandbox()

# Run with custom environment variables
result = sandbox.commands.run(
    command=["python", "-c", "import os; print(os.environ.get('MY_VAR'))"],
    cwd="/",
    env={"MY_VAR": "Hello World"},
    timeout_sec=30,
)

print(result.stdout)   # "Hello World\n"
print(result.exit_code)  # 0

sandbox.kill()

Error Handling

from sandforge import Client, NetworkError, SandboxNotFoundError

client = Client("http://localhost:8080")

try:
    sandbox = client.create_sandbox()
    result = sandbox.commands.run(["false"])  # Command that fails
    
    if result.exit_code != 0:
        print(f"Command failed with exit code {result.exit_code}")
        print(f"stderr: {result.stderr}")
    
    sandbox.kill()
    
except NetworkError as e:
    print(f"Connection error: {e}")
except SandboxNotFoundError as e:
    print(f"Sandbox not found: {e}")

Sandbox Information

from sandforge import Client

client = Client("http://localhost:8080")
sandbox = client.create_sandbox()

# Get sandbox information
info = sandbox.info()
print(f"Sandbox ID: {info.id}")
print(f"State: {info.state}")  # "ready", "executing", "destroyed", etc.

API Reference

Client

The main entry point for interacting with Sandforge.

Constructor

Client(base_url: str, timeout: int = 60)
  • base_url: The control plane URL (e.g., "http://localhost:8080")
  • timeout: Request timeout in seconds (default: 60)

Methods

create_sandbox(spec: Optional[SandboxSpec] = None) -> SandboxHandle

Create a new sandbox.

  • Returns: A SandboxHandle to the created sandbox
  • Raises: NetworkError or SandforgeException
exec(sandbox_id: str, request: ExecRequest) -> ExecResult

Execute a command in a sandbox.

  • Returns: An ExecResult with exit code, stdout, and stderr
  • Raises: NetworkError or SandforgeException
get_status(sandbox_id: str) -> str

Get the current state of a sandbox.

  • Returns: The sandbox state as a string
  • Raises: NetworkError
get_info(sandbox_id: str) -> SandboxInfo

Get detailed information about a sandbox.

  • Returns: A SandboxInfo object
  • Raises: NetworkError
destroy(sandbox_id: str) -> None

Destroy a sandbox.

  • Raises: NetworkError or SandforgeException

SandboxHandle

A handle to a created sandbox with convenience APIs.

Properties

  • id: The sandbox ID (string)

Methods

kill() -> None

Destroy the sandbox.

sandbox.kill()
info() -> SandboxInfo

Get sandbox information.

info = sandbox.info()

Nested APIs

commands

The CommandsAPI for executing commands.

run(command, cwd="/", env=None, timeout_sec=60) -> ExecResult

Run a command in the sandbox.

  • command: List of command and arguments
  • cwd: Working directory (default: "/")
  • env: Dictionary of environment variables (default: {})
  • timeout_sec: Command timeout in seconds (default: 60)
  • Returns: ExecResult with exit code, stdout, and stderr
result = sandbox.commands.run(
    ["python", "script.py"],
    cwd="/workspace",
    env={"PYTHONUNBUFFERED": "1"},
    timeout_sec=300,
)
files

The FilesAPI for reading files from the sandbox.

read(path: str) -> str

Read a file from the sandbox.

Note: This method is currently not implemented and raises NotImplementedError. VSOCK copyout support is coming soon.

try:
    content = sandbox.files.read("/etc/hostname")
except NotImplementedError:
    print("files.read() not yet supported")

Types

SandboxSpec

Specification for creating a sandbox.

SandboxSpec(
    backend: str = "macos-vz",        # "linux-kvm", "linux-firecracker", "macos-vz"
    cpu: int = 2,                      # Number of vCPUs
    memory_mb: int = 512,              # Memory in MB
    disk_gb: int = 10,                 # Disk size in GB
    timeout_sec: int = 3600,           # Sandbox lifetime in seconds
    network_mode: str = "offline",     # "offline", "fetch", "full"
    task_isolation: str = "container", # "container", "process"
    mounts: List[WorkspaceMount] = [], # Mounted directories
)

WorkspaceMount

A directory mount from host to guest.

WorkspaceMount(
    host_path: str,   # Path on the host
    guest_path: str,  # Path in the sandbox
    read_only: bool = False,  # Whether the mount is read-only
)

ExecRequest

A request to execute a command.

ExecRequest(
    command: List[str],              # Command and arguments
    cwd: str = "/",                  # Working directory
    env: Dict[str, str] = {},        # Environment variables
    timeout_sec: int = 60,           # Timeout in seconds
)

ExecResult

The result of command execution.

ExecResult(
    exit_code: int,              # Command exit code
    stdout: str,                 # Standard output
    stderr: str,                 # Standard error
    artifacts: List[str] = [],   # Paths to generated artifacts
)

SandboxInfo

Information about a sandbox.

SandboxInfo(
    id: str,     # Sandbox ID
    state: str,  # Current state (e.g., "ready", "executing", "destroyed")
)

Exceptions

All exceptions inherit from SandforgeException.

  • SandforgeException: Base exception for all Sandforge errors
  • NetworkError: Network communication error with the control plane
  • SandboxNotFoundError: Sandbox does not exist
  • ExecutionError: Command execution failed
  • InvalidSpecError: Invalid sandbox specification

Error Handling

The SDK provides specific exception types for different error scenarios:

from sandforge import Client, NetworkError, SandboxNotFoundError, SandforgeException

client = Client("http://localhost:8080")

try:
    sandbox = client.create_sandbox()
    result = sandbox.commands.run(["exit", "1"])
except NetworkError as e:
    print(f"Network error: {e}")
except SandboxNotFoundError as e:
    print(f"Sandbox not found: {e}")
except SandforgeException as e:
    print(f"Sandforge error: {e}")

Running Tests

pip install -e ".[dev]"
pytest tests/

Contributing

Contributions are welcome! Please ensure code passes linting and type checks:

black sandforge/
flake8 sandforge/
mypy sandforge/

License

Apache License 2.0. See LICENSE in the repository root for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sandforge_sdk-0.1.1.tar.gz (13.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sandforge_sdk-0.1.1-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file sandforge_sdk-0.1.1.tar.gz.

File metadata

  • Download URL: sandforge_sdk-0.1.1.tar.gz
  • Upload date:
  • Size: 13.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sandforge_sdk-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e109627090e35643518678f1502ca42b187e9b17a6cdbe812431536c51fa1a84
MD5 a52fb9ea3f17fe1a1611b1370badeb94
BLAKE2b-256 fc77a284ec2d55a1f53d57429ad276cf9217b3af4ee6c7f7c5bf7d4c456bdf7c

See more details on using hashes here.

File details

Details for the file sandforge_sdk-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: sandforge_sdk-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sandforge_sdk-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a5b1f3eed9e0398623f401f4463d888d035d2dadab74fe07fb78038058e5845b
MD5 d7ff6b8581140c707661b3451c3fcce3
BLAKE2b-256 5b3d043b7c48aa36719528b1f73eceb2febeed1a3f8114da05a7a5086d795f7f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page