Skip to main content

pyropust

Python versions PyPI

Rust-powered, type-safe pipelines for Python.

pyropust bridges the messy, exception-heavy reality of Python with the explicit, composable world of Rust’s Result / Option.

This is not just another Result library.

pyropust is built around three core ideas:

  • Blueprints — typed, declarative data-processing pipelines
  • Rust operators — hot-path operations (e.g. JSON decoding) executed safely and efficiently in Rust
  • Exception boundaries — explicit normalization of Python exceptions into Result

If you have ever thought:

“I want Rust-like error flow, but I live in Python and can’t avoid exceptions”

pyropust is designed for you.

Why pyropust exists

Python already has multiple Result / Option libraries. The problem is not representation — it is integration.

In real Python systems:

  • Most libraries raise exceptions (requests, boto3, sqlalchemy, ...)
  • Data transformation is written as long chains of try/except
  • Type checkers lose track of what can fail and where

pyropust treats exceptions as an external reality and provides a structured boundary where they are captured, typed, and composed.

Why not exceptions?

Exceptions are great for failures that should abort the current operation. They are less suitable for orchestration and pipelines:

  • They hide control flow in call stacks
  • They complicate typed composition across steps
  • They are hard to make explicit at module boundaries

pyropust makes failures values so they can be composed, transformed, and tested like data.

Adoption path

You do not need to switch everything at once. A realistic path is:

  1. Wrap exceptions with @catch
  2. Use Result / Option explicitly in Python code
  3. Use @do for structured propagation
  4. Introduce Blueprint for typed pipelines

Key concepts

1) Result and Option

Rust-style Result[T] and Option[T] as first-class values.

from pyropust import Ok, Err, Some, None_

value = Ok(10)
error = Err("boom")

maybe = Some(42)
empty = None_()

Result is explicit about failures. All failures are represented as RopustError. You can return it from functions and branch on is_ok / is_err without exceptions.

from pyropust import Ok, Err, Result

def divide(a: int, b: int) -> Result[float]:
    if b == 0:
        return Err("division by zero")
    return Ok(a / b)

res = divide(10, 2)
if res.is_ok():
    value = res.unwrap()
else:
    error = res.unwrap_err()
    print(error.message)

Keep Option short and explicit: you must unwrap or provide defaults.

from pyropust import Some, None_, Option

def find_user(user_id: int) -> Option[str]:
    return Some("alice") if user_id == 1 else None_()

user = find_user(1)
name = user.unwrap_or("guest")

missing = find_user(2)
name2 = missing.unwrap_or("guest")

Unlike Optional[T] (which is only a type hint), Option[T] is a runtime value that forces explicit handling.

Functional Chaining (map, and_then)

Avoid if checks by chaining operations.

from pyropust import Ok

res = (
    Ok("123")
    .map(int)                # Result[int]
    .map(lambda x: x * 2)    # Result[int]
    .and_then(lambda x: Ok(f"Value is {x}"))
)
print(res.unwrap())  # "Value is 246"

When to use: map/and_then is best for small, expression-style transforms where each step is a function.

[!TIP] Type Hint for and_then: When using and_then with a callback that may return Err, define the initial Result with an explicit return type annotation. This ensures the Ok type is correctly inferred.

from pyropust import Ok, Err, Result

def fetch_data() -> Result[int]:  # Declare ok type here
    return Ok(42)

def validate(x: int) -> Result[int]:
    return Err("invalid") if x < 0 else Ok(x)

# Error type flows correctly through the chain
result = fetch_data().and_then(validate)

Adding context and error codes

In real applications, errors often need additional context as they move up the stack. pyropust provides helpers inspired by Rust’s context and error mapping patterns.

from pyropust import Result, Err

def load_config(path: str) -> Result[str]:
    return Err("file not found")

result = load_config("/etc/app.toml").context(
    "failed to load application config",
    code="config.load",
)
  • context(...) adds human-readable context while preserving the original cause
  • The original error is kept as a structured cause chain

You can also modify error codes for classification and observability:

result = load_config("/etc/app.toml").with_code("config.not_found")

result = load_config("/etc/app.toml").map_err_code("startup")

Error codes are stable, machine-facing identifiers. Messages are for humans and may change; codes are for branching, testing, and observability.

These helpers make it easy to:

  • Add meaning at higher layers
  • Classify failures without losing detail
  • Keep error handling explicit and testable

2) Blueprint: typed pipelines

A Blueprint is a declarative pipeline that describes what happens to data, not how it is wired together.

from pyropust import Blueprint, Op

bp = (
    Blueprint.for_type(str)
    .pipe(Op.json_decode())
    .pipe(Op.get("user"))
    .pipe(Op.get("id"))
)

Characteristics:

  • Typed: Blueprint.for_type(T) gives static analyzers a concrete starting point
  • Composable: pipelines are values, not control flow
  • No runtime type checks: types are for humans and tools, not runtime checks

Blueprints are the primary abstraction of pyropust.

Blueprints are inert definitions. Use run(bp, value) to execute them, typically inside an exception boundary.

Only a core set of basic operators is supported today; see the full list in docs/operations.md.

3) Rust operators (hot paths)

Some operations are performance-critical and error-prone. pyropust implements these as Rust-backed operators:

  • Op.json_decode()
  • (future) Op.base64_decode(), Op.url_parse(), ...

Benefits:

  • Faster execution for hot paths
  • Consistent error semantics
  • No Python-level exceptions leaking through the pipeline

You can always fall back to Python:

bp = bp.pipe(Op.map_py(lambda x: x + 1))

Rust where it matters, Python where it’s convenient.

4) Exception boundaries (@catch)

Python exceptions are unavoidable. pyropust makes them explicit.

from pyropust import Blueprint, Op, catch, run

bp = (
    Blueprint.for_type(str)
    .pipe(Op.json_decode())
    .pipe(Op.get("value"))
)

@catch
def load_value(payload: str):
    return run(bp, payload)

Inside the boundary:

  • Exceptions are captured
  • Normalized into Err
  • Enriched with traceback metadata (py_traceback)

Outside the boundary:

  • No hidden control flow
  • Failures are values

This makes error flow visible, testable, and composable.

5) @do: Rust-like ? for Python

The @do decorator enables linear, Rust-style propagation of Result.

from pyropust import Ok, Result, do

@do
def process(data: str) -> Result[str]:
    text = yield Ok(data)
    return Ok(text.upper())

When to use: @do reads like imperative code and is better when you need intermediate variables, early returns, or mixed steps. Prefer context for adding meaning instead of catching exceptions.

This is not syntax sugar over exceptions — it is structured propagation of Result values.

Framework boundaries

You can safely use pyropust in frameworks that expect exceptions by converting Result back into exceptions at the boundary.

from fastapi import FastAPI, HTTPException
from pyropust import Result, catch

app = FastAPI()

@catch(ValueError, KeyError)
def parse_user_input(data: dict) -> dict:
    return {
        "age": int(data["age"]),
        "name": data["name"],
    }

@app.post("/users")
def create_user(data: dict):
    result = parse_user_input(data)

    # Convert Result to exception at the framework boundary
    parsed = result.unwrap_or_raise(
        HTTPException(status_code=400, detail="Invalid input")
    )

    return {"user": parsed}

Installation

pyropust is currently experimental.

pip install pyropust

Supported:

  • Python 3.10+
  • CPython (wheels provided)

Note: Some platforms may require a Rust toolchain to build from source.

Minimal example (30 seconds)

from pyropust import Blueprint, Op, catch, run

bp = (
    Blueprint.for_type(str)
    .pipe(Op.json_decode())
    .pipe(Op.get("value"))
)

@catch
def run_value(payload: str):
    return run(bp, payload)

result = run_value('{"value": 123}')
  • No try/except
  • Failures are explicit
  • The pipeline is reusable and testable

Documentation

Non-goals

pyropust intentionally does not aim to:

  • Replace Python exceptions everywhere
  • Be a general-purpose FP toolkit
  • Hide Python’s dynamic nature

It is a boundary and pipeline tool, not a new language.

Roadmap

  • More Rust-backed operators
  • Benchmark suite and published numbers
  • Better IDE / type-checker ergonomics
  • Stabilization of public APIs

Stability

  • APIs may change before 1.0
  • Semantic versioning will start at 1.0
  • Breaking changes will be documented

License

MIT

Metadata

Release files for pyropust 0.2.0

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

Source distribution (sdist)

Source distribution for pyropust 0.2.0
File Size Uploaded
pyropust-0.2.0.tar.gz 82.7 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for pyropust 0.2.0
File
pyropust-0.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.17+ x86-64 Details
pyropust-0.2.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.14 CPython 3.14 Linux glibc 2.17+ ARM64 Details
pyropust-0.2.0-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details
pyropust-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ x86-64 Details
pyropust-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ ARM64 Details
pyropust-0.2.0-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
pyropust-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ x86-64 Details
pyropust-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ ARM64 Details
pyropust-0.2.0-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details

Total release size: 4.7 MB

Release files / pyropust-0.2.0.tar.gz

Download URL pyropust-0.2.0.tar.gz
Size 82.7 kB
Tags Source
SHA-256 checksum
How to use checksums
b9f5056fbe7e5566cc9e199feb72a78a9c53ef29bb7a177a044155b81ae128e0
BLAKE2b-256 checksum
How to use checksums
11d23490b99a39545159e2a4d1d584ef18f1b03fa515a1817b6be8c05b9b5602
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release files / pyropust-0.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL pyropust-0.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 536.9 kB
Tags CPython 3.14 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
dc0358737f1b7940138517579c66dae77862d2f58634b66ecc51004f59e72d50
BLAKE2b-256 checksum
How to use checksums
a18fa555904d60a651a6a9a08de657fc49d8f9ce24152cac13e391166c589baa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release files / pyropust-0.2.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL pyropust-0.2.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 525.6 kB
Tags CPython 3.14 Linux glibc 2.17+ ARM64
SHA-256 checksum
How to use checksums
5bd0b018680224933489893e5e5bb0c1c98c4c89e295aab297523b5bc63ecbaa
BLAKE2b-256 checksum
How to use checksums
40aa13f93023cbb509cf062e467c33ad79ac0b846391fea381e496c12eb9f95b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release files / pyropust-0.2.0-cp314-cp314-macosx_11_0_arm64.whl

Download URL pyropust-0.2.0-cp314-cp314-macosx_11_0_arm64.whl
Size 480.7 kB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f5ed563b9b2024bfdb61b380d998075164133f5c4d687e607daa84653b9cd888
BLAKE2b-256 checksum
How to use checksums
c2e6a3ba4adc5dda7bc390366a063a2ac96c1bcec795b05ddeea798994211db7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release files / pyropust-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL pyropust-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 535.7 kB
Tags CPython 3.13 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
8a278845ab80180a67100ad6db6c8b27f08ba9fb2032f2e28ed8530ea646ab51
BLAKE2b-256 checksum
How to use checksums
c931c3a1693feb0d8e3f18a04b6a93698ff74426a9842cba246000091d3203b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release files / pyropust-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL pyropust-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 524.3 kB
Tags CPython 3.13 Linux glibc 2.17+ ARM64
SHA-256 checksum
How to use checksums
9b66742ccde616207697e8973b733f6f71ef14dd2b8b1a6da36a82c725084670
BLAKE2b-256 checksum
How to use checksums
2dc811bc06ea13ea92b3cb0b922d9a14a43e9fe5a0ec1131ea9be43fc09000c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release files / pyropust-0.2.0-cp313-cp313-macosx_11_0_arm64.whl

Download URL pyropust-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Size 480.2 kB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
336484256f11dcb795a3651978d7585623b01b273ff0f426631ec1f26e7eb125
BLAKE2b-256 checksum
How to use checksums
28acd86fa478317961e956ea6c5e04f2084c18b9092beaa083c62e846f78bd0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release files / pyropust-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL pyropust-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 535.8 kB
Tags CPython 3.12 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
efa93f5f1fade9cd89f8bef2ab623d757d3530670ef2a226c95bdb3b9e192b11
BLAKE2b-256 checksum
How to use checksums
db34c74d5eae91af1fe43a7b4a9fcc16ce3abf567d65dfe83dcada6b2cb15c85
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release files / pyropust-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL pyropust-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 524.3 kB
Tags CPython 3.12 Linux glibc 2.17+ ARM64
SHA-256 checksum
How to use checksums
b33570bc29168c6ecf771a47d9ead09195f6b4d91dfe21867591543aa086eddd
BLAKE2b-256 checksum
How to use checksums
90169e9d8db215448a8b391cd6a5d6d6be00654db25558f081c9e66441120a87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release files / pyropust-0.2.0-cp312-cp312-macosx_11_0_arm64.whl

Download URL pyropust-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Size 481.7 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
2816b2fdc82dbee0f36146e1475bf7ac9a53cbf87e7f6c23db7565e0165bcdd7
BLAKE2b-256 checksum
How to use checksums
f44d9159dd07c1f6619d2b92f117693f1c8fabc661ad625209ef080fec613fee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

10 release files

0.1.0

10 release files

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