Use it

Python API

Two functions cover almost everything: run_container to run a program, cleanup_containers to tidy up.

Run a program#

example.py
from pybox import run_container

result = run_container("print(6 * 7)", timeout_s=2.0, max_output_bytes=4096)
record = result.record

if record["cleanup"]["status"] != "REMOVED":
    print("box not confirmed gone:", record["cleanup"]["status"])

exit_code = record["observed"]["engine_state"].get("ExitCode")   # from the engine
said = record["capture"]["stdout"]                                # from the program: untrusted

The VM must already be running (pybox vm start). The function never starts it, never installs anything, and never downloads an image.

Arguments#

ArgumentRule
sourceA string of Python, at most 65,536 bytes as UTF-8
timeout_sMore than 0, at most 30 (default 2.0)
max_output_bytes1–65,536 per stream (default 65,536)
image"stdlib" (default) or "data", once built. Images
inputs(name, bytes) pairs copied to /tmp/input/; up to 64 files, 8 MiB. Files
collect_outputsTrue to bring back what the program writes to /tmp/output/

Bad arguments raise ValueError before anything happens. Everything else, including "the VM isn't running", comes back inside the result, so you never lose the record of what was attempted.

What you get back#

AttributeMeaning
recordThe receipt. Start here
returncodeThe program's exit code, only when the engine confirms it; otherwise None
stdout, stderrWhat the program printed (untrusted)
timed_out, timeoutsWhether a deadline fired, and which
cleanup_status, removedSee statuses
cancelledTrue if you pressed Ctrl-C; the box was still cleaned up
runner_errorA description of anything that went wrong in PyBox itself
output_files(name, bytes) pairs the program wrote (untrusted, already checked for names and size). Nothing is written to your Mac unless you do it
inputs, outputs, outputs_skipped, outputs_errorWhat went in and came back: names, sizes and SHA-256s

Tidy up#

from pybox import cleanup_containers

report = cleanup_containers()
print(report.found, report.removed, report.pending_attempts, report.admission_allowed)

This removes only this installation's expired, stopped boxes. Pass resolve_attempts=["<run id>"] to settle an unconfirmed run.

One run at a time#

PyBox admits one run (or cleanup) at a time per installation, using a lock the operating system releases automatically if your process dies. A second simultaneous call gets "another PyBox run or cleanup holds lifecycle admission" in runner_error instead of waiting.

The unsealed runner#

pybox.run_file(path, unsafe_local=True) runs a file directly on your Mac, without a box. unsafe_local must be exactly True or it refuses. Use it only to learn how supervision works, with your own code.

Checked against the source on 21 October 2026.

esc