Skip to main content

Python SDK for AgentFense - A sandbox infrastructure service for AI Agents with fine-grained file permission control

Project description

AgentFense SDK for Python

Python client library for the AgentFense service - a sandbox infrastructure for AI Agents with fine-grained file permission control.

Compatibility note: package/import names remain sandbox-rls / sandbox_rls for now.

Installation

pip install sandbox-rls

Or install from source:

cd sdk/python
pip install -e .

Quick Start (High-Level API)

The easiest way to use the SDK is with the high-level Sandbox class:

from sandbox_rls import Sandbox

# One-liner to create a sandbox from a local directory
with Sandbox.from_local("./my-project") as sandbox:
    result = sandbox.run("python main.py")
    print(result.stdout)

This automatically:

  1. Creates a codebase
  2. Uploads all files from the directory
  3. Creates a sandbox with the "agent-safe" preset
  4. Starts the sandbox
  5. Cleans up everything when done

Using Docker Runtime with Resource Limits

from sandbox_rls import Sandbox, RuntimeType, ResourceLimits

with Sandbox.from_local(
    "./my-project",
    preset="agent-safe",
    runtime=RuntimeType.DOCKER,
    image="python:3.11-slim",
    resources=ResourceLimits(
        memory_bytes=512 * 1024 * 1024,  # 512 MB
        pids_limit=100,
    ),
) as sandbox:
    # Use a session for stateful commands
    with sandbox.session() as session:
        session.exec("cd /workspace")
        session.exec("pip install -r requirements.txt")
        result = session.exec("pytest")
        print(result.stdout)

Permission Presets

The SDK includes several built-in permission presets:

Preset Description
agent-safe Read all files, write to /output and /tmp, hide secrets (.env, *.key, etc.)
read-only Read all files, no write access
full-access Full read/write access to all files
development Full access except secrets
view-only Can see file names but not read content
from sandbox_rls import list_presets, get_preset, extend_preset

# List all available presets
print(list_presets())  # ['agent-safe', 'development', 'full-access', 'read-only', 'view-only']

# Extend a preset with custom rules
rules = extend_preset(
    "agent-safe",
    additions=[{"pattern": "/custom/**", "permission": "write"}],
)

Error Handling

The SDK provides semantic exception classes:

from sandbox_rls import Sandbox, SandboxError, CommandTimeoutError, CommandExecutionError

try:
    with Sandbox.from_local("./my-project") as sandbox:
        result = sandbox.run("python main.py", timeout=30, raise_on_error=True)
except CommandTimeoutError as e:
    print(f"Command timed out: {e}")
except CommandExecutionError as e:
    print(f"Command failed with exit code {e.exit_code}: {e.stderr}")
except SandboxError as e:
    print(f"Sandbox error: {e}")

Low-Level API

For fine-grained control, use the SandboxClient directly:

from sandbox_rls import SandboxClient, RuntimeType, ResourceLimits

# Connect to the sandbox server
client = SandboxClient(endpoint="localhost:9000")

# Create a codebase (file storage)
codebase = client.create_codebase(name="my-project", owner_id="user_123")

# Upload a file
client.upload_file(codebase.id, "hello.py", b'print("Hello, World!")')

# Create a sandbox with permissions and Docker runtime
sandbox = client.create_sandbox(
    codebase_id=codebase.id,
    permissions=[
        {"pattern": "**/*.py", "permission": "read"},
        {"pattern": "/docs/**", "permission": "write"},
    ],
    runtime=RuntimeType.DOCKER,
    image="python:3.11-slim",
    resources=ResourceLimits(memory_bytes=256 * 1024 * 1024),
)

# Start the sandbox
client.start_sandbox(sandbox.id)

# Execute a command
result = client.exec(sandbox.id, command="python hello.py")
print(result.stdout)  # Output: Hello, World!

# Clean up
client.destroy_sandbox(sandbox.id)
client.delete_codebase(codebase.id)

Features

Permission Levels

The SDK supports four permission levels:

Level Description
none Completely invisible, not shown in ls
view Visible in ls, but cannot read content
read Can read file content
write Can modify file

Permission Patterns

You can use glob patterns, directory paths, or file paths:

from sandbox_rls import PermissionRule, Permission, PatternType

permissions = [
    # Glob pattern - matches all .py files
    PermissionRule(pattern="**/*.py", permission=Permission.READ),
    
    # Directory - applies to entire directory
    PermissionRule(pattern="/docs/", permission=Permission.WRITE, type=PatternType.DIRECTORY),
    
    # Specific file
    PermissionRule(pattern="/config.yaml", permission=Permission.VIEW, type=PatternType.FILE),
]

sandbox = client.create_sandbox(codebase_id=codebase.id, permissions=permissions)

Stateful Sessions

Sessions maintain a persistent shell process that preserves working directory and environment variables:

with client.session(sandbox.id) as session:
    session.exec("cd /workspace/src")     # Change directory
    session.exec("export DEBUG=1")         # Set environment variable
    session.exec("source venv/bin/activate")  # Activate virtualenv
    result = session.exec("python main.py")   # All above state is preserved

Command Execution

Execute commands with optional stdin, environment variables, and timeout:

from datetime import timedelta

result = client.exec(
    sandbox_id=sandbox.id,
    command="python script.py",
    stdin="input data",
    env={"DEBUG": "1"},
    workdir="/workspace/src",
    timeout=timedelta(seconds=30),
)

print(f"Exit code: {result.exit_code}")
print(f"stdout: {result.stdout}")
print(f"stderr: {result.stderr}")
print(f"Duration: {result.duration}")

Streaming Output

For long-running commands, use streaming:

for chunk in client.exec_stream(sandbox.id, command="long-running-task"):
    print(chunk.decode(), end="")

File Operations

# List files
files = client.list_files(codebase.id, path="/src", recursive=True)
for f in files:
    print(f"{f.path} - {f.size} bytes")

# Download a file
content = client.download_file(codebase.id, "config.yaml")
print(content.decode())

# Upload a file
result = client.upload_file(codebase.id, "new_file.txt", b"file content")
print(f"Uploaded {result.size} bytes, checksum: {result.checksum}")

Context Manager

Both the high-level Sandbox and low-level SandboxClient support context managers:

# High-level (recommended)
with Sandbox.from_local("./project") as sandbox:
    sandbox.run("make test")
# Automatically cleans up sandbox and codebase

# Low-level
with SandboxClient(endpoint="localhost:9000") as client:
    sandbox = client.create_sandbox(codebase_id="cb_123")
    # ... use the sandbox ...
# Connection is automatically closed

API Reference

High-Level API

Sandbox Class

  • Sandbox.from_local(path, preset, permissions, runtime, image, resources, ...) - Create sandbox from local directory
  • Sandbox.from_codebase(codebase_id, preset, ...) - Create sandbox from existing codebase
  • Sandbox.connect(sandbox_id) - Connect to existing sandbox
  • sandbox.run(command, timeout, env, workdir, raise_on_error) - Execute command (simplified)
  • sandbox.exec(command, stdin, env, workdir, timeout) - Execute command (full API)
  • sandbox.session(shell, env) - Create stateful session
  • sandbox.read_file(path) - Read file as string
  • sandbox.write_file(path, content) - Write file
  • sandbox.list_files(path, recursive) - List files
  • sandbox.start() / sandbox.stop() - Lifecycle control
  • sandbox.destroy(delete_codebase) - Clean up

Presets

  • get_preset(name) - Get preset as PermissionRule list
  • get_preset_dicts(name) - Get preset as dict list
  • extend_preset(base, additions, overrides) - Extend preset
  • list_presets() - List available presets
  • register_preset(name, rules) - Register custom preset

Low-Level API

SandboxClient

  • create_sandbox(codebase_id, permissions, runtime, image, resources, labels, expires_in) - Create sandbox
  • get_sandbox(sandbox_id) - Get sandbox info
  • list_sandboxes(codebase_id) - List sandboxes
  • start_sandbox(sandbox_id) - Start sandbox
  • stop_sandbox(sandbox_id) - Stop sandbox
  • destroy_sandbox(sandbox_id) - Destroy sandbox
  • exec(sandbox_id, command, stdin, env, workdir, timeout) - Execute command
  • exec_stream(sandbox_id, command, ...) - Execute with streaming
  • create_session(sandbox_id, shell, env) - Create session
  • session_exec(session_id, command, timeout) - Execute in session
  • create_codebase(name, owner_id) - Create codebase
  • get_codebase(codebase_id) - Get codebase info
  • list_codebases(owner_id) - List codebases
  • delete_codebase(codebase_id) - Delete codebase
  • upload_file(codebase_id, file_path, content) - Upload file
  • download_file(codebase_id, file_path) - Download file
  • list_files(codebase_id, path, recursive) - List files

Types

  • RuntimeType - BWRAP, DOCKER
  • ResourceLimits - memory_bytes, cpu_quota, cpu_shares, pids_limit
  • Permission - NONE, VIEW, READ, WRITE
  • PatternType - GLOB, DIRECTORY, FILE
  • SandboxStatus - PENDING, RUNNING, STOPPED, ERROR
  • SessionStatus - UNKNOWN, ACTIVE, CLOSED

Exceptions

  • SandboxError - Base exception
  • SandboxNotFoundError - Sandbox not found
  • SandboxNotRunningError - Sandbox not running
  • CodebaseError - Codebase operation error
  • CodebaseNotFoundError - Codebase not found
  • CommandTimeoutError - Command timed out
  • CommandExecutionError - Command failed (non-zero exit)
  • PermissionDeniedError - Permission denied
  • SessionError - Session operation error
  • ConnectionError - Connection to service failed

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black sandbox_rls tests
ruff check --fix sandbox_rls tests

# Type check
mypy sandbox_rls

License

MIT

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

sandbox_rls-0.2.0.tar.gz (54.0 kB view details)

Uploaded Source

Built Distribution

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

sandbox_rls-0.2.0-py3-none-any.whl (53.0 kB view details)

Uploaded Python 3

File details

Details for the file sandbox_rls-0.2.0.tar.gz.

File metadata

  • Download URL: sandbox_rls-0.2.0.tar.gz
  • Upload date:
  • Size: 54.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for sandbox_rls-0.2.0.tar.gz
Algorithm Hash digest
SHA256 516dad1be3cb129dc7eb908f4651f5010fe7caa0a3a42632d55bbba961147d20
MD5 2d6467512d5ac7562fed89f1ace5e772
BLAKE2b-256 b3a4e43ab12aa1a32f229b29fee29029efd9551d776f76215691a42950c74b2c

See more details on using hashes here.

File details

Details for the file sandbox_rls-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: sandbox_rls-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 53.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for sandbox_rls-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 10aa3c43a53e9f1ef8136ba344b4153a2403be25b23bdbdea6183a5c37802e74
MD5 0eb0f8790b383481624d42a76783eabc
BLAKE2b-256 8355cf6de0454bd45f5142f6304698b3db2aca60d7d92dbc075aa17ae05a8d89

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