Composable chain-of-steps orchestrator with context passing, logging, retries, and validation.
Project description
StepChain 🪢
Composable step orchestrator for Python.
Write clean, declarative pipelines for synchronous and asynchronous workflows — with retries, validation, logging, and hooks — all in a tiny, dependency-free package.
Why StepChain?
Every real system has orchestration glue code:
- “extract → transform → load” ETL jobs
- “fetch → enrich → push” API calls
- “validate → save → notify” business workflows
Without structure, these pipelines quickly become:
- ❌ Nested try/except spaghetti
- ❌ Repeated logging boilerplate
- ❌ Retry logic scattered everywhere
- ❌ Hard to test, hard to extend
StepChain exists to fix that.
It gives you a fluent API to compose steps into a pipeline that is:
- 🔒 Safe — retries, validation hooks, deadlines, error classes
- 📊 Transparent — precompiled logging, redaction, before/after hooks
- ⚡ Fast — near-zero runtime overhead, tiny dependency footprint (great for Lambdas & microservices)
- 🧩 Universal — works in basic Python, FastAPI/asyncio, or inside your ETL jobs
Use Cases
-
Data pipelines
ETL/ELT flows with retries, validation, and logging baked in. -
APIs & async services
Orchestrate async calls (HTTP, DB, queues) with retries and deadlines. -
Business workflows
Chaining validation → save → publish → notify in web apps. -
Serverless (AWS Lambda, GCP Cloud Functions)
Tiny cold-start friendly orchestrator (no heavy deps). -
Testing & prototyping
Express multi-step flows declaratively, without external schedulers.
Install
pip install py-stepchain
Usage
Sync example (basic Python ETL)
from stepchain import Chain
data = [
{"id": 1, "name": "alice", "active": True},
{"id": 2, "name": "bob", "active": False},
]
def extract():
return data
def transform(rows):
return [r["name"].upper() for r in rows if r["active"]]
def load(names):
print("Loaded:", names)
return {"count": len(names)}
ctx = (
Chain()
.next(extract, out="raw", log_fmt="raw_n={raw.__len__}")
.next(transform, out="clean", args=["raw"], log_fmt="clean_n={clean.__len__}")
.next(load, out="loadres", args=["clean"], log_fmt="loaded={loadres.count}")
.run()
)
print(ctx["loadres"])
# → {"count": 1}
Async example (FastAPI)
from fastapi import FastAPI
from stepchain.chain.async_chain import AsyncChain
app = FastAPI()
async def fetch_user(user_id: int):
return {"id": user_id, "name": "Alice"}
async def enrich(user):
user["greeting"] = f"Hello {user['name']}!"
return user
@app.get("/hello/{user_id}")
async def hello(user_id: int):
ctx = await (
AsyncChain()
.put("id", user_id)
.next(fetch_user, out="user", args=["id"])
.next(enrich, out="enriched", args=["user"], log_fmt="User={enriched.name}")
.run()
)
return ctx["enriched"]
Features
✅ Sync + Async APIs
✅ Retries with backoff + jitter
✅ Validation hooks per step
✅ Logging templates with {dotted.refs} and JSON serialization
✅ Before/After hooks for metrics and tracing
✅ Context redaction for secrets
✅ Strict mode: unresolved refs cause errors
✅ 100% type hints (mypy-friendly)
✅ Dependency-free (only stdlib)
Why not Airflow/Prefect/dbt/etc?
-
Those are heavy DAG engines for distributed orchestration.
-
StepChain is for the inner loop: inside your function, microservice, or Lambda.
-
It complements those tools, not replaces them.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_stepchain-0.1.0.tar.gz.
File metadata
- Download URL: py_stepchain-0.1.0.tar.gz
- Upload date:
- Size: 14.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
291fc74fc5f7139ea1f92fbc5bf95ae4e07a066e78795a8691e523a864ccb891
|
|
| MD5 |
1febd02efb90c5e8645959e232a104e9
|
|
| BLAKE2b-256 |
e541594b0e2a93a9563236b09b1cf226f8503f22b04f89ca3d82b0989da31c54
|
Provenance
The following attestation bundles were made for py_stepchain-0.1.0.tar.gz:
Publisher:
publish.yml on inderdevbhumi82-prog/stepchain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_stepchain-0.1.0.tar.gz -
Subject digest:
291fc74fc5f7139ea1f92fbc5bf95ae4e07a066e78795a8691e523a864ccb891 - Sigstore transparency entry: 453185100
- Sigstore integration time:
-
Permalink:
inderdevbhumi82-prog/stepchain@1c48592fddc3559ad969d9b623f1769372f900fe -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/inderdevbhumi82-prog
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1c48592fddc3559ad969d9b623f1769372f900fe -
Trigger Event:
release
-
Statement type:
File details
Details for the file py_stepchain-0.1.0-py3-none-any.whl.
File metadata
- Download URL: py_stepchain-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5b81e96324013c3eb3a71c32420a2c3763e799f5b8280c43f2fde8a6bccf567
|
|
| MD5 |
49779233624379bf4a0c9133e30d841f
|
|
| BLAKE2b-256 |
b59735063457a9ea8080a5ddbffda1bc161fb9fce6d5f4ddc0e5a4463b10e1d1
|
Provenance
The following attestation bundles were made for py_stepchain-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on inderdevbhumi82-prog/stepchain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_stepchain-0.1.0-py3-none-any.whl -
Subject digest:
c5b81e96324013c3eb3a71c32420a2c3763e799f5b8280c43f2fde8a6bccf567 - Sigstore transparency entry: 453185104
- Sigstore integration time:
-
Permalink:
inderdevbhumi82-prog/stepchain@1c48592fddc3559ad969d9b623f1769372f900fe -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/inderdevbhumi82-prog
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1c48592fddc3559ad969d9b623f1769372f900fe -
Trigger Event:
release
-
Statement type: