[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-5586":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":23,"hasPages":23,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":16,"starSnapshotCount":16,"syncStatus":29,"lastSyncTime":30,"discoverSource":31},5586,"monty","pydantic\u002Fmonty","pydantic","A minimal, secure Python interpreter written in Rust for use by AI","",null,"Rust",7626,367,42,53,0,86,326,471,467,38.7,"MIT License",false,"main",[],"2026-06-12 02:01:12","\u003Cdiv align=\"center\">\n  \u003Ch1>Monty\u003C\u002Fh1>\n\u003C\u002Fdiv>\n\u003Cdiv align=\"center\">\n  \u003Ch3>A minimal, secure Python interpreter written in Rust for use by AI.\u003C\u002Fh3>\n\u003C\u002Fdiv>\n\u003Cdiv align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fpydantic\u002Fmonty\u002Factions\u002Fworkflows\u002Fci.yml?query=branch%3Amain\">\u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fpydantic\u002Fmonty\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg\" alt=\"CI\">\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fcodspeed.io\u002Fpydantic\u002Fmonty?utm_source=badge\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCodSpeed-Performance%20Tracked-blue?logo=data:image\u002Fsvg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOCAwTDAgOEw4IDE2TDE2IDhMOCAwWiIgZmlsbD0id2hpdGUiLz48L3N2Zz4=\" alt=\"Codspeed\">\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fcodecov.io\u002Fgh\u002Fpydantic\u002Fmonty\">\u003Cimg src=\"https:\u002F\u002Fcodecov.io\u002Fgh\u002Fpydantic\u002Fmonty\u002Fgraph\u002Fbadge.svg?token=HX4RDQX5OG\" alt=\"Coverage\">\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fpypi.python.org\u002Fpypi\u002Fpydantic-monty\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fv\u002Fpydantic-monty.svg\" alt=\"PyPI\">\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fpydantic\u002Fmonty\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fpyversions\u002Fpydantic-monty.svg\" alt=\"versions\">\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fpydantic\u002Fmonty\u002Fblob\u002Fmain\u002FLICENSE\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flicense\u002Fpydantic\u002Fmonty.svg?v=2\" alt=\"license\">\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Flogfire.pydantic.dev\u002Fdocs\u002Fjoin-slack\u002F\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FSlack-Join%20Slack-4A154B?logo=slack\" alt=\"Join Slack\" \u002F>\u003C\u002Fa>\n\u003C\u002Fdiv>\n\n---\n\n**Experimental** - This project is still in development, and not ready for the prime time.\n\nA minimal, secure Python interpreter written in Rust for use by AI.\n\nMonty avoids the cost, latency, complexity and general faff of using a full container based sandbox for running LLM generated code.\n\nInstead, 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.\n\nWhat Monty **can** do:\n\n- Run a reasonable subset of Python code - enough for your agent to express what it wants to do\n- Completely block access to the host environment: filesystem, env variables and network access are all implemented via external function calls the developer can control\n- Call functions on the host - only functions you give it access to\n- Run typechecking - monty supports full modern python type hints and comes with [ty](https:\u002F\u002Fdocs.astral.sh\u002Fty\u002F) included in a single binary to run typechecking\n- Be snapshotted to bytes at external function calls, meaning you can store the interpreter state in a file or database, and resume later\n- Startup extremely fast (\u003C1μs to go from code to execution result), and has runtime performance that is similar to CPython (generally between 5x faster and 5x slower)\n- Be called from Rust, Python, or Javascript - because Monty has no dependencies on cpython, you can use it anywhere you can run Rust\n- Control resource usage - Monty can track memory usage, allocations, stack depth, and execution time and cancel execution if it exceeds preset limits\n- Collect stdout and stderr and return it to the caller\n- Run async or sync code on the host via async or sync code on the host\n- Use a small subset of the standard library: `sys`, `os`, `typing`, `asyncio`, `re`, `datetime`, `json`, `dataclasses` (soon)\n\nWhat Monty **cannot** do:\n\n- Use the rest of the standard library\n- Use third party libraries (like Pydantic), support for external python library is not a goal\n- define classes (support should come soon)\n- use match statements (again, support should come soon)\n\n---\n\nIn short, Monty is extremely limited and designed for **one** use case:\n\n**To run code written by agents.**\n\nFor motivation on why you might want to do this, see:\n\n- [Codemode](https:\u002F\u002Fblog.cloudflare.com\u002Fcode-mode\u002F) from Cloudflare\n- [Programmatic Tool Calling](https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fagents-and-tools\u002Ftool-use\u002Fprogrammatic-tool-calling) from Anthropic\n- [Code Execution with MCP](https:\u002F\u002Fwww.anthropic.com\u002Fengineering\u002Fcode-execution-with-mcp) from Anthropic\n- [Smol Agents](https:\u002F\u002Fgithub.com\u002Fhuggingface\u002Fsmolagents) from Hugging Face\n\nIn 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.\n\n**Note:** Monty will (soon) be used to implement `codemode` in [Pydantic AI](https:\u002F\u002Fgithub.com\u002Fpydantic\u002Fpydantic-ai)\n\n## Usage\n\nMonty can be called from Python, JavaScript\u002FTypeScript or Rust.\n\n### Python\n\nTo install:\n\n```bash\nuv add pydantic-monty\n```\n\n(Or `pip install pydantic-monty` for the boomers)\n\nUsage:\n\n```python\nfrom typing import Any\n\nimport pydantic_monty\n\ncode = \"\"\"\nasync def agent(prompt: str, messages: Messages):\n    while True:\n        print(f'messages so far: {messages}')\n        output = await call_llm(prompt, messages)\n        if isinstance(output, str):\n            return output\n        messages.extend(output)\n\nawait agent(prompt, [])\n\"\"\"\n\ntype_definitions = \"\"\"\nfrom typing import Any\n\nMessages = list[dict[str, Any]]\n\nasync def call_llm(prompt: str, messages: Messages) -> str | Messages:\n    raise NotImplementedError()\n\nprompt: str = ''\n\"\"\"\n\nm = pydantic_monty.Monty(\n    code,\n    inputs=['prompt'],\n    script_name='agent.py',\n    type_check=True,\n    type_check_stubs=type_definitions,\n)\n\n\nMessages = list[dict[str, Any]]\n\n\nasync def call_llm(prompt: str, messages: Messages) -> str | Messages:\n    if len(messages) \u003C 2:\n        return [{'role': 'system', 'content': 'example response'}]\n    else:\n        return f'example output, message count {len(messages)}'\n\n\nasync def main():\n    output = await m.run_async(\n        inputs={'prompt': 'testing'},\n        external_functions={'call_llm': call_llm},\n    )\n    print(output)\n    #> example output, message count 2\n\n\nif __name__ == '__main__':\n    import asyncio\n\n    asyncio.run(main())\n```\n\n#### Iterative Execution with External Functions\n\nUse `start()` and `resume()` to handle external function calls iteratively,\ngiving you control over each call:\n\n```python\nimport pydantic_monty\n\ncode = \"\"\"\ndata = fetch(url)\nlen(data)\n\"\"\"\n\nm = pydantic_monty.Monty(code, inputs=['url'])\n\n# Start execution - pauses when fetch() is called\nresult = m.start(inputs={'url': 'https:\u002F\u002Fexample.com'})\n\nprint(type(result))\n#> \u003Cclass 'pydantic_monty.FunctionSnapshot'>\nprint(result.function_name)  # fetch\n#> fetch\nprint(result.args)\n#> ('https:\u002F\u002Fexample.com',)\n\n# Perform the actual fetch, then resume with the result\nresult = result.resume({'return_value': 'hello world'})\n\nprint(type(result))\n#> \u003Cclass 'pydantic_monty.MontyComplete'>\nprint(result.output)\n#> 11\n```\n\n#### Serialization\n\nBoth `Monty` and snapshot types like `FunctionSnapshot` can be serialized to bytes and restored later.\nThis allows caching parsed code or suspending execution across process boundaries:\n\n```python\nimport pydantic_monty\n\n# Serialize parsed code to avoid re-parsing\nm = pydantic_monty.Monty('x + 1', inputs=['x'])\ndata = m.dump()\n\n# Later, restore and run\nm2 = pydantic_monty.Monty.load(data)\nprint(m2.run(inputs={'x': 41}))\n#> 42\n\n# Serialize execution state mid-flight\nm = pydantic_monty.Monty('fetch(url)', inputs=['url'])\nprogress = m.start(inputs={'url': 'https:\u002F\u002Fexample.com'})\nstate = progress.dump()\n\n# Later, restore and resume (e.g., in a different process)\nprogress2 = pydantic_monty.load_snapshot(state)\nresult = progress2.resume({'return_value': 'response data'})\nprint(result.output)\n#> response data\n```\n\n### Rust\n\n```rust\nuse monty::{MontyRun, MontyObject, NoLimitTracker, PrintWriter};\n\nlet code = r#\"\ndef fib(n):\n    if n \u003C= 1:\n        return n\n    return fib(n - 1) + fib(n - 2)\n\nfib(x)\n\"#;\n\nlet runner = MontyRun::new(code.to_owned(), \"fib.py\", vec![\"x\".to_owned()]).unwrap();\nlet result = runner.run(vec![MontyObject::Int(10)], NoLimitTracker, PrintWriter::Stdout).unwrap();\nassert_eq!(result, MontyObject::Int(55));\n```\n\n#### Serialization\n\n`MontyRun` and `RunProgress` can be serialized using the `dump()` and `load()` methods:\n\n```rust\nuse monty::{MontyRun, MontyObject, NoLimitTracker, PrintWriter};\n\n\u002F\u002F Serialize parsed code\nlet runner = MontyRun::new(\"x + 1\".to_owned(), \"main.py\", vec![\"x\".to_owned()]).unwrap();\nlet bytes = runner.dump().unwrap();\n\n\u002F\u002F Later, restore and run\nlet runner2 = MontyRun::load(&bytes).unwrap();\nlet result = runner2.run(vec![MontyObject::Int(41)], NoLimitTracker, PrintWriter::Stdout).unwrap();\nassert_eq!(result, MontyObject::Int(42));\n```\n\n## PydanticAI Integration\n\nMonty will power code-mode in\n[Pydantic AI](https:\u002F\u002Fgithub.com\u002Fpydantic\u002Fpydantic-ai). Instead of making\nsequential tool calls, the LLM writes Python code that calls your tools\nas functions and Monty executes it safely.\n\n```python test=\"skip\"\nimport asyncio\nimport json\n\nimport logfire\nfrom httpx import AsyncClient\nfrom pydantic_ai import Agent, RunContext\nfrom pydantic_ai.toolsets.code_mode import CodeModeToolset\nfrom pydantic_ai.toolsets.function import FunctionToolset\nfrom typing_extensions import TypedDict\n\nlogfire.configure()\nlogfire.instrument_pydantic_ai()\n\n\nclass LatLng(TypedDict):\n    lat: float\n    lng: float\n\n\nweather_toolset: FunctionToolset[AsyncClient] = FunctionToolset()\n\n\n@weather_toolset.tool\nasync def get_lat_lng(\n    ctx: RunContext[AsyncClient], location_description: str\n) -> LatLng:\n    \"\"\"Get the latitude and longitude of a location.\"\"\"\n    # NOTE: the response here will be random, and is not related to the location description.\n    r = await ctx.deps.get(\n        'https:\u002F\u002Fdemo-endpoints.pydantic.workers.dev\u002Flatlng',\n        params={'location': location_description},\n    )\n    r.raise_for_status()\n    return json.loads(r.content)\n\n\n@weather_toolset.tool\nasync def get_temp(ctx: RunContext[AsyncClient], lat: float, lng: float) -> float:\n    \"\"\"Get the temp at a location.\"\"\"\n    # NOTE: the responses here will be random, and are not related to the lat and lng.\n    r = await ctx.deps.get(\n        'https:\u002F\u002Fdemo-endpoints.pydantic.workers.dev\u002Fnumber',\n        params={'min': 10, 'max': 30},\n    )\n    r.raise_for_status()\n    return float(r.text)\n\n\n@weather_toolset.tool\nasync def get_weather_description(\n    ctx: RunContext[AsyncClient], lat: float, lng: float\n) -> str:\n    \"\"\"Get the weather description at a location.\"\"\"\n    # NOTE: the responses here will be random, and are not related to the lat and lng.\n    r = await ctx.deps.get(\n        'https:\u002F\u002Fdemo-endpoints.pydantic.workers.dev\u002Fweather',\n        params={'lat': lat, 'lng': lng},\n    )\n    r.raise_for_status()\n    return r.text\n\n\nagent = Agent(\n    'gateway\u002Fanthropic:claude-sonnet-4-5',\n    # toolsets=[weather_toolset],\n    toolsets=[CodeModeToolset(weather_toolset)],\n    deps_type=AsyncClient,\n)\n\n\nasync def main():\n    async with AsyncClient() as client:\n        await agent.run('Compare the weather of London, Paris, and Tokyo.', deps=client)\n\n\nif __name__ == '__main__':\n    asyncio.run(main())\n```\n\n## Community Bindings\n\n- **Go**: [gomonty](https:\u002F\u002Fgithub.com\u002Fewhauser\u002Fgomonty\u002F) - Go bindings for the Monty interpreter\n\n# Alternatives\n\nThere are generally two responses when you show people Monty:\n\n1. Oh my god, this solves so many problems, I want it.\n2. Why not X?\n\nWhere 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.\n\nI'll try to run through the most obvious alternatives, and why there aren't right for what we wanted.\n\nNOTE: 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.\n\n| Tech               | Language completeness | Security     | Start latency | FOSS       | Setup complexity | File mounting  | Snapshotting |\n| ------------------ | --------------------- | ------------ | ------------- | ---------- | ---------------- | -------------- | ------------ |\n| Monty              | partial               | strict       | 0.06ms        | free \u002F OSS | easy             | easy           | easy         |\n| Docker             | full                  | good         | 195ms         | free \u002F OSS | intermediate     | easy           | intermediate |\n| Pyodide            | full                  | poor         | 2800ms        | free \u002F OSS | intermediate     | easy           | hard         |\n| starlark-rust      | very limited          | good         | 1.7ms         | free \u002F OSS | easy             | not available? | impossible?  |\n| WASI \u002F Wasmer      | partial, almost full  | strict       | 66ms          | free \\*    | intermediate     | easy           | intermediate |\n| sandboxing service | full                  | strict       | 1033ms        | not free   | intermediate     | hard           | intermediate |\n| YOLO Python        | full                  | non-existent | 0.1ms \u002F 30ms  | free \u002F OSS | easy             | easy \u002F scary   | hard         |\n\nSee [.\u002Fscripts\u002Fstartup_performance.py](scripts\u002Fstartup_performance.py) for the script used to calculate the startup performance numbers.\n\nDetails on each row below:\n\n### Monty\n\n- **Language completeness**: No classes (yet), limited stdlib, no third-party libraries\n- **Security**: Explicitly controlled filesystem, network, and env access, strict limits on execution time and memory usage\n- **Start latency**: Starts in microseconds\n- **Setup complexity**: just `pip install pydantic-monty` or `npm install @pydantic\u002Fmonty`, ~4.5MB download\n- **File mounting**: Strictly controlled, see [#85](https:\u002F\u002Fgithub.com\u002Fpydantic\u002Fmonty\u002Fpull\u002F85)\n- **Snapshotting**: Monty's pause and resume functionality with `dump()` and `load()` makes it trivial to pause, resume and fork execution\n\n### Docker\n\n- **Language completeness**: Full CPython with any library\n- **Security**: Process and filesystem isolation, network policies, but container escapes exist, memory limitation is possible\n- **Start latency**: Container startup overhead (~195ms measured)\n- **Setup complexity**: Requires Docker daemon, container images, orchestration, `python:3.14-alpine` is 50MB - docker can't be installed from PyPI\n- **File mounting**: Volume mounts work well\n- **Snapshotting**: Possible with durable execution solutions like Temporal, or snapshotting an image and saving it as a Docker image.\n\n### Pyodide\n\n- **Language completeness**: Full CPython compiled to WASM, almost all libraries available\n- **Security**: Relies on browser\u002FWASM 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\u002Fimpossible to enforce with deno\n- **Start latency**: WASM runtime loading is slow (~2800ms cold start)\n- **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\n- **File mounting**: Virtual filesystem via browser APIs\n- **Snapshotting**: Possible with durable execution solutions like Temporal presumably, but hard\n\n### starlark-rust\n\nSee [starlark-rust](https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fstarlark-rust).\n\n- **Language completeness**: Configuration language, not Python - no classes, exceptions, async\n- **Security**: Deterministic and hermetic by design\n- **Start latency**: runs embedded in the process like Monty, hence impressive startup time\n- **Setup complexity**: Usable in python via [starlark-pyo3](https:\u002F\u002Fgithub.com\u002Finducer\u002Fstarlark-pyo3)\n- **File mounting**: No file handling by design AFAIK?\n- **Snapshotting**: Impossible AFAIK?\n\n### WASI \u002F Wasmer\n\nRunning Python in WebAssembly via [Wasmer](https:\u002F\u002Fwasmer.io\u002F).\n\n- **Language completeness**: Full CPython, pure Python external packages work via mounting, external packages with C bindings don't work\n- **Security**: In principle WebAssembly should provide strong sandboxing guarantees.\n- **Start latency**: The [wasmer](https:\u002F\u002Fpypi.org\u002Fproject\u002Fwasmer\u002F) 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.\n- **Setup complexity**: wasmer download is 100mb, the \"python\u002Fpython\" package is 50mb.\n- **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\u002Fpython` wasmer package](https:\u002F\u002Fwasmer.io\u002Fpython\u002Fpython) 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)_\n- **File mounting**: Supported\n- **Snapshotting**: Supported via journaling\n\n### sandboxing service\n\nServices like [Daytona](https:\u002F\u002Fdaytona.io), [E2B](https:\u002F\u002Fe2b.dev), [Modal](https:\u002F\u002Fmodal.com).\n\nThere are similar challenges, more setup complexity but lower network latency for setting up your own sandbox setup with k8s.\n\n- **Language completeness**: Full CPython with any library\n- **Security**: Professionally managed container isolation\n- **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\n- **FOSS**: Pay per execution or compute time, some implementations are open source\n- **Setup complexity**: API integration, auth tokens - fine for startups but generally a non-start for enterprises\n- **File mounting**: Upload\u002Fdownload via API calls\n- **Snapshotting**: Possible with durable execution solutions like Temporal, also the services offer some solutions for this, I think based con docker containers\n\n### YOLO Python\n\nRunning Python directly via `exec()` (~0.1ms) or subprocess (~30ms).\n\n- **Language completeness**: Full CPython with any library\n- **Security**: None - full filesystem, network, env vars, system commands\n- **Start latency**: Near-zero for `exec()`, ~30ms for subprocess\n- **Setup complexity**: None\n- **File mounting**: Direct filesystem access (that's the problem)\n- **Snapshotting**: Possible with durable execution solutions like Temporal\n","Monty 是一个专为AI设计的、用Rust编写的最小化且安全的Python解释器。它通过避免使用完整容器沙箱来运行由大型语言模型生成的代码，从而降低了成本、延迟和复杂性。核心功能包括执行合理的Python子集、完全隔离主机环境（文件系统、环境变量及网络访问均需开发者控制）、支持现代Python类型提示、极快的启动时间（小于1微秒）以及与CPython相近的运行时性能。适用于需要快速、安全地执行AI生成Python代码的场景，如嵌入式代理或对性能有严格要求的应用程序中。此外，Monty还能够被Rust、Python或JavaScript调用，并提供资源使用监控能力。",2,"2026-06-11 03:04:13","top_language"]