pydantic-monty-runtime

The compiled `monty` CLI and worker binary that gives pydantic-monty and @pydantic/monty crash-isolated Python sandbox execution.

Tool
PyPI
v0.0.21
8,124stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
86/100Excellent
Development Activity96
Maintenance96
Community60
Maturity52
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
86/100Excellent
Architecture85
Code Quality88
Innovation80
Learning Curve90

pydantic-monty-runtime packages the compiled monty binary for PyPI, the same way uv and ruff distribute their Rust binaries: installing the wheel drops monty straight into the environment’s scripts directory, with no compiler or manual build step required. The binary is built from the monty-runtime Rust crate inside the pydantic/monty workspace, and it is the execution engine underneath Monty, a minimal, secure Python interpreter written in Rust for sandboxing LLM-generated code.

Most users never install this package directly — the pydantic-monty metapackage pulls it in automatically alongside the pydantic_monty Python bindings, which spawn monty as a crash-isolated worker subprocess to run untrusted, agent-generated code with microsecond startup and strict controls over filesystem, network, and resource usage. Installed on its own, pydantic-monty-runtime gives you just the monty CLI: an interactive REPL, monty file.py execution, monty -c "<code>" one-liners, and a monty subprocess worker mode that speaks a framed protobuf protocol over stdio for embedding in a parent process’s worker pool.

What You Get

  • Compiled monty binary - a maturin-built, bindings = "bin" wheel that places the Rust-compiled monty executable directly in the environment’s scripts directory on install.
  • Standalone CLI - monty for an interactive REPL, monty file.py to run a script, and monty -c "<code>" for one-off snippets, mirroring python’s own invocation flags.
  • Subprocess worker mode - monty subprocess runs the binary as a wire-protocol child, reading framed protobuf requests from stdin and streaming events back on stdout, so a parent pool (like pydantic-monty or monty-pool) gets crash isolation for free.
  • Type checking on demand - -t / --type-check runs the bundled ty-powered type checker before executing, with multiple diagnostic output formats (full, concise, json, github, and more).
  • Sandboxed filesystem mounts - -m / --mount maps a host directory into the sandbox in read-only, read-write, or in-memory overlay mode, with an optional write-size limit.
  • Resource limit flags - --max-memory, --max-duration, --max-recursion-depth, and --gc-interval bound a session’s heap, wall-clock time, call-stack depth, and GC cadence.

Common Use Cases

  • Standalone tool install - uv tool install pydantic-monty-runtime to get a global monty command for exploring the sandbox interactively, independent of any Python project.
  • Supplying the worker binary - installing pydantic-monty-runtime alongside an existing pydantic-monty-client install when the binary needs to come from a separate build or pinned version.
  • Crash-isolated agent code execution - as the worker binary spawned by pydantic-monty’s AsyncMonty/Monty pools or the JavaScript @pydantic/monty package, so a stack overflow or allocator abort in agent-written code kills only the worker subprocess, never the host process.
  • CI and local debugging of the sandbox itself - running monty -c snippets directly to check what a given piece of Python does under Monty’s supported subset before wiring it into an agent.

Under The Hood

Architecture The monty-runtime crate (main.rs, run.rs at ~700 lines, subprocess.rs at ~135 lines) builds one binary with two distinct execution paths behind a shared Cli argument struct: a standalone path (run.rs) that drives MontyRepl/MontyRun from the core monty crate for REPL, file, and -c execution, wired to monty-fs for sandboxed mounts and monty-type-checking for optional type checking; and a subprocess path (subprocess.rs) that is a thin stdio shell around monty_proto::worker::Child, a transport-agnostic state machine reading framed protobuf requests and emitting framed events, explicitly designed so a parent pool can distinguish a graceful FatalError from an uncommunicative crash. A process-wide monty_alloc::LimitedAllocator global allocator enforces soft and hard memory ceilings across both paths, and a standalone Cargo feature can strip the REPL/terminal stack entirely to build a subprocess-only worker binary.

Tech Stack Pure Rust, built with maturin using the bindings = "bin" mode (the same PyPI packaging pattern uv and ruff use) so the compiled binary lands in the wheel’s scripts directory with no Python glue code. Dependencies include clap for argument parsing, rustyline plus anstream/anstyle for the interactive REPL and terminal styling, monty-proto for the protobuf worker protocol, monty-type-checking (backed by Astral’s ty), monty-fs for mount handling, and an optional logfire/tracing pairing gated behind a telemetry feature that instruments only the standalone CLI path, never the subprocess worker.

Code Quality The crate carries substantial integration test coverage relative to its size — a 1,329-line tests/subprocess.rs exercising the worker protocol and a tests/mounts.rs covering filesystem mount modes. Error handling is explicit and structured: the subprocess loop matches every FrameError variant and exits with dedicated BSD sysexits.h-style codes so a parent process can classify failures programmatically, and a custom panic hook guards the worker loop. The wider workspace runs CI (ci.yml) and continuous performance tracking (codspeed.yml), with dense, precise doc comments throughout explaining non-obvious design decisions (why telemetry lives only in the standalone path, why memory limiting must be declared in the binary crate).

API Design The binary deliberately offers two ergonomic surfaces for two very different audiences: a CLI that mirrors python’s own flags (-c, -i, file execution) for a developer poking at the sandbox by hand, and a strict framed-protocol subprocess mode for a parent process embedding Monty programmatically. Packaging the compiled binary itself as a plain PyPI/npm-installable artifact (rather than requiring a Rust toolchain or a separate download step) removes the most common friction point in shipping native tooling to Python and JS developers.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search