Use it
Python API
Two functions cover almost everything: run_container to run a program, cleanup_containers to tidy up.
Run a program#
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: untrustedThe VM must already be running (pybox vm start). The function never starts it, never installs anything, and never downloads an image.
Arguments#
| Argument | Rule |
|---|---|
source | A string of Python, at most 65,536 bytes as UTF-8 |
timeout_s | More than 0, at most 30 (default 2.0) |
max_output_bytes | 1–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_outputs | True 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#
| Attribute | Meaning |
|---|---|
record | The receipt. Start here |
returncode | The program's exit code, only when the engine confirms it; otherwise None |
stdout, stderr | What the program printed (untrusted) |
timed_out, timeouts | Whether a deadline fired, and which |
cleanup_status, removed | See statuses |
cancelled | True if you pressed Ctrl-C; the box was still cleaned up |
runner_error | A 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_error | What 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.