Skip to main content

EU-hosted sandbox VMs for AI agents - official Python SDK

Project description

orkestr Python SDK

EU-hosted sandbox VMs for AI agents. Type-safe Python client for the api.orkestr.eu/v1/sandboxes REST API.

Status: private beta pre-release (0.1.0a1). The client surface is stable and tested, but the api.orkestr.eu/v1/sandboxes backend is not live yet - every endpoint returns 501 Not Implemented until the public beta. This release exists so you can pin the package and review the API. See docs/sandbox-mvp-plan.md in the orkestr repo for the timeline.

Install

pip install --pre orkestr

Requires Python 3.10+. The --pre flag is needed while the SDK is a pre-release; it is dropped once 0.1.0 ships with the public beta.

Authenticate

Mint an API token in the orkestr console with the sandboxes:write scope.

export ORKESTR_API_KEY="ork_..."

The SDK picks the key up from ORKESTR_API_KEY or you pass it explicitly.

Quick start

One-shot execution inside a fresh sandbox. The with block auto-terminates the sandbox on exit, preventing runaway costs if the caller crashes.

from orkestr import Sandbox

with Sandbox.create(template="python-3.12") as sbx:
    sbx.files.write("/workspace/main.py", "print(sum(range(1_000_000)))")
    result = sbx.exec("python /workspace/main.py")
    print(result.stdout)        # 499999500000
    print(result.duration_ms)   # ~120

API

Create a sandbox

sbx = Sandbox.create(
    template="python-3.12",          # one of the templates listed below
    cpu=1.0,                         # vCPU (default 1, plan-capped)
    memory_mb=2048,                  # RAM (default 2048, plan-capped)
    network="off",                   # "off" | "restricted" | "open"
    timeout_seconds=600,             # auto-terminate after this many seconds
    env={"OPENAI_API_KEY": "sk-..."},
    metadata={"agent_run": "r_123"},
    region="fsn1",                   # "fsn1" (DE) | "hel1" (FI) | None for auto
    api_key=None,                    # falls back to ORKESTR_API_KEY
)
print(sbx.id)             # "sbx_01HXYZ..."
print(sbx.status)         # "running"

Templates

Template Description
python-3.12 CPython 3.12 with pip and common libs
python-3.12-bare CPython 3.12 only, faster start
node-22 Node 22 with npm
ubuntu-24.04 Minimal Ubuntu shell environment

Run a command

result = sbx.exec("python /workspace/main.py", timeout_seconds=60)
result.stdout       # str
result.stderr       # str
result.exit_code    # int
result.duration_ms  # int

Stream a long command

for chunk in sbx.exec_stream("python long_task.py"):
    if chunk.stream == "stdout":
        print(chunk.data, end="", flush=True)
    else:
        print(chunk.data, end="", flush=True, file=sys.stderr)

Files

sbx.files.write("/workspace/data.json", '{"x": 1}')
sbx.files.write_bytes("/workspace/blob.bin", b"\x00\x01\x02")

content = sbx.files.read("/workspace/out.txt")       # returns str
raw = sbx.files.read_bytes("/workspace/blob.bin")     # returns bytes

for entry in sbx.files.list("/workspace"):
    print(entry.name, entry.is_dir, entry.size)

sbx.files.delete("/workspace/out.txt")

Pause + resume

Pausing snapshots the sandbox memory + disk and stops the compute meter. Resume restores it on the same or a different host. pause() returns the sandbox id; persist it across processes and pass to Sandbox.resume.

sbx = Sandbox.create(template="node-22", network="restricted")
sandbox_id = sbx.pause()
# ... minutes or hours later, from any worker:
sbx = Sandbox.resume(sandbox_id)

Snapshot retention is plan-capped (free: 1, pro: 3, team: 10). Calling pause() over the cap raises SnapshotCapReached.

Terminate

Context-manager exit calls terminate(). Outside with:

sbx.terminate()

After terminate() the sandbox row stays in your account history but the VM and any in-memory state are gone.

List your sandboxes

for sbx in Sandbox.list(status="running"):
    print(sbx.id, sbx.template, sbx.created_at)

Errors

All SDK errors inherit from orkestr.OrkestrError.

Exception When
AuthError Missing / invalid / expired API key, or scope mismatch
RateLimitError Plan rate limit hit
PlanLimitError Sandbox limit, concurrent limit, snapshot cap
SandboxNotFound sandbox_id doesn't exist or isn't yours
SandboxNotReady Operation called on a paused / terminated sandbox
ExecTimeout exec() exceeded timeout_seconds
NetworkPolicyError Command tried to reach a host the policy blocks
OrkestrError Any other API-level error

Async support

The MVP SDK is sync only. Async (AsyncSandbox) lands in v0.2.0 if a design partner blocks on it; the wire format is identical.

Versioning

Follows Semantic Versioning. The SDK targets the /v1/sandboxes API; bumps to v1 of the API are non-breaking for SDK callers. v2 of the API will require an SDK major.

Links

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

orkestr-0.1.0a2.tar.gz (21.0 kB view details)

Uploaded Source

Built Distribution

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

orkestr-0.1.0a2-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file orkestr-0.1.0a2.tar.gz.

File metadata

  • Download URL: orkestr-0.1.0a2.tar.gz
  • Upload date:
  • Size: 21.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for orkestr-0.1.0a2.tar.gz
Algorithm Hash digest
SHA256 74ec1976d01bf67ed2a1299d93df9fc369c0e76f9859c4bc669934277725a359
MD5 72d2b5ad919944996495e6ca84110692
BLAKE2b-256 888215cfc0d48e985d12ab15f0887ab4cd90803e21a5dd304e19f051dcf87878

See more details on using hashes here.

File details

Details for the file orkestr-0.1.0a2-py3-none-any.whl.

File metadata

  • Download URL: orkestr-0.1.0a2-py3-none-any.whl
  • Upload date:
  • Size: 16.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for orkestr-0.1.0a2-py3-none-any.whl
Algorithm Hash digest
SHA256 5366c7c6a6851ff06a0c00e80097f5df7f8caddc7b55ad7c555bc0327c70d2cd
MD5 36a1103369dffbc2323e326db7007c7b
BLAKE2b-256 08238f60d0c452b8e515d953afca5c4b43281cb801f4b19db4eca3658d101e42

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