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.1.tar.gz (14.1 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.1-py3-none-any.whl (2.5 kB view details)

Uploaded Python 3

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

Hashes for watchflow-0.1.1.tar.gz
Algorithm Hash digest
SHA256 0a9def4d0033251b931ba0816947c13b4265649dfa18c0f179629bd068c176c9
MD5 81e79d5e68b3cf8064242fa16bed6cc1
BLAKE2b-256 996906c6504d08a254700459970ee0f609e93544d13938346e57a9973974021e

See more details on using hashes here.

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

Hashes for watchflow-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7ba510c2b3f982f5371d499d77f9bf6ae443ca7f725a16db5b88bb56614551d0
MD5 84060ad0b88290f4bc6b717b736c42ce
BLAKE2b-256 c7a53e3b61032ba32d7c7368b36c4b8f096ece586dd29bd5d72e0af298cf2240

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