Skip to main content

Sandboxed Python interpreter for untrusted and LLM-generated code

Project description

interpretthis

Run untrusted or LLM-generated Python inside a sandbox — from Python.

interpretthis evaluates a Python AST under resource limits and an allowlisted language surface. It is not CPython in a subprocess and not a container: the interpreter is written in Rust and simply has no filesystem, network, or process access to give away. Capabilities reach the script only through tools you inject.

pip install interpretthis

Why

You want a model to write Python that transforms data, scores records, or orchestrates your tools — without handing it a real Python process. exec() in a try block is not a sandbox. This is the evaluator: you own the tools, the limits, and what happens to the result.

Quick start

from interpretthis import Interpreter

def double(n: int) -> int:
    return n * 2

interp = Interpreter(tools={"double": double})

result = interp.execute("answer = double(n=x)\nprint(answer)", {"x": 21})

print(result.stdout)              # '42\n'
print(interp.get_variable("answer"))  # 42

Failure is data, not an exception. execute returns an ExecutionResult carrying stdout and error, because a script that prints three lines and then raises has told you something useful in both halves — and that pair is exactly what you feed back to a model:

result = interp.execute("print('working...')\nresult = 1 / 0")

result.ok        # False
result.stdout    # 'working...\n'
result.error     # PythonException('ZeroDivisionError: division by zero ...')
result.check()   # raises, if you would rather

Tools

A tool is any callable — sync or async. The script calls it by name; arguments arrive as keywords.

import aiohttp

async def fetch(url: str) -> str:
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

interp = Interpreter(tools={"fetch": fetch})
interp.execute("page = fetch(url='https://example.com')")

Coroutine tools work from the blocking execute() too — the interpreter runs them on a background event loop it starts on first use. Inside async code, use execute_async instead, which schedules tool coroutines on your loop so they may await objects bound to it (an aiohttp session, an asyncio.Lock):

result = await interp.execute_async("page = fetch(url='https://example.com')")

Tools that are safe to overlap can say so, and the interpreter will run them concurrently:

from interpretthis import Tool

interp = Interpreter(tools={"fetch": Tool(fetch, parallelizable=True)})

A tool that raises becomes a catchable Exception inside the script, and a ToolError for you if the script does not catch it.

Limits

from interpretthis import Config

interp = Interpreter(config=Config(
    max_operations=1_000_000,
    max_memory_bytes=64 * 1024 * 1024,
    max_execution_time=5.0,        # seconds
    max_recursion_depth=100,
))

Exceeding one stops the script with a LimitExceededError — with whatever it printed before then still in stdout.

Resumable state

Variables and classes persist across execute calls on one interpreter, and can be checkpointed:

blob = interp.export_state()   # bytes; sign or encrypt them yourself

later = Interpreter()
later.import_state(blob)
later.execute("counter = counter + 1")

What it is not

  • Not full CPython. A large subset, deliberately chosen. See CONFORMANCE.md.
  • Tools are trusted. A tool with side effects extends the trust boundary by exactly as much as it does. That is the point, and it is your call.
  • async/await inside the script is not supported. Await around execute, not within it.

Security boundary: THREAT_MODEL.md.

Types

The package ships py.typed and is checked under mypy --strict.

Licence

MIT OR Apache-2.0, at your option.

Binary wheels statically link malachite (LGPL-3.0-only), reached transitively via the Python parser. See the bundled NOTICE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

interpretthis-0.4.1.tar.gz (912.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

interpretthis-0.4.1-cp311-abi3-win_amd64.whl (6.8 MB view details)

Uploaded CPython 3.11+Windows x86-64

interpretthis-0.4.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

interpretthis-0.4.1-cp311-abi3-macosx_11_0_arm64.whl (6.5 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

interpretthis-0.4.1-cp311-abi3-macosx_10_12_x86_64.whl (6.5 MB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file interpretthis-0.4.1.tar.gz.

File metadata

  • Download URL: interpretthis-0.4.1.tar.gz
  • Upload date:
  • Size: 912.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for interpretthis-0.4.1.tar.gz
Algorithm Hash digest
SHA256 8802e57bcca7bcf8e2197246c1970f54799f1021892781d5ac36742ae354813d
MD5 0fcfbb879e7e3bcf4ee5eeee009de9ce
BLAKE2b-256 d0e505185a901fc55040b610b42da8e1b2e984c3513bf1b7cfa23503015258ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for interpretthis-0.4.1.tar.gz:

Publisher: release-python.yml on moderately-ai/interpretthis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file interpretthis-0.4.1-cp311-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for interpretthis-0.4.1-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 060df40afd77042d0b7b259f6358b847452b3c0f90101ac98c3986039f4393d5
MD5 316ecbc7d511ae2df4d313fca63c3799
BLAKE2b-256 fd22a810969b74fbc70a14a5ce757f9373135d2b270a9cfb6584ab34fb2d8ac1

See more details on using hashes here.

Provenance

The following attestation bundles were made for interpretthis-0.4.1-cp311-abi3-win_amd64.whl:

Publisher: release-python.yml on moderately-ai/interpretthis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file interpretthis-0.4.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for interpretthis-0.4.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 743a30fa68f5e224158710f5988e92ba2d70ad3cbf4a6112a98363ddcef0ee53
MD5 1732c111cdb4d789033585176d06b5fb
BLAKE2b-256 449a1e6770baec2048b24315d06407f58138755a02fc839cc5682cb3841c4611

See more details on using hashes here.

Provenance

The following attestation bundles were made for interpretthis-0.4.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release-python.yml on moderately-ai/interpretthis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file interpretthis-0.4.1-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for interpretthis-0.4.1-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a8ece9f4a504d2df6965fec56f75aec9d798c464734ca2a6b4d671cdd849fb6f
MD5 80dbfdc1fba1e969be6324ea60054353
BLAKE2b-256 a24c5362647519791942922a27820715d11bf98c5ad05b37019f2aba3f5c29c7

See more details on using hashes here.

Provenance

The following attestation bundles were made for interpretthis-0.4.1-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: release-python.yml on moderately-ai/interpretthis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file interpretthis-0.4.1-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for interpretthis-0.4.1-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 2946374eeb078fad71a4c314df72c5205bf49bd26c69c9d71de5d2eaa536f652
MD5 3852721f7255bf7f8667ea2a4bc08b45
BLAKE2b-256 97a4dd48a0d87b99b9da4441113db4ed83d1e1c049df5855a51a69c6ce17b77a

See more details on using hashes here.

Provenance

The following attestation bundles were made for interpretthis-0.4.1-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: release-python.yml on moderately-ai/interpretthis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page