philiprehberger-task-graph
Lightweight task dependency engine with topological execution.
Installation
pip install philiprehberger-task-graph
Usage
from philiprehberger_task_graph import TaskGraph
graph = TaskGraph()
@graph.task()
def fetch_data():
return download()
@graph.task(depends=["fetch_data"])
def process_data():
return transform()
@graph.task(depends=["process_data"])
def save_results():
return store()
# Run tasks in dependency order
results = graph.run()
# Or run with parallelism
results = graph.run_parallel(max_workers=4)
Programmatic API
graph = TaskGraph()
graph.add_task("fetch", fetch_fn)
graph.add_task("process", process_fn, depends=["fetch"])
graph.add_task("save", save_fn, depends=["process"])
# Preview execution order
order = graph.dry_run()
# ["fetch", "process", "save"]
Timeout
Set a maximum execution time for a task. Raises TimeoutError if the task exceeds the limit.
@graph.task(timeout=30.0)
def slow_task():
return long_running_operation()
# Or with add_task
graph.add_task("fetch", fetch_fn, timeout=10.0)
Retries
Automatically retry a task on failure. The task is retried up to N times before the exception propagates.
@graph.task(retries=3)
def flaky_task():
return call_unreliable_api()
# Or with add_task
graph.add_task("fetch", fetch_fn, retries=2)
Timeout and Retries Combined
@graph.task(timeout=5.0, retries=2)
def resilient_task():
return fetch_with_deadline()
Pass Dependency Results
Pass each dependency's return value as a keyword argument to the task function (named after the dependency).
graph = TaskGraph()
graph.add_task("source", lambda: 7)
graph.add_task("double", lambda source: source * 2, depends=["source"])
results = graph.run(pass_results=True)
# {"source": 7, "double": 14}
Execution Hooks
Register callbacks to observe task execution — useful for logging, metrics, or tracing without modifying the task functions.
graph = TaskGraph()
@graph.on_before_run
def log_start(name: str) -> None:
print(f"starting {name}")
@graph.on_after_run
def log_done(name: str, result: object, duration: float) -> None:
print(f"{name} done in {duration:.3f}s -> {result!r}")
@graph.on_error
def log_failure(name: str, exc: BaseException) -> None:
print(f"{name} failed: {exc!r}")
The error hook fires only after all retries have been exhausted; the original exception still propagates after every hook has run.
Cycle Detection
from philiprehberger_task_graph import CycleError
# Raises CycleError if dependencies form a cycle
graph.run()
API
| Function / Class | Description |
|---|---|
TaskGraph() |
Create a new task graph |
@graph.task(name=None, depends=None, timeout=None, retries=0) |
Decorator to register a task with optional timeout and retries |
graph.add_task(name, fn, depends=None, timeout=None, retries=0) |
Add a task programmatically |
graph.run(pass_results=False) |
Execute tasks in topological order; optionally pass dep results as kwargs |
graph.run_parallel(max_workers=None, pass_results=False) |
Execute with thread parallelism |
graph.dry_run() |
Return execution order without running |
graph.on_before_run(hook) |
Register (name) -> None callback fired before each task |
graph.on_after_run(hook) |
Register (name, result, duration) -> None callback fired after each successful task |
graph.on_error(hook) |
Register (name, exc) -> None callback fired after retries are exhausted |
CycleError |
Raised when a dependency cycle is detected |
Development
pip install -e .
python -m pytest tests/ -v
Support
If you find this project useful:
License
Release files for philiprehberger-task-graph 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| philiprehberger_task_graph-0.4.0.tar.gz | 188.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| philiprehberger_task_graph-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 195.0 kB
Release files / philiprehberger_task_graph-0.4.0.tar.gz
| Download URL | philiprehberger_task_graph-0.4.0.tar.gz |
|---|---|
| Size | 188.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c018172187e14786d233c1dec7b55c66587fd27015e03e125635b56cf85c5e3a
|
|
BLAKE2b-256 checksum How to use checksums |
c14141be290581e28f262eb8a322bf7bcbaf1a26e6a4808521ffbd5fa9050669
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / philiprehberger_task_graph-0.4.0-py3-none-any.whl
| Download URL | philiprehberger_task_graph-0.4.0-py3-none-any.whl |
|---|---|
| Size | 6.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
92e45a82287a9caac1d566e3b7dd728aade170e89a6b8859713e00b832edebc3
|
|
BLAKE2b-256 checksum How to use checksums |
9cbeaba94240bd34540ed40595939be3f9fabb7c5ebcd99f1fae1253a2a70784
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|