Skip to main content

masoora

Fluent builder for testable ETL pipelines in Python.

  • Fluent chaining: .with_read_step() / .with_transform_step() / .with_write_step()
  • Pydantic context: typed configuration passed to every step
  • Data catalog: in-memory key → dataset store (polars/pandas/spark/dicts — anything)
  • DAG resolution: declare steps in any order; cycles and missing inputs fail at build()
  • Testable: mock reads/writes and assert on the catalog with a pytest fixture

Usage

from masoora import PipelineBuilder, PipelineContext


class MyContext(PipelineContext):
    source_url: str
    min_score: float = 0.5


def read_events(ctx: MyContext): ...
def score(ctx: MyContext, events): ...
def filter_top(ctx: MyContext, scored): ...
def write_db(ctx: MyContext, top): ...


pipeline = (
    PipelineBuilder[MyContext]()
    .with_read_step(read_events, output="events")
    .with_transform_step(score, inputs=["events"], output="scored")
    .with_transform_step(filter_top, inputs=["scored"], output="top")
    .with_write_step(write_db, inputs=["top"])
    .build()
)

catalog = pipeline.run(MyContext(source_url="https://..."))

Step signatures:

Step kind Signature Effect
read fn(ctx) -> dataset catalog[output] = result
transform fn(ctx, *inputs) -> dataset catalog[output] = result
write fn(ctx, *inputs) -> None terminal

Steps may be declared in any order — build() topo-sorts them. Run only what's needed for one output with pipeline.run(ctx, target="top"). Pre-populated catalog keys are declared with .with_seed(key).

Parallel execution

pipeline.run(ctx, parallel=True)  # thread pool, os.cpu_count() workers
pipeline.run(ctx, parallel=4)  # explicit worker count
pipeline.run(ctx, executor=pool)  # your Executor (not shut down by masoora)

Steps run concurrently in a ThreadPoolExecutor with dependency-driven scheduling: each step starts the instant its own dependencies finish — there is no level barrier, so unrelated slow steps never delay a ready branch. Fail-fast: the first step error cancels queued work and raises StepExecutionError immediately; already-running siblings finish in the background.

Contract: steps must only read their declared input keys, write their own output key, and treat the context as read-only. Under this contract parallel results are identical to sequential.

Testing

from masoora import TestRunResult, make_pipeline_fixture

run_pipeline = make_pipeline_fixture(
    pipeline,
    MyContext(source_url="test"),
    reads={"events": fake_events},  # read step is replaced, real source untouched
)


def test_top_events(run_pipeline: TestRunResult[MyContext]) -> None:
    assert run_pipeline.catalog["top"] == expected
    assert run_pipeline.written["top"] == expected  # write step captured, not executed

Or without pytest: pipeline.to_testable(reads={...}).run(ctx)TestRunResult.

Development

uv sync
uv run pytest
uv run ruff check .
uv run mypy src tests

Download files

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

Source Distribution

masoora-0.1.0.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

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

masoora-0.1.0-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file masoora-0.1.0.tar.gz.

File metadata

  • Download URL: masoora-0.1.0.tar.gz
  • Upload date:
  • Size: 9.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.5

File hashes

Hashes for masoora-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ee0804908160c7881709ea378f1935754f6c7c6a5336f1c6d66876219038ab17
MD5 837717dd979bc1550d7034e38d3e0dc6
BLAKE2b-256 c30f67abf58fa3238e0abf4363ced7812c6cb8bbae78b3148d9ace9096f392e0

See more details on using hashes here.

File details

Details for the file masoora-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: masoora-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.5

File hashes

Hashes for masoora-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d50cb7c4388813cfa02b9485760ac0a265a216297f658bcda32c39a17d27c476
MD5 3d84dbe0bf817cbe1765ef5e6d03fbac
BLAKE2b-256 0fa7a9d5f7564f1b8b33ce9ddebb4735dd2b128ed1fdc8ef1da0bafff4a5ce4a

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.0

2 files

0.2.0

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

This release

0.1.0 This release

2 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