A lightweight Python task scheduler with dependency resolution
Project description
watchflow
A lightweight Python task scheduler with dependency resolution.
watchflow fills the gap between a simple cron job and a full-blown orchestrator like Airflow. Define tasks with a decorator, declare dependencies, and let watchflow figure out the execution order.
from watchflow import task, run
@task
def fetch_data():
return load_csv("data.csv")
@task(depends_on=["fetch_data"])
def clean_data(fetch_data):
return [row for row in fetch_data if row is not None]
@task(depends_on=["fetch_data"])
def validate_data(fetch_data):
return len(fetch_data) > 0
@task(depends_on=["clean_data", "validate_data"])
def train_model(clean_data, validate_data):
if not validate_data:
raise ValueError("Invalid data")
return model.fit(clean_data)
run()
Why watchflow?
| cron + bash | watchflow | Airflow / Prefect | |
|---|---|---|---|
| Dependency resolution | No | Yes | Yes |
| Pure Python API | No | Yes | Yes |
| Zero config | Yes | Yes | No |
| Parallel execution | No | Yes | Yes |
| Setup time | 1 min | 1 min | 30+ min |
Installation
pip install watchflow
Features
@taskdecorator withdepends_onfor dependency declaration- Automatic topological sort — no need to think about execution order
- Parallel execution of independent tasks with
run(parallel=True) - Retry with exponential backoff —
@task(retries=3, retry_delay=1.0) - Timeout per task —
@task(timeout=30.0) - DAG visualization in ASCII and Mermaid format
- Zero external dependencies — pure Python stdlib
Usage
Basic pipeline
from watchflow import task, run
@task
def step_one():
return 42
@task(depends_on=["step_one"])
def step_two(step_one):
return step_one * 2
run()
Parallel execution
run(parallel=True)
Independent tasks run concurrently using ThreadPoolExecutor.
Retry and timeout
@task(retries=3, retry_delay=1.0, retry_backoff=2.0, timeout=30.0)
def fetch_from_api():
return requests.get("https://api.example.com/data").json()
Visualize the DAG
from watchflow import get_dag
from watchflow.core.visualizer import print_graph
print_graph(get_dag())
# DAG watchflow (4 tasks)
# └── [ ] fetch_data
# ├── [ ] clean_data
# │ └── [ ] train_model
# └── [ ] validate_data
# └── [ ] train_model
print_graph(get_dag(), fmt="mermaid")
Contributing
Contributions are welcome! Here are some good first issues to start with:
- Add a
dry_runmode that prints the execution plan without running tasks - Add a
JSONBackendto persist execution results - Add support for async tasks with
asyncio - Add a
@task(tags=["etl"])feature to run subsets of the pipeline - Improve the ASCII visualization for diamond-shaped DAGs
See CONTRIBUTING.md for guidelines.
License
MIT
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 watchflow-0.1.1.tar.gz.
File metadata
- Download URL: watchflow-0.1.1.tar.gz
- Upload date:
- Size: 14.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.5 cpython/3.13.3 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a9def4d0033251b931ba0816947c13b4265649dfa18c0f179629bd068c176c9
|
|
| MD5 |
81e79d5e68b3cf8064242fa16bed6cc1
|
|
| BLAKE2b-256 |
996906c6504d08a254700459970ee0f609e93544d13938346e57a9973974021e
|
File details
Details for the file watchflow-0.1.1-py3-none-any.whl.
File metadata
- Download URL: watchflow-0.1.1-py3-none-any.whl
- Upload date:
- Size: 2.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.5 cpython/3.13.3 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ba510c2b3f982f5371d499d77f9bf6ae443ca7f725a16db5b88bb56614551d0
|
|
| MD5 |
84060ad0b88290f4bc6b717b736c42ce
|
|
| BLAKE2b-256 |
c7a53e3b61032ba32d7c7368b36c4b8f096ece586dd29bd5d72e0af298cf2240
|