Skip to main content

Lightweight Python workflow orchestration platform

Project description

Piply

Piply is a lightweight Python pipeline framework for teams that want YAML-defined workflows, schedules, retries, logs, sensors, and an operations UI without running a heavy orchestration stack.

It stays small on purpose:

  • local dependency-aware DAG execution
  • SQLite for runs, logs, task outputs, queue state, sensors, and pause overrides
  • FastAPI plus server-rendered UI
  • no Redis, Celery, Airflow, Prefect, or external queue required

Features

  • Multi-task pipelines with depends_on
  • Python script, Python callable, CLI, API, webhook, email, and SSH tasks
  • Reusable YAML variables with {name} interpolation
  • .env, environment variables, explicit secrets, and reusable SQL connections
  • Task output passing through context["task_id"]
  • Pipeline-to-pipeline output and tenant context passing
  • Metadata-driven entities expansion for reusable task templates
  • Optional pipeline_templates and pipeline_deployments for advanced reuse
  • Per-task upstream failure behavior: skip, fail, or continue
  • Heartbeat-backed runtime recovery for interrupted runs and stale scheduler state
  • Schedules, sensors, retries, cancellation, reruns, and searchable logs
  • Dashboard, Pipelines, Execution Matrix, Logs, Settings, and run detail pages

Quick Start

pip install -e .
copy .env.example .env
piply validate --config piply-demo/piply.yaml
piply start --config piply-demo/piply.yaml

Open http://127.0.0.1:8000.

Run on a different port when 8000 is already in use:

piply start --config piply-demo/piply.yaml --port 8080
piply start --config piply-demo/piply.yaml --host 0.0.0.0 --port 8080

Create a starter workspace:

piply init my-piply-project
piply run extract_flow --config my-piply-project/piply.yaml --wait

Minimal YAML

version: "1"
title: Piply Workspace
workspace: .

variables:
  scripts_dir: pipelines
  batch_id: demo-batch

connections:
  app_db: sqlite:///sensor_demo.db

pipelines:
  extract_flow:
    schedule:
      every: 15m
    retry:
      attempts: 2
      mode: resume
      delay_seconds: 10
    triggers_on_success:
      - report_flow
    tasks:
      extract:
        type: python
        path: "{scripts_dir}/extract.py"
        function: extract_data

      transform:
        type: python
        path: "{scripts_dir}/extract.py"
        function: transform_data
        depends_on: [extract]

      validate:
        type: cli
        command: python {scripts_dir}/validate_cli.py {batch_id}
        cwd: .
        depends_on: [transform]

  report_flow:
    tasks:
      build_report:
        type: python
        path: "{scripts_dir}/report.py"
        function: build_report

Python callable tasks can consume upstream outputs:

def transform_data(context):
    extracted = context["extract"]
    return {"records": extracted["records"] + 1}

For plain commands, omit shell so Piply uses the platform default shell. Set shell: bash only for Bash-specific syntax and only on machines where Bash is installed and available on PATH:

tasks:
  load_env_and_run:
    type: cli
    shell: bash
    command: set -a && source .env && set +a && conda run -n py312_extract python {scripts_dir}/job.py
    cwd: .

Dynamic Entity Mapping

Use entities when one task template should run once per business value. Piply expands templates at runtime into normal DAG tasks, so existing retries, logs, outputs, and parallel execution continue to work.

pipelines:
  extract_flow:
    entities:
      report:
        - payment
        - adjustment
        - refund
    max_parallel_tasks: 3
    tasks:
      extract:
        type: python
        path: pipelines/extract.py
        function: extract_data
        kwargs:
          report: "{report}"

      validate:
        type: cli
        command: python validate.py --report {report}
        depends_on: [extract]

Runtime tasks are generated as payment.extract -> payment.validate, adjustment.extract -> adjustment.validate, and refund.extract -> refund.validate.

Advanced Deployments

Simple pipelines: YAML remains the default. For repeated tenant or environment rollouts, define a reusable template and deployment-specific schedules or variables:

pipeline_templates:
  report_pipeline:
    tasks:
      extract:
        type: python
        path: pipelines/extract.py
        function: extract_data
        kwargs:
          tenant: "{tenant}"

pipeline_deployments:
  client_a_reporting:
    template: report_pipeline
    schedule:
      every: 15m
    variables:
      tenant: client_a

  client_b_reporting:
    template: report_pipeline
    schedule:
      cron: "0 * * * *"
    tenant: client_b

Each deployment becomes a normal runnable pipeline id, so the scheduler, UI, CLI, and API keep working without a second execution model.

Deployment Variables In Downstream Pipelines

Variables from a deployment are automatically passed to a downstream pipeline started through triggers_on_success. This is useful when several deployments share one downstream workflow. Parent deployment variables take precedence for the triggered run; a manual run of the downstream pipeline uses the downstream pipeline's own variables or top-level defaults.

pipelines:
  Bronze_to_Silver:
    tasks:
      dbt:
        type: cli
        command: DBT_CLIENT={practice} dbt run --selector appointment_silver

pipeline_templates:
  ECW_Extract_test:
    tasks:
      extract:
        type: cli
        command: echo extract

pipeline_deployments:
  BENNETT_ETL_Flow:
    template: ECW_Extract_test
    variables:
      practice: BENNETT
    triggers_on_success: [Bronze_to_Silver]

When BENNETT_ETL_Flow succeeds, Piply runs Bronze_to_Silver with DBT_CLIENT=BENNETT. A deployment for PALOS would use the same target and set practice: PALOS.

Common CLI

piply --version
piply init my-piply-project
piply validate --config piply-demo/piply.yaml
piply list --config piply-demo/piply.yaml
piply run extract_flow --config piply-demo/piply.yaml --wait
piply run extract_flow --tenant acme --param batch=2026-05-26 --config piply-demo/piply.yaml
piply tasks list extract_flow --config piply-demo/piply.yaml
piply tasks run extract_flow validate --tenant acme --param region=west --config piply-demo/piply.yaml
piply tasks retry <run_id> <task_id> --mode resume --config piply-demo/piply.yaml
piply runs --config piply-demo/piply.yaml
piply logs <run_id> --config piply-demo/piply.yaml
piply pause extract_flow --config piply-demo/piply.yaml
piply resume extract_flow --config piply-demo/piply.yaml
piply start --config piply-demo/piply.yaml
piply start --config piply-demo/piply.yaml --port 8080
piply stop --config piply-demo/piply.yaml

Docs

Roadmap

Planned features:

  • piply logs --follow
  • plugin hooks for custom operators and sensors
  • managed external secret backends
  • richer queue, worker, and artifact metrics
  • UI-safe pipeline editing
  • task groups, conditional branches, and richer mapped-run visualization
  • Optional distributed runner while keeping local mode as the default
  • Task Priority Support

Introduce optional task priority support.

Goal:

When multiple runnable tasks are available for execution, the scheduler should prefer higher-priority tasks.

User-friendly syntax:

tasks:

extract***: type: python

transform**: type: python

validate*: type: python

Interpretation:

*** = priority 3 ** = priority 2

  • = priority 1

Internally normalize task IDs:

extract*** → extract

transform** → transform

Store priority separately.

Equivalent explicit syntax:

tasks:

extract: priority: 3

transform: priority: 2

validate: priority: 1

Both syntaxes should be supported.

Execution Rules:

  • Higher priority tasks execute first.
  • Only among currently runnable tasks.
  • Dependencies still take precedence.
  • Priority does not bypass dependencies.
  • Equal-priority tasks may execute FIFO or randomly.

Requirements:

  • Backward compatible.
  • UI should display priority visually.
  • DAG graph should indicate priority.
  • Runtime metadata should persist priority.
  • Dynamic task expansion should inherit priority.
  • Scheduler should sort ready tasks using priority.

Recommended scheduling order:

  1. Priority DESC
  2. Ready Time ASC
  3. Created Time ASC
  4. Random tie-breaker

The Pipelines page supports Grid and List views. The selected view is remembered in the browser.

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

mr_piply-0.1.8.tar.gz (113.9 kB view details)

Uploaded Source

Built Distribution

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

mr_piply-0.1.8-py3-none-any.whl (122.7 kB view details)

Uploaded Python 3

File details

Details for the file mr_piply-0.1.8.tar.gz.

File metadata

  • Download URL: mr_piply-0.1.8.tar.gz
  • Upload date:
  • Size: 113.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.14

File hashes

Hashes for mr_piply-0.1.8.tar.gz
Algorithm Hash digest
SHA256 87f7e04afec57d2178c284ba0a4d69659cb965fef6c8a3b13f4698eb3a1b7a68
MD5 ec41cd491af16eae0046fa566385ce3b
BLAKE2b-256 f3c63eb97c4276a25bdb3fe44645b712b62c221ec62df9f1987c6f552d08eda6

See more details on using hashes here.

File details

Details for the file mr_piply-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: mr_piply-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 122.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.14

File hashes

Hashes for mr_piply-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 0cf1b883082ecdeef6c9a25b4efe00321b2b95401cb797cea3103135ca1ec6e8
MD5 d5cf0cfac9ecfa5758fc063c44150385
BLAKE2b-256 2f234bd9f491413be082aaa66e4b78747ca5b0e6334354ece26f25c28203a4df

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