Skip to main content

peno

A JS sandbox for AI agents

peno = python + deno: a Python-embeddable JavaScript sandbox built on deno_core and V8.

Run untrusted, LLM-generated JavaScript safely in Python — real V8, real isolation, real tool-calling.


Publish PyPI License Docs

Documentation · Examples · Issues

16-18x faster repeat execution via context-isolated isolate pooling — ~3 ms cold Runtime() start vs. ~167-185 µs per pooled IsolatePool checkout+eval, measured with Criterion and pytest-benchmark, with a dedicated test proving no state leaks between checkouts. Proven, not claimed — see BENCHMARKS.md.

For tool-calling workloads, retain one Runtime per session instead: a warm Runtime does a full host tool call in ~13.4 µs — ~12x faster than a pool checkout, which cannot host tool calls at all. See docs/tool-calling-at-pool-speed.md.

What this is

Agent frameworks and tool-execution runtimes increasingly need to run JavaScript the model itself wrote — a code-generation step, a small data transform, a "call this JS snippet to compute the answer" tool. That code is untrusted by construction. peno embeds a real V8 isolate per runtime (via Rust/PyO3) so that code runs with no filesystem, no network, and no ambient Node.js APIs by default, with heap and wall-clock limits you set, and a real way to kill it if it doesn't stop on its own.

It is not a general "embed any JS anywhere" library and not a JS interpreter reimplemented in Python — it's V8, the same engine behind Chrome and Node.js, so the JS your model writes actually behaves like JS.

import peno

peno.bind_function("add", lambda a, b: a + b)
print(peno.eval("add(2, 3)"))  # 5

Why it's different

  • Real V8, not a toy interpreter. Every language quirk, every standard library method, every performance characteristic your model expects from "JavaScript" is the real thing.
  • Cross-thread termination that actually works. A watchdog thread calling .terminate() on a runaway while(true){} used to panic instead of stopping the code (pyo3_runtime.PanicException: Runtime is unsendable, but sent to another thread) — a real bug in the upstream design that meant a stuck agent tool call couldn't be killed from outside. TerminationHandle fixes this: it exposes only the Send + Sync part of V8's isolate handle, so a watchdog on a separate thread can interrupt execution safely. See PATCH.md for the full root cause and proof; tests/test_termination_handle.py is the regression test.
  • Context-isolated pooling, so speed doesn't cost you isolation. A cold V8 isolate costs ~3 ms to create; IsolatePool keeps a small set of them warm and hands out a brand-new, empty V8 Context on every checkout — the isolate is reused, but no JS-visible global state (globalThis, etc.) ever survives from one caller to the next, even when they land on the same underlying isolate. Measured: ~3 ms cold-start → ~170-185 µs pooled, ~16-18x, with a dedicated test proving a globalThis value set in one checkout is gone (typeof x === 'undefined') in the next. See BENCHMARKS.md and src/runtime/pool.rs for the numbers and the reasoning.
  • A host-callback bridge for tool-calling from JS. bind_function/ bind_object let the sandboxed JS call back into Python — the primitive an agent needs when the model's JS wants to invoke a real tool, not just compute a value. ToolBridge builds the product shape on top: hand it a dict of callables and get a call budget, fail-closed name checking, and JS-catchable typed errors, instead of hand-rolling all three.
  • Tool errors JS can branch on. A Python exception raised inside a bound tool reaches JavaScript as a real Error whose name is the exception's class name, so the model's JS can tell "bad arguments" from "rate limited" from "tool not found" with a plain catch (e) { if (e.name === ...) } — rather than string-matching one flattened TypeError. The same name/message shape a JS exception already carries into Python, so the two directions are symmetric.
  • console.log you can actually read. Sandboxed console.* output can be routed back to a Python callback with RuntimeConfig(on_console=...), receiving structured (level, args) — the single most common thing you want when showing a model what its own script printed. Composes with enable_console rather than replacing it.

Get Started

pip install peno  # or uv pip install peno

Requires Python 3.10+ on macOS or Linux. peno is experimental — expect breaking changes between versions.

Quickstart: sandboxed eval, tool-calling, and a timeout

import asyncio

from peno import Runtime, RuntimeConfig

# Cap memory; the runtime terminates itself if JS tries to exceed it.
config = RuntimeConfig(max_heap_size=10 * 1024 * 1024)  # 10 MB


async def main():
    with Runtime(config) as runtime:
        # The tool-calling primitive: expose a Python function to the sandboxed JS.
        def get_weather(city: str) -> str:
            return f"72F and sunny in {city}"

        runtime.bind_function("getWeather", get_weather)

        # Model-generated JS calling back into your tool.
        result = runtime.eval("getWeather('Zurich')")
        print(result)  # "72F and sunny in Zurich"

        # Enforce a wall-clock timeout on code that might not terminate.
        try:
            await runtime.eval_async("while (true) {}", timeout=2.0)
        except Exception as exc:
            print(f"killed a runaway eval after 2s: {exc}")


asyncio.run(main())

Running an untrusted sync eval() you can't await? Grab a TerminationHandle before the call and .terminate() it from a watchdog thread — see tests/test_termination_handle.py for the exact pattern (and the bug it fixed, in PATCH.md).

Many tools, one budget

When the model gets more than one tool, ToolBridge gives you the whole surface — budget, name checking, typed errors — in one object:

from peno import Runtime, ToolBridge

bridge = ToolBridge(
    {"get_weather": get_weather, "send_email": send_email},
    max_calls=50,  # total tool calls this agent turn may make
)

with Runtime() as runtime:
    bridge.attach(runtime)
    runtime.eval("tools.get_weather('Zurich')")

The call that exceeds max_calls never reaches your Python function — JS gets a catchable ToolBudgetError. Note ToolBridge needs a full Runtime: pooled isolates have no op registry to bind tools into, which is a permanent architectural boundary, not a todo — see the bindings guide for why.

For a fast path when you're running many short-lived, independent snippets (e.g. one per agent turn) and don't need bind_function/modules for that particular call, check out an isolate from a warm IsolatePool instead of paying full cold-start cost each time:

from peno import IsolatePool

pool = IsolatePool(size=4)
with pool.checkout() as isolate:
    print(isolate.eval("1 + 41"))  # 42

Integrations

  • FastMCP tool bridge - expose FastMCP tools to sandboxed JS via bind_function and an in-process fastmcp.Client
  • pydantic-ai "code mode" agent - an agent tool where the model submits one JS batch script instead of many separate tool calls, run safely with a timeout
  • ToolBridge - hand a sandbox several Python tools with a total call budget, typed errors the model's JS can branch on, and console.log routed back to Python
  • Vendored npm libraries - run real npm document-generation libraries (pptxgenjs, pdf-lib) from their browser bundles inside the sandbox; see the guide for what makes a library a good candidate
  • Arrow IPC dataframes - move 100k+ row tables into the sandbox as Arrow IPC bytes instead of JSON objects (5 ms vs 253 ms, and it works at the default 10 MB serialization limit that rejects the JSON payload); see the guide

Documentation

  • Quick Start
  • Concepts: runtimes, type conversion, resource controls
  • Guides: binding functions, module loading, snapshots
  • Use cases: AI agent sandboxes, workflow runners, plugin systems
  • API reference
  • Benchmarks — measured, reproducible numbers, including the pooling comparison above

Metadata

Release files for peno 0.1.1

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

Source distribution (sdist)

Source distribution for peno 0.1.1
File Size Uploaded Provenance Actions
peno-0.1.1.tar.gz 463.5 kB With provenance Details for peno-0.1.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for peno 0.1.1
File Actions
peno-0.1.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl PyPy 3.11 PyPy 3.11 7.3 Linux glibc 2.28+ x86-64 Details for peno-0.1.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl
peno-0.1.1-cp314-cp314t-manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ x86-64 Details for peno-0.1.1-cp314-cp314t-manylinux_2_28_x86_64.whl
peno-0.1.1-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details for peno-0.1.1-cp314-cp314-win_amd64.whl
peno-0.1.1-cp314-cp314-manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ x86-64 Details for peno-0.1.1-cp314-cp314-manylinux_2_28_x86_64.whl
peno-0.1.1-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details for peno-0.1.1-cp314-cp314-macosx_11_0_arm64.whl
peno-0.1.1-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details for peno-0.1.1-cp313-cp313-win_amd64.whl
peno-0.1.1-cp313-cp313-manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64 Details for peno-0.1.1-cp313-cp313-manylinux_2_28_x86_64.whl
peno-0.1.1-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details for peno-0.1.1-cp313-cp313-macosx_11_0_arm64.whl
peno-0.1.1-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details for peno-0.1.1-cp312-cp312-win_amd64.whl
peno-0.1.1-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details for peno-0.1.1-cp312-cp312-manylinux_2_28_x86_64.whl
peno-0.1.1-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details for peno-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
peno-0.1.1-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details for peno-0.1.1-cp311-cp311-win_amd64.whl
peno-0.1.1-cp311-cp311-manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64 Details for peno-0.1.1-cp311-cp311-manylinux_2_28_x86_64.whl
peno-0.1.1-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details for peno-0.1.1-cp311-cp311-macosx_11_0_arm64.whl
peno-0.1.1-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details for peno-0.1.1-cp310-cp310-win_amd64.whl
peno-0.1.1-cp310-cp310-manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64 Details for peno-0.1.1-cp310-cp310-manylinux_2_28_x86_64.whl

Total release size: 328.2 MB

Release files / peno-0.1.1.tar.gz

Download URL peno-0.1.1.tar.gz
Size 463.5 kB
Tags Source
SHA-256 checksum
How to use checksums
4468c7cdc9aa2068155266c49d60f5da8f2866611aa9336c7e5e50633616b792
BLAKE2b-256 checksum
How to use checksums
a6a3d3ea2b1ec8a9baa7bbb2cee866f2e5015685cf1d3f52ff558b2f72a6d67d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl

Download URL peno-0.1.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl
Size 21.9 MB
Tags Linux glibc 2.28+ x86-64 PyPy 3.11 PyPy 3.11 7.3
SHA-256 checksum
How to use checksums
a02d4d21ced85ca56e27415cbe4fa380257b19864dd7e7f6f405a884d79995b9
BLAKE2b-256 checksum
How to use checksums
c3ed0b0ca73561336b69a384fb0d263b473ba27fa40b01ed6d64eb44bdb0bee9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp314-cp314t-manylinux_2_28_x86_64.whl

Download URL peno-0.1.1-cp314-cp314t-manylinux_2_28_x86_64.whl
Size 21.9 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
380797d7712367860315d4c1325670c03c647ce7b2a1c7d30f50fb2c6c7debf8
BLAKE2b-256 checksum
How to use checksums
aef821df98b4f55bf06fe0c9aed1ddcc5b03971e48a3433864a99c4e36a11e07
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp314-cp314-win_amd64.whl

Download URL peno-0.1.1-cp314-cp314-win_amd64.whl
Size 19.0 MB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
9fe88be3448326b84c12dbeaeb7a398e1e73cd005a95523ba316a9358ff40487
BLAKE2b-256 checksum
How to use checksums
fdb94d5fd251b6ab57235fb514ce5dfa32073d6221ef6ee70f1aa17deb866d77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp314-cp314-manylinux_2_28_x86_64.whl

Download URL peno-0.1.1-cp314-cp314-manylinux_2_28_x86_64.whl
Size 21.9 MB
Tags CPython 3.14 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
a94aa8db3eda2ba8a223a72b5cb39de3f0a21bd1a33fe80bd35901b98b5263c6
BLAKE2b-256 checksum
How to use checksums
75781e11b29b2a350a442e3d4b1fe44181187be0a78f63ec6404689a6ba5337d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp314-cp314-macosx_11_0_arm64.whl

Download URL peno-0.1.1-cp314-cp314-macosx_11_0_arm64.whl
Size 19.9 MB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
af8204b3f543c95f66d2e571f62b254da936930d9efb92fdf5e3c98f3eaf3d2f
BLAKE2b-256 checksum
How to use checksums
0b7f3f9b2c25a97627f89ede9559679d15b5cc1d0f64bc1eb8993f009c3d14f1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp313-cp313-win_amd64.whl

Download URL peno-0.1.1-cp313-cp313-win_amd64.whl
Size 19.0 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
83363f7e93e6aeb152eb8f6f15644fbd148ffb529b19c40039f8ba0aa0e64cae
BLAKE2b-256 checksum
How to use checksums
95290fa99ab5644eaecf3a7ecde9b0cfeac7f86f3f092b086e34dff798abb16e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp313-cp313-manylinux_2_28_x86_64.whl

Download URL peno-0.1.1-cp313-cp313-manylinux_2_28_x86_64.whl
Size 21.9 MB
Tags CPython 3.13 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
77ad55ce5515dff582b7c8e5261e53144fadfbbb73eb12b195b3b652b8ca44d1
BLAKE2b-256 checksum
How to use checksums
6e5efa052543b5e18e78e6bd7bd2c3c7d6f6d14fd9275904b4f7d849e191501a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp313-cp313-macosx_11_0_arm64.whl

Download URL peno-0.1.1-cp313-cp313-macosx_11_0_arm64.whl
Size 19.9 MB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
55934804881d746a65daca73ab5b52dee670fdab7c2e858d4b57925713e6edaf
BLAKE2b-256 checksum
How to use checksums
dfcf03d00fbcd9aebe45e8719255dcaeeb5a8aae0d72a4f19dd07c0e0aeb8380
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp312-cp312-win_amd64.whl

Download URL peno-0.1.1-cp312-cp312-win_amd64.whl
Size 19.0 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
f7515fc87ca485ee87464fdc579530cd1c87a609e6ff006b0b5f19bda7c8c3e5
BLAKE2b-256 checksum
How to use checksums
0b85b887f8fa78669e13a2801a042a7c2a5902f6f2fecb5f69d37fb2b65620aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp312-cp312-manylinux_2_28_x86_64.whl

Download URL peno-0.1.1-cp312-cp312-manylinux_2_28_x86_64.whl
Size 21.9 MB
Tags CPython 3.12 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
2c1a7134eccc8ba076e6e8edcdcc232458472e2815b9bdc9ef7db7aaa0baf410
BLAKE2b-256 checksum
How to use checksums
2e77108623978049a8d5d26f520adc5060f8a37b8e4f94741ee006b612b80064
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp312-cp312-macosx_11_0_arm64.whl

Download URL peno-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
Size 19.9 MB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
9874166b292b3eb277a9593aa4af509a7508f44bf5214294f271ebf5ee9b8e49
BLAKE2b-256 checksum
How to use checksums
3526686d4b92faca1e54abf0596d2b048b4df000952f6d5c3c26a73ab3c5b978
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp311-cp311-win_amd64.whl

Download URL peno-0.1.1-cp311-cp311-win_amd64.whl
Size 19.0 MB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
0ad3baf6b497d6d6869e46002a09b6b1f6ef5e1ee4ded76e887ba25278a983b2
BLAKE2b-256 checksum
How to use checksums
70115e64b5bbf315010f1e936476b086de1c02a352f216c1b7b77c8124a29d0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp311-cp311-manylinux_2_28_x86_64.whl

Download URL peno-0.1.1-cp311-cp311-manylinux_2_28_x86_64.whl
Size 21.9 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
0d93767d50a91a2ba3041e65e9cfa0e0841a00ffd5a8bc58bd758ccd868921b1
BLAKE2b-256 checksum
How to use checksums
8acd21758d5094db84d1faf54ae972320d1ed8f1b728365490845ede80337f59
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp311-cp311-macosx_11_0_arm64.whl

Download URL peno-0.1.1-cp311-cp311-macosx_11_0_arm64.whl
Size 19.9 MB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
ce31fa624fb738afa89e8e4a1a60ff1093344828d5aacfbeaba7ea3af3d9fb1b
BLAKE2b-256 checksum
How to use checksums
c66f34c5e4e8c84fbc5792f00e767d099a935e0f661df1946d6dcd80f645873b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp310-cp310-win_amd64.whl

Download URL peno-0.1.1-cp310-cp310-win_amd64.whl
Size 19.0 MB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
f52e987bc7e0cc928f7308d59819a41e84fa0a5877e92d19a51045a5f058b952
BLAKE2b-256 checksum
How to use checksums
c5d022e0ece2e0152b7f7f2cf7a6a7b7324a568e6e0717a1e5dd8d5d56c7ac7b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / peno-0.1.1-cp310-cp310-manylinux_2_28_x86_64.whl

Download URL peno-0.1.1-cp310-cp310-manylinux_2_28_x86_64.whl
Size 21.9 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
07418ccd3fa2e9d26f64da88e5adf89b96eb3b1833e3122d64307404be41dbc7
BLAKE2b-256 checksum
How to use checksums
24bdb797e7f9b9368aabb6ab4e86a858d7763db40cf4e3bf1db33ba556bb2b17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Security for peno 0.1.1

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.

Full provenance

All 17 files in this release have been uploaded with provenance metadata.

Select from 17 files

Attestation for peno-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

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