python3 script.py need an interpreter. Mirage calls that
interpreter a runtime, and you pick it per workspace. The TypeScript
packages ship two:
Pyodide (default)
Pyodide is full CPython in WebAssembly: real stdlib,sys.argv, stdin,
and auto-loaded scientific packages. Mirage mirrors the workspace mounts
into Pyodide’s in-memory filesystem, so open() and os.listdir work on
mounted paths.
Monty
Monty runs each execution in a crash-isolated worker with microsecond startup and no host filesystem, environment, or network access.pathlib
I/O and os.getenv route through the workspace mounts:
@pydantic/monty package:
python3 exit with code 127 and an
install hint.
Differences from CPython
- Command-line arguments are the
argvglobal;sys.argvdoes not exist. - The builtin
open()is not bridged yet in the JS binding; usepathlib(Path(...).read_text(),.write_text(),.iterdir()). - No
sys.stdinand no third-party imports. os.environreflects the session env only.
Selecting in YAML
Server workspace config files take a top-levelruntimes list:
home option locates the
runtime’s interpreter or distribution, in the spirit of JAVA_HOME. For
pyodide that is where the distribution loads from: it defaults to
the installed package in Node and the pinned CDN in the browser; point
it at self-hosted assets to pin or air-gap the runtime (falls back to
the MIRAGE_PYODIDE_HOME environment variable). monty embeds its
interpreter and has no options yet. Python-only names (wasi,
local) fail loud with a cross-language hint. In application code the
entries are the runtimes workspace option, instances carrying their
own options:
Resource limits
python3 is a command like any other: the same command_safeguards
blocks that guard cat or grep guard it, enforced at the same
central point. A run that exceeds timeout_seconds answers with exit
124 and python3: timed out after Ns on stderr, exactly like any
other command; max_bytes and max_lines cap its output the same
way. There is no python3-specific limit surface.
One caveat: the guard bounds how long a run may answer, not the
interpreter itself. A run that ignores the deadline keeps its
interpreter busy in the background until it finishes (monty runs on a
crash-isolated worker; pyodide shares the event loop, so prefer monty
for untrusted code). Give untrusted code a finite workload, or run it
behind a sandboxed deployment.