Metadata-Version: 2.4
Name: philiprehberger-task-graph
Version: 0.1.2
Summary: Lightweight task dependency engine with topological execution
Project-URL: Homepage, https://github.com/philiprehberger/py-task-graph#readme
Project-URL: Repository, https://github.com/philiprehberger/py-task-graph
Project-URL: Issues, https://github.com/philiprehberger/py-task-graph/issues
Project-URL: Changelog, https://github.com/philiprehberger/py-task-graph/blob/main/CHANGELOG.md
Author: Philip Rehberger
License-Expression: MIT
License-File: LICENSE
Keywords: dag,dependency,graph,pipeline,task,workflow
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# philiprehberger-task-graph

Lightweight task dependency engine with topological execution.

## Installation

```bash
pip install philiprehberger-task-graph
```

## Usage

```python
from philiprehberger_task_graph import TaskGraph

graph = TaskGraph()

@graph.task()
def fetch_data():
    return download()

@graph.task(depends_on=["fetch_data"])
def process_data():
    return transform()

@graph.task(depends_on=["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

```python
graph = TaskGraph()
graph.add_task("fetch", fetch_fn)
graph.add_task("process", process_fn, depends_on=["fetch"])
graph.add_task("save", save_fn, depends_on=["process"])

# Preview execution order
order = graph.dry_run()
# ["fetch", "process", "save"]
```

### Cycle Detection

```python
from philiprehberger_task_graph import CycleError

# Raises CycleError if dependencies form a cycle
graph.run()
```

## API

- `TaskGraph()` — Create a new task graph
- `@graph.task(depends_on=None)` — Decorator to register a task
- `graph.add_task(name, fn, depends_on=None)` — Add a task programmatically
- `graph.run()` — Execute tasks in topological order
- `graph.run_parallel(max_workers=4)` — Execute with thread parallelism
- `graph.dry_run()` — Return execution order without running

## License

MIT
