Skip to main content

py-runner

License: AGPL-3.0-or-later Python >=3.10 TestPyPI Docs

Persistent Python code runner: string in, JSON out. A lightweight, dependency-free, ipykernel-like execution library — no Jupyter server, no ZMQ, no required third-party packages.

📖 Full documentation: https://rightfix.github.io/py-runner-docs/

Persistent Python code runner: string in, JSON out. A lightweight, dependency-free, ipykernel-like execution library — no Jupyter server, no ZMQ, no required third-party packages.

from py_runner import Kernel

k = Kernel()
k.execute("x = 40 + 2")
print(k.execute("x + 1"))
# {"output": null,
#  "display": [{"type": "text/plain", "data": "43"}],
#  "error": null, "execution_count": 2, "execution_time": 0.0001}

Install

pip install py-runner-kernel

Requires Python >= 3.10. Zero runtime dependencies.

Quickstart

from py_runner import Kernel, execute, execute_json

# Module-level shared kernel
execute("import math")
print(execute_json("math.sqrt(16)"))

# Isolated session kernel (one per user/request)
k = Kernel(on_input=lambda prompt: "bob", max_history=100)
r = k.execute('name = input("who? ")\nname.upper()')
assert r["display"][0]["data"] == "'BOB'"

Each result is a JSON-serializable dict:

key value
output captured stdout (str | None)
display rich values ([{type, data}]: text/plain, text/html, image/png base64, …)
error traceback / warning text (str | None)
execution_count incrementing cell number
execution_time seconds (float)

Features

  • Persistent namespace with Jupyter-style _, __, ___ and bounded Out[N] history
  • Last-expression display — DataFrames as HTML, arrays/tensors summarized, matplotlib figures as PNG, trailing ; suppresses output
  • Magics: %time, %timeit, %who/%whos, %run, %pip, !shell, %reset
  • Long runs: timeout=, cooperative interrupt(), on_stream chunks, on_heartbeat for silent fit() loops, tqdm \r collapsing, logging/warnings capture
  • Sandboxing: allow_shell=False, allow_pip=False, set_address_space_limit(mb) (Unix), reset(keep_imports=True)
  • CLI: py-runner -c "1+1", py-runner script.py, ... | py-runner, with --timeout, --no-shell, --no-pip

CLI

py-runner -c "print(2 + 3)"
py-runner analysis.py --timeout 300 > result.json
cat cell.py | py-runner
python -m py_runner -c "1+1"

Project structure

py_runner/
├── __init__.py   # public API: Kernel, execute, execute_json, reset, main
├── kernel.py     # persistent execution kernel (threaded, timeouts, input)
├── magics.py     # %time, %pip, !shell, … (sandbox-flaggable)
├── display.py    # rich display collector (pandas/numpy/PIL/matplotlib)
├── streams.py    # thread-routed streaming stdout, tqdm \r handling
└── utils.py      # guarded imports, address-space limit helper

Development

uv sync            # create .venv
uv run python -c "from py_runner import execute; print(execute('1+1'))"
uv build           # wheel + sdist in dist/
uv publish --publish-url https://test.pypi.org/legacy/  # trial run

HTTP server

py-runner-serve --host 127.0.0.1 --port 8000 --max-sessions 100
S=$(curl -s -X POST localhost:8000/sessions | python3 -c "import sys,json; print(json.load(sys.stdin)['session_id'])")
curl -s -X POST localhost:8000/execute \
  -d "{\"session_id\":\"$S\",\"code\":\"x = 40 + 2\"}"
curl -s -X POST localhost:8000/execute \
  -d "{\"session_id\":\"$S\",\"code\":\"x + 1\"}"        # display: 43 (state kept)
curl -s -X POST localhost:8000/interrupt \
  -d "{\"session_id\":\"$S\"}"
curl -s localhost:8000/sessions                          # list live sessions
curl -s -X DELETE localhost:8000/sessions/$S             # destroy session

Sessions are server-generated UUIDs, live until deleted (no idle timeout), and isolated per ID. Kernels default to allow_shell=false, allow_pip=false; pass {"allow_shell": true} to POST /sessions to relax per session.

License

AGPL-3.0-or-later — see LICENSE. Note the network clause (§13): if you serve a modified version over a network, you must offer its source to those users.

Metadata

Release files for py-runner-kernel 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for py-runner-kernel 0.1.2
File Size Uploaded Provenance Actions
py_runner_kernel-0.1.2.tar.gz 26.3 kB Without provenance Details for py_runner_kernel-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for py-runner-kernel 0.1.2
File Interpreter ABI Platform Actions
py_runner_kernel-0.1.2-py3-none-any.whl Python 3 none any Details for py_runner_kernel-0.1.2-py3-none-any.whl

Total release size: 56.1 kB

Release files / py_runner_kernel-0.1.2.tar.gz

Download URL py_runner_kernel-0.1.2.tar.gz
Size 26.3 kB
Tags Source
SHA-256 checksum
How to use checksums
60d7f74f1ba6a5d58e91708d947ca1a68d486ce87f8226d8ce29b1175e626448
BLAKE2b-256 checksum
How to use checksums
54bb5af3b0c08c71492e9e3041e0974810a33aab474e5f50faa9243b6afe5e1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / py_runner_kernel-0.1.2-py3-none-any.whl

Download URL py_runner_kernel-0.1.2-py3-none-any.whl
Size 29.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
346f03af9e1d73680ff93b20890f3263e5f6c707ad17826f7fcbca1809540b2e
BLAKE2b-256 checksum
How to use checksums
8ba15fc46b7d60f6e3307e1255c136746cd7995e7e72aeee4827e3a1ee30f735
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for py-runner-kernel 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page