Skip to main content

Action0-Pipeline

CI PyPI

asyncio pipelines with per-step parallelism, for work that spends its time waiting on blocking IO.

Requires Python 3.13 or newer.

Full documentation including the API reference: https://laughinjar.github.io/action0-pipeline/

Status: early. The pipeline, the per-step concurrency, the error policies and the buffer protocol all work and are covered by tests; the API may still move.

Installation

pip install action0-pipeline  # or uv add action0-pipeline

Usage

Build a pipeline from some initial data, append transformer steps, read the results as an async iterator:

import asyncio
from action0.pipeline import Pipeline


def double(value: int) -> list[int]:
    return [value * 2]


async def main() -> None:
    async with Pipeline(range(5)).add_step(double) as pipeline:
        print(sorted([item async for item in pipeline]))  # [0, 2, 4, 6, 8]


asyncio.run(main())

Every step is resident and working at the same time as every other, and each one sets its own concurrency: async_workers asyncio tasks consuming its input, and a thread pool of thread_pool_size threads for the blocking calls those tasks make. Use thread_pool_size=0 for a transformer that is already non-blocking — async def and async generator transformers always run in the event loop.

def blocking(value: int) -> list[int]:
    time.sleep(0.1)  # a blocking HTTP call, a database query, ...
    return [value]


async def waiting(value: int) -> AsyncIterator[int]:
    await asyncio.sleep(0.1)
    yield value


pipeline = (
    Pipeline(range(12))
    .add_step(blocking, async_workers=4, thread_pool_size=4)
    .add_step(waiting, async_workers=12)
)
async with pipeline as running:
    items = [item async for item in running]
# 12 items in 0.4s — done one at a time this would take 2.4s

A transformer is handed one item and returns the items it produced, so the same signature maps, fans out, or filters:

def letters(word: str) -> list[str]:
    return list(word)  # one word, several letters


def drop_vowels(letter: str) -> list[str]:
    return [] if letter in "aeiou" else [letter]  # emit nothing to drop it


pipeline = Pipeline(["hello", "world"]).add_step(letters).add_step(drop_vowels)
async with pipeline as running:
    print(sorted([item async for item in running]))
    # ['d', 'h', 'l', 'l', 'l', 'r', 'w']

The static type follows the chain — add_step returns a pipeline parameterised by that step's output type — so the checkers know what each step is handed.

Items come out in the order they finish, not the order they went in: as soon as a step has more than one worker, a quick item overtakes a slow one.

Bound the buffers to get backpressure, and let each step decide what to do when its transformer raises — tear the pipeline down and re-raise at the consumer (the default), drop the item, or substitute replacements from a callback:

pipeline = Pipeline(urls, maxsize=100).add_step(
    fetch, async_workers=8, thread_pool_size=8, maxsize=100, on_error=ErrorPolicy.SKIP
)

See the usage guide for backpressure, error callbacks, custom buffers, threaded sources and teardown.

Development

uv run pytest          # tests (incl. doctests in src/)
uv run ruff check      # lint
uv run ruff format     # format
uv run mypy            # type-check (strict)
uv run pyright         # type-check
uv run ty check        # type-check

License

MIT — see LICENSE.

Metadata

Release files for action0-pipeline 0.1.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 action0-pipeline 0.1.0
File Size Uploaded
action0_pipeline-0.1.0.tar.gz 79.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for action0-pipeline 0.1.0
File Interpreter ABI Platform
action0_pipeline-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 91.2 kB

Release files / action0_pipeline-0.1.0.tar.gz

Download URL action0_pipeline-0.1.0.tar.gz
Size 79.0 kB
Tags Source
SHA-256 checksum
How to use checksums
ce466b1e04aae8f98c29c77540c5c2478b37fb427973b1f477f4b4698439cd78
BLAKE2b-256 checksum
How to use checksums
669c45d52a5f79ffc4ad539a6be15721930e036af994536eb8511f1e12ed0474
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 Oct 17, 2026.

Transparency log

Release files / action0_pipeline-0.1.0-py3-none-any.whl

Download URL action0_pipeline-0.1.0-py3-none-any.whl
Size 12.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3576f31271fdc6c7ca2177dd4fce0c68852fd0a4d5b111dc363defaf6dd99c2d
BLAKE2b-256 checksum
How to use checksums
c66cea1c673d44c453dd64a41a88c8bfdc8145f5b62314ddc1497c3caa3bcd14
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 Oct 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 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