pydantic/montyPublic

A minimal, secure Python interpreter written in Rust for use by AI

AI summary: A minimal, secure Python interpreter written in Rust specifically for use by AI agents.

Stars
8K
+6 today
Forks
396
Watchers
40
Open issues
66
Open PRs
29
Contributors
~44
Commits
606
Branches
28

RustMITCreated May 28, 2023Last push todayLatest release v0.0.19+26 stars this week+28 this month

Star history

since Jan 25, 2026
02K4K6K8KJan 2026Mar 2026Jun 2026Aug 2026
8K stars as of Aug 7, 2026, tracked back to Jan 25, 2026. Historical curve reconstructed from public GitHub event archives, calibrated to the current total.

Contribution activity

commits per day, last 52 weeks
AugSepOctNovDecJanFebMarAprMayJunJulMonWedFri2025-08-03: 0 commits2025-08-04: 0 commits2025-08-05: 0 commits2025-08-06: 0 commits2025-08-07: 0 commits2025-08-08: 0 commits2025-08-09: 0 commits2025-08-10: 0 commits2025-08-11: 0 commits2025-08-12: 0 commits2025-08-13: 0 commits2025-08-14: 0 commits2025-08-15: 0 commits2025-08-16: 0 commits2025-08-17: 0 commits2025-08-18: 0 commits2025-08-19: 0 commits2025-08-20: 0 commits2025-08-21: 0 commits2025-08-22: 0 commits2025-08-23: 0 commits2025-08-24: 0 commits2025-08-25: 0 commits2025-08-26: 0 commits2025-08-27: 0 commits2025-08-28: 0 commits2025-08-29: 0 commits2025-08-30: 0 commits2025-08-31: 0 commits2025-09-01: 0 commits2025-09-02: 0 commits2025-09-03: 0 commits2025-09-04: 0 commits2025-09-05: 0 commits2025-09-06: 0 commits2025-09-07: 0 commits2025-09-08: 0 commits2025-09-09: 0 commits2025-09-10: 0 commits2025-09-11: 0 commits2025-09-12: 0 commits2025-09-13: 0 commits2025-09-14: 0 commits2025-09-15: 0 commits2025-09-16: 0 commits2025-09-17: 0 commits2025-09-18: 0 commits2025-09-19: 0 commits2025-09-20: 0 commits2025-09-21: 0 commits2025-09-22: 0 commits2025-09-23: 0 commits2025-09-24: 0 commits2025-09-25: 0 commits2025-09-26: 0 commits2025-09-27: 0 commits2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 0 commits2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 0 commits2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 0 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 0 commits2025-10-29: 0 commits2025-10-30: 0 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-08: 0 commits2025-11-09: 0 commits2025-11-10: 0 commits2025-11-11: 0 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 11 commits2025-11-20: 3 commits2025-11-21: 0 commits2025-11-22: 8 commits2025-11-23: 7 commits2025-11-24: 7 commits2025-11-25: 9 commits2025-11-26: 1 commit2025-11-27: 0 commits2025-11-28: 8 commits2025-11-29: 3 commits2025-11-30: 2 commits2025-12-01: 1 commit2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 1 commit2025-12-06: 8 commits2025-12-07: 9 commits2025-12-08: 1 commit2025-12-09: 2 commits2025-12-10: 0 commits2025-12-11: 0 commits2025-12-12: 1 commit2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 2 commits2025-12-17: 0 commits2025-12-18: 0 commits2025-12-19: 0 commits2025-12-20: 2 commits2025-12-21: 2 commits2025-12-22: 3 commits2025-12-23: 2 commits2025-12-24: 1 commit2025-12-25: 0 commits2025-12-26: 0 commits2025-12-27: 1 commit2025-12-28: 3 commits2025-12-29: 2 commits2025-12-30: 3 commits2025-12-31: 2 commits2026-01-01: 0 commits2026-01-02: 2 commits2026-01-03: 0 commits2026-01-04: 3 commits2026-01-05: 4 commits2026-01-06: 1 commit2026-01-07: 0 commits2026-01-08: 0 commits2026-01-09: 3 commits2026-01-10: 1 commit2026-01-11: 6 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 5 commits2026-01-15: 6 commits2026-01-16: 1 commit2026-01-17: 13 commits2026-01-18: 6 commits2026-01-19: 0 commits2026-01-20: 3 commits2026-01-21: 6 commits2026-01-22: 4 commits2026-01-23: 1 commit2026-01-24: 0 commits2026-01-25: 1 commit2026-01-26: 1 commit2026-01-27: 6 commits2026-01-28: 3 commits2026-01-29: 4 commits2026-01-30: 2 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 4 commits2026-02-04: 5 commits2026-02-05: 2 commits2026-02-06: 6 commits2026-02-07: 6 commits2026-02-08: 0 commits2026-02-09: 3 commits2026-02-10: 7 commits2026-02-11: 1 commit2026-02-12: 4 commits2026-02-13: 1 commit2026-02-14: 0 commits2026-02-15: 5 commits2026-02-16: 8 commits2026-02-17: 6 commits2026-02-18: 3 commits2026-02-19: 4 commits2026-02-20: 3 commits2026-02-21: 0 commits2026-02-22: 0 commits2026-02-23: 4 commits2026-02-24: 0 commits2026-02-25: 4 commits2026-02-26: 0 commits2026-02-27: 2 commits2026-02-28: 1 commit2026-03-01: 0 commits2026-03-02: 1 commit2026-03-03: 9 commits2026-03-04: 3 commits2026-03-05: 0 commits2026-03-06: 0 commits2026-03-07: 0 commits2026-03-08: 0 commits2026-03-09: 14 commits2026-03-10: 5 commits2026-03-11: 0 commits2026-03-12: 0 commits2026-03-13: 0 commits2026-03-14: 0 commits2026-03-15: 0 commits2026-03-16: 2 commits2026-03-17: 0 commits2026-03-18: 3 commits2026-03-19: 2 commits2026-03-20: 0 commits2026-03-21: 0 commits2026-03-22: 0 commits2026-03-23: 5 commits2026-03-24: 2 commits2026-03-25: 1 commit2026-03-26: 2 commits2026-03-27: 3 commits2026-03-28: 1 commit2026-03-29: 2 commits2026-03-30: 3 commits2026-03-31: 0 commits2026-04-01: 0 commits2026-04-02: 2 commits2026-04-03: 0 commits2026-04-04: 0 commits2026-04-05: 0 commits2026-04-06: 3 commits2026-04-07: 0 commits2026-04-08: 0 commits2026-04-09: 3 commits2026-04-10: 1 commit2026-04-11: 0 commits2026-04-12: 2 commits2026-04-13: 5 commits2026-04-14: 3 commits2026-04-15: 0 commits2026-04-16: 1 commit2026-04-17: 7 commits2026-04-18: 8 commits2026-04-19: 3 commits2026-04-20: 2 commits2026-04-21: 2 commits2026-04-22: 7 commits2026-04-23: 0 commits2026-04-24: 1 commit2026-04-25: 0 commits2026-04-26: 0 commits2026-04-27: 0 commits2026-04-28: 5 commits2026-04-29: 3 commits2026-04-30: 0 commits2026-05-01: 0 commits2026-05-02: 0 commits2026-05-03: 0 commits2026-05-04: 1 commit2026-05-05: 3 commits2026-05-06: 2 commits2026-05-07: 5 commits2026-05-08: 1 commit2026-05-09: 0 commits2026-05-10: 0 commits2026-05-11: 0 commits2026-05-12: 0 commits2026-05-13: 0 commits2026-05-14: 6 commits2026-05-15: 9 commits2026-05-16: 0 commits2026-05-17: 0 commits2026-05-18: 4 commits2026-05-19: 7 commits2026-05-20: 0 commits2026-05-21: 0 commits2026-05-22: 0 commits2026-05-23: 0 commits2026-05-24: 1 commit2026-05-25: 0 commits2026-05-26: 6 commits2026-05-27: 4 commits2026-05-28: 8 commits2026-05-29: 4 commits2026-05-30: 1 commit2026-05-31: 0 commits2026-06-01: 0 commits2026-06-02: 1 commit2026-06-03: 0 commits2026-06-04: 1 commit2026-06-05: 0 commits2026-06-06: 1 commit2026-06-07: 1 commit2026-06-08: 0 commits2026-06-09: 0 commits2026-06-10: 0 commits2026-06-11: 0 commits2026-06-12: 0 commits2026-06-13: 0 commits2026-06-14: 0 commits2026-06-15: 0 commits2026-06-16: 0 commits2026-06-17: 0 commits2026-06-18: 1 commit2026-06-19: 1 commit2026-06-20: 0 commits2026-06-21: 0 commits2026-06-22: 3 commits2026-06-23: 1 commit2026-06-24: 0 commits2026-06-25: 3 commits2026-06-26: 1 commit2026-06-27: 0 commits2026-06-28: 4 commits2026-06-29: 4 commits2026-06-30: 0 commits2026-07-01: 0 commits2026-07-02: 0 commits2026-07-03: 1 commit2026-07-04: 5 commits2026-07-05: 4 commits2026-07-06: 1 commit2026-07-07: 1 commit2026-07-08: 2 commits2026-07-09: 5 commits2026-07-10: 6 commits2026-07-11: 1 commit2026-07-12: 0 commits2026-07-13: 0 commits2026-07-14: 0 commits2026-07-15: 1 commit2026-07-16: 1 commit2026-07-17: 2 commits2026-07-18: 1 commit2026-07-19: 4 commits2026-07-20: 5 commits2026-07-21: 9 commits2026-07-22: 8 commits2026-07-23: 0 commits2026-07-24: 7 commits2026-07-25: 2 commits2026-07-26: 0 commits2026-07-27: 9 commits2026-07-28: 6 commits2026-07-29: 2 commits2026-07-30: 0 commits2026-07-31: 0 commits2026-08-01: 0 commits
549 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Very active

    549 commits in 52 weeks

  • Permissive license

    MIT

  • Continuous integration

    Automated checks passing

  • Repeat trending

    5 trending appearances

What monty does

Monty is a highly constrained and secure Python interpreter built in Rust by Pydantic. It is explicitly designed for executing Python code generated by AI models safely. By minimizing the standard library and implementing strict security boundaries at the Rust level, Monty ensures that AI agents can run ad-hoc scripts without compromising the host system. It provides a lightweight execution environment optimized for programmatic invocation.

AI framework developers and security engineers who need to safely execute untrusted, AI-generated Python code natively.

  • Rust foundation: Leverages Rust's memory safety and performance for interpreter execution.
  • AI-centric design: Built specifically to sandbox code generated by language models.
  • Minimalist core: Strips down the Python environment to reduce the attack surface.
  • Secure boundaries: Isolates execution from the host operating system deeply.
  • Performance tracked: Continuously benchmarked using Codspeed to ensure fast startup.

Where teams use it

Agentic Code Execution

Safely execute Python snippets generated by LLMs in a controlled sandbox.

Data processing pipelines

Allow AI to run transformations securely without risking system integrity.

Automated testing

Evaluate generated code logic rapidly with minimal overhead.

Secure multi-tenant execution

Run scripts on behalf of different users without containerization overhead.

Getting started: pip install pydantic-monty

README

main branch

Monty

A minimal, secure Python interpreter written in Rust for use by AI.

CI Codspeed Coverage PyPI versions license Join Slack

Experimental - This project is still in development, and not ready for prime time.

A minimal, secure Python interpreter written in Rust for use by AI.

Monty avoids the cost, latency, complexity and general faff of using a full container based sandbox for running LLM generated code.

Instead, it lets you safely run Python code written by an LLM embedded in your agent, with startup times measured in single digit microseconds not hundreds of milliseconds.

What Monty can do:

  • Run a reasonable subset of Python code - enough for your agent to express what it wants to do
  • Completely block access to the host environment: filesystem, env variables and network access are all implemented via external function calls the developer can control
  • Call functions on the host - only functions you give it access to
  • Run typechecking - monty supports full modern python type hints and comes with ty included in a single binary to run typechecking
  • Be snapshotted to bytes at external function calls, meaning you can store the interpreter state in a file or database, and resume later
  • Startup extremely fast (<1μs to go from code to execution result), and has runtime performance that is similar to CPython (generally between 5x faster and 5x slower)
  • Be called from Rust, Python, or Javascript - because Monty has no dependencies on cpython, you can use it anywhere you can run Rust
  • Control resource usage - Monty can track memory usage, stack depth, and execution time and cancel execution if it exceeds preset limits
  • Collect stdout and stderr and return it to the caller
  • Run async or sync code on the host via async or sync code on the host
  • Use a small subset of the standard library: sys, os, typing, asyncio, re, datetime, json, dataclasses (soon)

What Monty cannot do:

  • Use the rest of the standard library
  • Use third party libraries (like Pydantic), support for external python library is not a goal
  • define classes (support should come soon)
  • use match statements (again, support should come soon)

In short, Monty is extremely limited and designed for one use case:

To run code written by agents.

For motivation on why you might want to do this, see:

In very simple terms, the idea of all the above is that LLMs can work faster, cheaper and more reliably if they're asked to write Python (or Javascript) code, instead of relying on traditional tool calling. Monty makes that possible without the complexity of a sandbox or risk of running code directly on the host.

Note: Monty will (soon) be used to implement codemode in Pydantic AI

Usage

Monty can be called from Python, JavaScript/TypeScript or Rust.

Python

To install:

uv add pydantic-monty

(Or pip install pydantic-monty for the boomers)

Usage:

from typing import Any

import pydantic_monty

code = """
async def agent(prompt: str, messages: Messages):
    while True:
        print(f'messages so far: {messages}')
        output = await call_llm(prompt, messages)
        if isinstance(output, str):
            return output
        messages.extend(output)

await agent(prompt, [])
"""

type_definitions = """
from typing import Any

Messages = list[dict[str, Any]]

async def call_llm(prompt: str, messages: Messages) -> str | Messages:
    raise NotImplementedError()

prompt: str = ''
"""


Messages = list[dict[str, Any]]


async def call_llm(prompt: str, messages: Messages) -> str | Messages:
    if len(messages) < 2:
        return [{'role': 'system', 'content': 'example response'}]
    else:
        return f'example output, message count {len(messages)}'


async def main():
    async with pydantic_monty.AsyncMonty() as pool:
        async with pool.checkout(
            script_name='agent.py',
            type_check=True,
            type_check_stubs=type_definitions,
        ) as session:
            output = await session.feed_run(
                code,
                inputs={'prompt': 'testing'},
                external_lookup={'call_llm': call_llm},
            )
    print(output)
    #> example output, message count 2


if __name__ == '__main__':
    import asyncio

    asyncio.run(main())

Execution happens in a pool of monty worker subprocesses, so even a memory error triggered by adversarial code (stack overflow, allocator abort) can never crash your process — the worker dies, raises MontyCrashedError, and is replaced. There is also a fully synchronous API:

import pydantic_monty

with pydantic_monty.Monty() as pool:
    with pool.checkout() as session:
        # session state persists between feed_run calls
        session.feed_run('x = 21')
        print(session.feed_run('x * 2'))
        #> 42

JavaScript / TypeScript

To install:

npm install @pydantic/monty

The JS package is a native (napi) binding over the same Rust worker pool the Python package uses — the binding and the monty worker binary ship via platform-specific npm packages:

import { Monty } from '@pydantic/monty'

await using pool = await Monty.create()
await using session = await pool.checkout()

// session state persists between feedRun calls
await session.feedRun('x = 21')
console.log(await session.feedRun('x * 2')) // 42

// external functions may be async
const result = await session.feedRun('await fetch_data()', {
  externalLookup: { fetch_data: async () => 'data' },
})

For browsers (or anywhere subprocesses are impossible) the same package exposes an in-process WebAssembly build under the @pydantic/monty/wasm subpath (no crash isolation: a sandbox crash is a host crash there).

Rust

For running untrusted code from Rust, we recommend the monty-pool crate rather than the in-process API below. monty-pool only runs code in monty worker subprocesses, which affords extra protections: a crash triggered by adversarial code (stack overflow, allocator abort) kills only the worker — the pool detects the death and replaces the worker — and a parent-side watchdog can kill workers that exceed a hard timeout. It is the same engine the Python and JavaScript packages above are built on. See the monty-pool README for usage.

The monty crate itself provides the in-process interpreter:

use monty::MontyRun;
use monty_types::{CompileOptions, ResourceTracker, MontyObject, PrintWriter, ResourceLimits};

let code = r#"
def fib(n):
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)

fib(x)
"#;

let runner = MontyRun::new(code.to_owned(), "fib.py", vec!["x".to_owned()], CompileOptions::default()).unwrap();
let result = runner.run(vec![MontyObject::Int(10)], ResourceTracker::default(), PrintWriter::Stdout).unwrap();
assert_eq!(result, MontyObject::Int(55));

Serialization

MontyRun and RunProgress can be serialized using the dump() and load() methods:

use monty::MontyRun;
use monty_types::{CompileOptions, ResourceTracker, MontyObject, PrintWriter, ResourceLimits};

// Serialize parsed code
let runner = MontyRun::new("x + 1".to_owned(), "main.py", vec!["x".to_owned()], CompileOptions::default()).unwrap();
let bytes = runner.dump().unwrap();

// Later, restore and run
let runner2 = MontyRun::load(&bytes).unwrap();
let result = runner2.run(vec![MontyObject::Int(41)], ResourceTracker::default(), PrintWriter::Stdout).unwrap();
assert_eq!(result, MontyObject::Int(42));

PydanticAI Integration

Monty will power code-mode in Pydantic AI. Instead of making sequential tool calls, the LLM writes Python code that calls your tools as functions and Monty executes it safely.

import asyncio
import json

import logfire
from httpx import AsyncClient
from pydantic_ai import Agent, RunContext
from pydantic_ai.toolsets.code_mode import CodeModeToolset
from pydantic_ai.toolsets.function import FunctionToolset
from typing_extensions import TypedDict

logfire.configure()
logfire.instrument_pydantic_ai()


class LatLng(TypedDict):
    lat: float
    lng: float


weather_toolset: FunctionToolset[AsyncClient] = FunctionToolset()


@weather_toolset.tool
async def get_lat_lng(
    ctx: RunContext[AsyncClient], location_description: str
) -> LatLng:
    """Get the latitude and longitude of a location."""
    # NOTE: the response here will be random, and is not related to the location description.
    r = await ctx.deps.get(
        'https://demo-endpoints.pydantic.workers.dev/latlng',
        params={'location': location_description},
    )
    r.raise_for_status()
    return json.loads(r.content)


@weather_toolset.tool
async def get_temp(ctx: RunContext[AsyncClient], lat: float, lng: float) -> float:
    """Get the temp at a location."""
    # NOTE: the responses here will be random, and are not related to the lat and lng.
    r = await ctx.deps.get(
        'https://demo-endpoints.pydantic.workers.dev/number',
        params={'min': 10, 'max': 30},
    )
    r.raise_for_status()
    return float(r.text)


@weather_toolset.tool
async def get_weather_description(
    ctx: RunContext[AsyncClient], lat: float, lng: float
) -> str:
    """Get the weather description at a location."""
    # NOTE: the responses here will be random, and are not related to the lat and lng.
    r = await ctx.deps.get(
        'https://demo-endpoints.pydantic.workers.dev/weather',
        params={'lat': lat, 'lng': lng},
    )
    r.raise_for_status()
    return r.text


agent = Agent(
    'gateway/anthropic:claude-sonnet-4-5',
    # toolsets=[weather_toolset],
    toolsets=[CodeModeToolset(weather_toolset)],
    deps_type=AsyncClient,
)


async def main():
    async with AsyncClient() as client:
        await agent.run('Compare the weather of London, Paris, and Tokyo.', deps=client)


if __name__ == '__main__':
    asyncio.run(main())

Community Bindings

  • Go: gomonty - Go bindings for the Monty interpreter
  • Dart/Flutter: dart_monty (github) (pub.dev)- Dart/Flutter bindings for Monty

Alternatives

There are generally two responses when you show people Monty:

  1. Oh my god, this solves so many problems, I want it.
  2. Why not X?

Where X is some alternative technology. Oddly often these responses are combined, suggesting people have not yet found an alternative that works for them, but are incredulous that there's really no good alternative to creating an entire Python implementation from scratch.

I'll try to run through the most obvious alternatives, and why there aren't right for what we wanted.

NOTE: all these technologies are impressive and have widespread uses, this commentary on their limitations for our use case should not be seen as a criticism. Most of these solutions were not conceived with the goal of providing an LLM sandbox, which is why they're not necessary great at it.

Tech Language completeness Security Start latency FOSS Setup complexity File mounting Snapshotting
Monty partial strict 0.06ms free / OSS easy easy easy
Docker full good 195ms free / OSS intermediate easy intermediate
Pyodide full poor 2800ms free / OSS intermediate easy hard
starlark-rust very limited good 1.7ms free / OSS easy not available? impossible?
WASI / Wasmer partial, almost full strict 66ms free * intermediate easy intermediate
sandboxing service full strict 1033ms not free intermediate hard intermediate
YOLO Python full non-existent 0.1ms / 30ms free / OSS easy easy / scary hard

See ./scripts/startup_performance.py for the script used to calculate the startup performance numbers.

Details on each row below:

Monty

  • Language completeness: No classes (yet), limited stdlib, no third-party libraries
  • Security: Explicitly controlled filesystem, network, and env access, strict limits on execution time and memory usage
  • Start latency: Starts in microseconds
  • Setup complexity: just pip install pydantic-monty or npm install @pydantic/monty, ~4.5MB download
  • File mounting: Strictly controlled, see #85
  • Snapshotting: Monty's pause and resume functionality with dump() and load() makes it trivial to pause, resume and fork execution

Docker

  • Language completeness: Full CPython with any library
  • Security: Process and filesystem isolation, network policies, but container escapes exist, memory limitation is possible
  • Start latency: Container startup overhead (~195ms measured)
  • Setup complexity: Requires Docker daemon, container images, orchestration, python:3.14-alpine is 50MB - docker can't be installed from PyPI
  • File mounting: Volume mounts work well
  • Snapshotting: Possible with durable execution solutions like Temporal, or snapshotting an image and saving it as a Docker image.

Pyodide

  • Language completeness: Full CPython compiled to WASM, almost all libraries available
  • Security: Relies on browser/WASM sandbox - not designed for server-side isolation, python code can run arbitrary code in the JS runtime, only deno allows isolation, memory limits are hard/impossible to enforce with deno
  • Start latency: WASM runtime loading is slow (~2800ms cold start)
  • Setup complexity: Need to load WASM runtime, handle async initialization, pyodide NPM package is ~12MB, deno is ~50MB - Pyodide can't be called with just PyPI packages
  • File mounting: Virtual filesystem via browser APIs
  • Snapshotting: Possible with durable execution solutions like Temporal presumably, but hard

starlark-rust

See starlark-rust.

  • Language completeness: Configuration language, not Python - no classes, exceptions, async
  • Security: Deterministic and hermetic by design
  • Start latency: runs embedded in the process like Monty, hence impressive startup time
  • Setup complexity: Usable in python via starlark-pyo3
  • File mounting: No file handling by design AFAIK?
  • Snapshotting: Impossible AFAIK?

WASI / Wasmer

Running Python in WebAssembly via Wasmer.

  • Language completeness: Full CPython, pure Python external packages work via mounting, external packages with C bindings don't work
  • Security: In principle WebAssembly should provide strong sandboxing guarantees.
  • Start latency: The wasmer python package hasn't been updated for 3 years and I couldn't find docs on calling Python in wasmer from Python, so I called it via subprocess. Start latency was 66ms.
  • Setup complexity: wasmer download is 100mb, the "python/python" package is 50mb.
  • FOSS: I marked this as "free *" since the cost is zero but not everything seems to be open source. As of 2026-02-10 the python/python wasmer package package has no readme, no license, no source link and no indication of how it's built, the recently uploaded versions show size as "0B" although the download is ~50MB - the build process for the Python binary is not clear and transparent. (If I'm wrong here, please create an issue to correct correct me)
  • File mounting: Supported
  • Snapshotting: Supported via journaling

sandboxing service

Services like Daytona, E2B, Modal.

There are similar challenges, more setup complexity but lower network latency for setting up your own sandbox setup with k8s.

  • Language completeness: Full CPython with any library
  • Security: Professionally managed container isolation
  • Start latency: Network round-trip and container startup time. I got ~1s cold start time with Daytona EU from London, Daytona advertise sub 90ms latency, presumably that's for an existing container, not clear if it includes network latency
  • FOSS: Pay per execution or compute time, some implementations are open source
  • Setup complexity: API integration, auth tokens - fine for startups but generally a non-start for enterprises
  • File mounting: Upload/download via API calls
  • Snapshotting: Possible with durable execution solutions like Temporal, also the services offer some solutions for this, I think based con docker containers

YOLO Python

Running Python directly via exec() (~0.1ms) or subprocess (~30ms).

  • Language completeness: Full CPython with any library
  • Security: None - full filesystem, network, env vars, system commands
  • Start latency: Near-zero for exec(), ~30ms for subprocess
  • Setup complexity: None
  • File mounting: Direct filesystem access (that's the problem)
  • Snapshotting: Possible with durable execution solutions like Temporal

Part of the Pydantic Stack

The Pydantic Stack is everything you need to ship production-grade AI agents:

View on GitHub

Recent activity

commits and pull requests

Releases and announcements

25 total
  1. v0.0.19 - 2026-07-24v0.0.19Jul 24, 2026

    ## What's Changed * introduce iterator helpers that manage recursion / time by @davidhewitt in https://github.com/pydantic/monty/pull/454 * fix interactions with global names, function scopes & repl by @davidhewitt in https://github.com/pydantic/monty/pull/469 * experiment with `StringBuilder` to guard strings under construction by @davidhewitt in https://github.com/pydantic/monty/pull/448 * fix type-object marshalling across the sandbox boundary by @samuelcolvin in https://github.com/pydantic/monty/pull/478 * `FromArgs` slots cleanup by @samuelcolvin in https://github.com/pydantic/monty/pull/484 * fix(file): release the buffered-file OS-call pin on all paths by @arkuhn in https://github.com/pydantic/monty/pull/485 * add `__name__` et al. by @samuelcolvin in https://github.com/pydantic/monty/pull/495 * f-strings improvements by @samuelcolvin in https://github.com/pydantic/monty/pull/494 * fix: return error instead of panicking in `ForIter` heap read by @tontinton in https://github.com/pydantic/monty/pull/493 * Move execution to a subprocess pool by @samuelcolvin in https://github.com/pydantic/monty/pull/500 * Add 'Part of the Pydantic Stack' footer to README by @strawgat

  2. v0.0.19-beta.6 - 2026-07-22v0.0.19-beta.6Jul 22, 2026pre-release

    ## What's Changed * fix npm publish by @davidhewitt in https://github.com/pydantic/monty/pull/603 * Fix leaks and panics on `MontyObject` conversion error paths by @samuelcolvin in https://github.com/pydantic/monty/pull/600 * release 0.0.19b6 by @davidhewitt in https://github.com/pydantic/monty/pull/604 **Full Changelog**: https://github.com/pydantic/monty/compare/v0.0.19-beta.5...v0.0.19-beta.6

  3. v0.0.19-beta.5 - 2026-07-21v0.0.19-beta.5Jul 21, 2026pre-release

    ## What's Changed * clean up js packaging / smoke test by @davidhewitt in https://github.com/pydantic/monty/pull/550 * build and release the `monty-cpython` container by @samuelcolvin in https://github.com/pydantic/monty/pull/563 * remove mod eq optimization by @davidhewitt in https://github.com/pydantic/monty/pull/565 * Add pytest-style assert failure messages by @samuelcolvin in https://github.com/pydantic/monty/pull/556 * remove monty-cpython by @samuelcolvin in https://github.com/pydantic/monty/pull/571 * improve error messages from suspensions in `evaluate_function` by @davidhewitt in https://github.com/pydantic/monty/pull/573 * inline `clone_immediate` into `clone_with_heap` by @davidhewitt in https://github.com/pydantic/monty/pull/578 * Make an existing iterator self-iterable by @rewitt94 in https://github.com/pydantic/monty/pull/579 * Move mounting to the host-side and move `fs` to `monty-fs` by @samuelcolvin in https://github.com/pydantic/monty/pull/576 * Arg fixes, `int()`, `str()`, `round()` by @samuelcolvin in https://github.com/pydantic/monty/pull/584 * Public API fixes by @samuelcolvin in https://github.com/pydantic/monty/pull/587 * add iterator to `PyTrai

  4. v0.0.19-beta.4 - 2026-07-100.0.19-beta.4Jul 10, 2026pre-release

    ## What's Changed * monty-wasm-runtime publish false, prep 0.0.19-beta.4 by @samuelcolvin in https://github.com/pydantic/monty/pull/559 **Full Changelog**: https://github.com/pydantic/monty/compare/0.0.19-beta.3...0.0.19-beta.4

  5. v0.0.19-beta.3 - 2026-07-100.0.19-beta.3Jul 10, 2026pre-release

    ## What's Changed * merge `DropWithHeap` / `DropWithVM` by @davidhewitt in https://github.com/pydantic/monty/pull/521 * fix interned longint ops by @davidhewitt in https://github.com/pydantic/monty/pull/547 * Add per-crate READMEs, rename `monty-cli` to `monty-runtime` by @samuelcolvin in https://github.com/pydantic/monty/pull/544 * migrate from ava to vitest by @davidhewitt in https://github.com/pydantic/monty/pull/548 * use web workers for browser wasm by @davidhewitt in https://github.com/pydantic/monty/pull/525 * remove cargo config by @davidhewitt in https://github.com/pydantic/monty/pull/546 * Monty-proto moves by @samuelcolvin in https://github.com/pydantic/monty/pull/549 * JSON error data, and type conversion to cpython by @samuelcolvin in https://github.com/pydantic/monty/pull/552 * Prep for `0.0.19-beta.3` by @samuelcolvin in https://github.com/pydantic/monty/pull/555 **Full Changelog**: https://github.com/pydantic/monty/compare/0.0.19-beta.2...0.0.19-beta.3

Commits per week

last 52 weeks
350Week of 2025-08-03: 0 commitsWeek of 2025-08-10: 0 commitsWeek of 2025-08-17: 0 commitsWeek of 2025-08-24: 0 commitsWeek of 2025-08-31: 0 commitsWeek of 2025-09-07: 0 commitsWeek of 2025-09-14: 0 commitsWeek of 2025-09-21: 0 commitsWeek of 2025-09-28: 0 commitsWeek of 2025-10-05: 0 commitsWeek of 2025-10-12: 0 commitsWeek of 2025-10-19: 0 commitsWeek of 2025-10-26: 0 commitsWeek of 2025-11-02: 0 commitsWeek of 2025-11-09: 0 commitsWeek of 2025-11-16: 22 commitsWeek of 2025-11-23: 35 commitsWeek of 2025-11-30: 12 commitsWeek of 2025-12-07: 13 commitsWeek of 2025-12-14: 4 commitsWeek of 2025-12-21: 9 commitsWeek of 2025-12-28: 12 commitsWeek of 2026-01-04: 12 commitsWeek of 2026-01-11: 31 commitsWeek of 2026-01-18: 20 commitsWeek of 2026-01-25: 17 commitsWeek of 2026-02-01: 23 commitsWeek of 2026-02-08: 16 commitsWeek of 2026-02-15: 29 commitsWeek of 2026-02-22: 11 commitsWeek of 2026-03-01: 13 commitsWeek of 2026-03-08: 19 commitsWeek of 2026-03-15: 7 commitsWeek of 2026-03-22: 14 commitsWeek of 2026-03-29: 7 commitsWeek of 2026-04-05: 7 commitsWeek of 2026-04-12: 26 commitsWeek of 2026-04-19: 15 commitsWeek of 2026-04-26: 8 commitsWeek of 2026-05-03: 12 commitsWeek of 2026-05-10: 15 commitsWeek of 2026-05-17: 11 commitsWeek of 2026-05-24: 24 commitsWeek of 2026-05-31: 3 commitsWeek of 2026-06-07: 1 commitsWeek of 2026-06-14: 2 commitsWeek of 2026-06-21: 8 commitsWeek of 2026-06-28: 14 commitsWeek of 2026-07-05: 20 commitsWeek of 2026-07-12: 5 commitsWeek of 2026-07-19: 35 commitsWeek of 2026-07-26: 17 commitsAug 3, 2025Jul 26, 2026
549 commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 0 commitsSun 1:00 — 1 commitsSun 2:00 — 0 commitsSun 3:00 — 0 commitsSun 4:00 — 0 commitsSun 5:00 — 0 commitsSun 6:00 — 0 commitsSun 7:00 — 0 commitsSun 8:00 — 0 commitsSun 9:00 — 7 commitsSun 10:00 — 5 commitsSun 11:00 — 3 commitsSun 12:00 — 5 commitsSun 13:00 — 6 commitsSun 14:00 — 4 commitsSun 15:00 — 8 commitsSun 16:00 — 3 commitsSun 17:00 — 9 commitsSun 18:00 — 7 commitsSun 19:00 — 6 commitsSun 20:00 — 3 commitsSun 21:00 — 1 commitsSun 22:00 — 8 commitsSun 23:00 — 7 commitsMon 0:00 — 4 commitsMon 1:00 — 1 commitsMon 2:00 — 0 commitsMon 3:00 — 0 commitsMon 4:00 — 0 commitsMon 5:00 — 1 commitsMon 6:00 — 0 commitsMon 7:00 — 2 commitsMon 8:00 — 1 commitsMon 9:00 — 8 commitsMon 10:00 — 6 commitsMon 11:00 — 7 commitsMon 12:00 — 9 commitsMon 13:00 — 8 commitsMon 14:00 — 11 commitsMon 15:00 — 12 commitsMon 16:00 — 6 commitsMon 17:00 — 3 commitsMon 18:00 — 4 commitsMon 19:00 — 1 commitsMon 20:00 — 11 commitsMon 21:00 — 4 commitsMon 22:00 — 5 commitsMon 23:00 — 4 commitsTue 0:00 — 2 commitsTue 1:00 — 0 commitsTue 2:00 — 0 commitsTue 3:00 — 0 commitsTue 4:00 — 0 commitsTue 5:00 — 0 commitsTue 6:00 — 1 commitsTue 7:00 — 1 commitsTue 8:00 — 3 commitsTue 9:00 — 1 commitsTue 10:00 — 14 commitsTue 11:00 — 8 commitsTue 12:00 — 5 commitsTue 13:00 — 11 commitsTue 14:00 — 7 commitsTue 15:00 — 7 commitsTue 16:00 — 6 commitsTue 17:00 — 8 commitsTue 18:00 — 5 commitsTue 19:00 — 4 commitsTue 20:00 — 6 commitsTue 21:00 — 8 commitsTue 22:00 — 5 commitsTue 23:00 — 3 commitsWed 0:00 — 4 commitsWed 1:00 — 0 commitsWed 2:00 — 1 commitsWed 3:00 — 0 commitsWed 4:00 — 0 commitsWed 5:00 — 3 commitsWed 6:00 — 0 commitsWed 7:00 — 1 commitsWed 8:00 — 4 commitsWed 9:00 — 4 commitsWed 10:00 — 8 commitsWed 11:00 — 3 commitsWed 12:00 — 6 commitsWed 13:00 — 7 commitsWed 14:00 — 5 commitsWed 15:00 — 6 commitsWed 16:00 — 3 commitsWed 17:00 — 6 commitsWed 18:00 — 6 commitsWed 19:00 — 5 commitsWed 20:00 — 6 commitsWed 21:00 — 2 commitsWed 22:00 — 0 commitsWed 23:00 — 0 commitsThu 0:00 — 2 commitsThu 1:00 — 0 commitsThu 2:00 — 1 commitsThu 3:00 — 3 commitsThu 4:00 — 1 commitsThu 5:00 — 1 commitsThu 6:00 — 0 commitsThu 7:00 — 1 commitsThu 8:00 — 0 commitsThu 9:00 — 3 commitsThu 10:00 — 4 commitsThu 11:00 — 5 commitsThu 12:00 — 4 commitsThu 13:00 — 6 commitsThu 14:00 — 5 commitsThu 15:00 — 2 commitsThu 16:00 — 6 commitsThu 17:00 — 6 commitsThu 18:00 — 8 commitsThu 19:00 — 1 commitsThu 20:00 — 5 commitsThu 21:00 — 4 commitsThu 22:00 — 1 commitsThu 23:00 — 1 commitsFri 0:00 — 2 commitsFri 1:00 — 1 commitsFri 2:00 — 0 commitsFri 3:00 — 0 commitsFri 4:00 — 1 commitsFri 5:00 — 0 commitsFri 6:00 — 0 commitsFri 7:00 — 1 commitsFri 8:00 — 3 commitsFri 9:00 — 1 commitsFri 10:00 — 7 commitsFri 11:00 — 8 commitsFri 12:00 — 4 commitsFri 13:00 — 9 commitsFri 14:00 — 3 commitsFri 15:00 — 4 commitsFri 16:00 — 13 commitsFri 17:00 — 4 commitsFri 18:00 — 3 commitsFri 19:00 — 1 commitsFri 20:00 — 1 commitsFri 21:00 — 4 commitsFri 22:00 — 2 commitsFri 23:00 — 3 commitsSat 0:00 — 0 commitsSat 1:00 — 0 commitsSat 2:00 — 1 commitsSat 3:00 — 0 commitsSat 4:00 — 1 commitsSat 5:00 — 1 commitsSat 6:00 — 4 commitsSat 7:00 — 1 commitsSat 8:00 — 5 commitsSat 9:00 — 4 commitsSat 10:00 — 1 commitsSat 11:00 — 3 commitsSat 12:00 — 5 commitsSat 13:00 — 3 commitsSat 14:00 — 4 commitsSat 15:00 — 5 commitsSat 16:00 — 5 commitsSat 17:00 — 5 commitsSat 18:00 — 3 commitsSat 19:00 — 6 commitsSat 20:00 — 9 commitsSat 21:00 — 7 commitsSat 22:00 — 4 commitsSat 23:00 — 3 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.
DateListRankStars gained
Feb 10, 2026daily#20+168
Feb 9, 2026daily#4+390
Feb 8, 2026daily#10+266
Feb 7, 2026daily#7+312
Feb 6, 2026daily#6+328
  • ultraworkers/claw-code

    An agent-managed museum exhibit, built in Rust with Gajae-Code / LazyCodex — developed and maintained with no human intervention.

    195K stars · Rust

  • ultraworkers/claw-code

    An agent-managed museum exhibit, built in Rust with Gajae-Code / LazyCodex — developed and maintained with no human intervention.

    194.9K stars · Rust

  • ultraworkers/claw-code

    An agent-managed museum exhibit, built in Rust with Gajae-Code / LazyCodex — developed and maintained with no human intervention.

    194.9K stars · Rust

  • farion1231/cc-switch

    A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

    125.4K stars · Rust

  • denoland/deno

    A modern runtime for JavaScript and TypeScript.

    108.2K stars · Rust

  • openai/codex

    Lightweight coding agent that runs in your terminal

    104.6K stars · Rust