Skip to content

Quickstart

Installation

Using uv (recommended):

uv add backyard

Or with pip:

pip install backyard

Note: To use the container-backed Sandbox (for third-party packages or full Python features), you need either Podman or Docker installed and running on your system. The sandbox auto-detects which runtime is available. Monty-only usage (which supports limited stdlib modules plus external functions) comes built-in.

Optional dependencies

For the TUI:

uv add "backyard[tui]"

Basic usage

from backyard import Sandbox

# Create a sandbox (defaults to Monty backend)
sandbox = Sandbox()

# Execute code
result = sandbox.run("print('hello from the sandbox!')")
print(result.stdout)  # hello from the sandbox!

Stateful execution

State is preserved across run() calls, just like a Jupyter notebook:

sandbox.run("x = [1, 2, 3]")
sandbox.run("x.append(4)")
result = sandbox.run("sum(x)")
print(result.result)  # 10

Container sandbox with third-party packages

The sandbox automatically converts to a container when you use third-party packages:

result = sandbox.run("import numpy; numpy.array([1, 2, 3])")
print(result.success)  # True

Or start with the container directly:

sandbox = Sandbox(sandbox_type="container")
result = sandbox.run("import numpy; numpy.__version__")

Read-only mode

Prevent the sandbox from modifying files:

sandbox = Sandbox(readonly=True)
result = sandbox.run("""
with open('test.txt', 'w') as f:
    f.write('hello')
""")
print(result.failed)  # True (write was denied)

Async usage

import asyncio
from backyard import Sandbox


async def main():
    async with Sandbox() as sb:
        result = await sb.run_async("print('async execution')")
        print(result.stdout)


asyncio.run(main())

Context manager

Sandboxes support both sync and async context managers for automatic cleanup:

# Sync
with Sandbox() as sb:
    sb.run("print('auto cleanup on exit')")

# Async
async with Sandbox() as sb:
    await sb.run_async("print('auto cleanup on exit')")