Skip to main content

A lightweight Python task scheduler with dependency resolution

Project description

watchflow

A lightweight Python task scheduler with dependency resolution.

CI Python License: MIT

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

  • @task decorator with depends_on for 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_run mode that prints the execution plan without running tasks
  • Add a JSONBackend to 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


Download files

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

Source Distribution

watchflow-0.1.0.tar.gz (13.9 kB view details)

Uploaded Source

Built Distribution

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

watchflow-0.1.0-py3-none-any.whl (2.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: watchflow-0.1.0.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.5 cpython/3.13.3 HTTPX/0.28.1

File hashes

Hashes for watchflow-0.1.0.tar.gz
Algorithm Hash digest
SHA256 734424bdb39d09f3945a1a7f7552bceb40d021eefcbe3c122bb7c4832f2168ad
MD5 f0fc9cbc5d1dfd748d2e020c6428ec46
BLAKE2b-256 9d984420c1bd4abf5c45682c0641351ecd42cd9ac2f8c0204dcc98395235c2ae

See more details on using hashes here.

File details

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

File metadata

  • Download URL: watchflow-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 2.4 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

Hashes for watchflow-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fc9d78cefb20621b4a845584128fc6caf193e159ef3e0988f5e634b1f3b67349
MD5 72cb4080d345a47f191ebb0b4cd9ea0c
BLAKE2b-256 0f082c97decb8ec5e3e470e2c23e1febb688cc1806a146f27cec497d8d7fa06f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page