Skip to content

Create Python SDK #515

@appcypher

Description

@appcypher

Summary

Create a Python SDK (updating microsandbox package already on PyPI) that provides the same capabilities as the existing Node.js/TypeScript SDK, adapted to Python conventions. Python is the dominant language for AI agent frameworks, so this is a high-priority SDK.

API design

The design is meant to be idiomatic:

from microsandbox import Sandbox, Volume, Secret, NetworkPolicy

sb = await Sandbox.create(
    "my-sandbox",
    image="python",
    memory=512,
    cpus=2,
    env={"PYTHONDONTWRITEBYTECODE": "1"},
    workdir="/app",
    volumes={"/app/src": Volume.bind("./src", readonly=True)},
    network=NetworkPolicy.public_only()
)

output = await sb.exec("python", ["-c", "print('Hello!')"])
print(output.stdout())

await sb.stop()

Core API surface

Sandbox — lifecycle, execution, filesystem, metrics

  • Sandbox.create(name, image=, memory=, cpus=, ...) — create and boot
  • Sandbox.create_detached(...) — survives parent process
  • Sandbox.get(name) / Sandbox.list() / Sandbox.remove(name)
  • sb.exec(cmd, args, cwd=, env=, timeout=, rlimits=) — collected output
  • sb.exec_stream(cmd, args, stdin_pipe=, tty=) — streaming with async iterator
  • sb.shell(script) / sb.attach()
  • sb.fs — read, write, list, stat, copy (host <-> guest)
  • sb.metrics() — CPU, memory, disk I/O, network I/O
  • sb.stop() / sb.kill() / sb.drain() / sb.detach()
  • Context manager: async with await Sandbox.create(...) as sb:

Volume — persistent storage

  • Volume.create(name, quota=) / Volume.list() / Volume.remove(name)
  • Mount factories: Volume.bind(path), Volume.named(name), Volume.tmpfs(size_mib=)

NetworkPolicy — presets

  • NetworkPolicy.none() / NetworkPolicy.public_only() / NetworkPolicy.allow_all()

Secret — host-side credential injection

  • Secret.env(name, value=, allow_hosts=)

Patch — pre-boot rootfs modifications

  • Patch.text(path, content) / Patch.mkdir(path) / Patch.copy_dir(src, dst) / etc.

Streaming — async iterator + structural pattern matching

handle = await sb.exec_stream("tail", ["-f", "/var/log/app.log"])
async for event in handle.events():
    match event:
        case StdoutEvent(data=data):
            sys.stdout.buffer.write(data)
        case ExitedEvent(code=code):
            break

Utilities

  • is_installed() / install() — runtime setup
  • all_sandbox_metrics() — metrics for all running sandboxes

Implementation approach

Use PyO3/maturin to wrap the microsandbox Rust crate as a native Python extension module, same strategy as the Node.js SDK uses with NAPI.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions