mr-piply 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. mr_piply-0.1.3/MANIFEST.in +1 -0
  2. mr_piply-0.1.3/PKG-INFO +222 -0
  3. mr_piply-0.1.3/README.md +180 -0
  4. mr_piply-0.1.3/mr_piply.egg-info/PKG-INFO +222 -0
  5. mr_piply-0.1.3/mr_piply.egg-info/SOURCES.txt +118 -0
  6. mr_piply-0.1.3/mr_piply.egg-info/dependency_links.txt +1 -0
  7. mr_piply-0.1.3/mr_piply.egg-info/entry_points.txt +2 -0
  8. mr_piply-0.1.3/mr_piply.egg-info/requires.txt +24 -0
  9. mr_piply-0.1.3/mr_piply.egg-info/top_level.txt +1 -0
  10. mr_piply-0.1.3/piply/api/__init__.py +3 -0
  11. mr_piply-0.1.3/piply/api/app.py +100 -0
  12. mr_piply-0.1.3/piply/api/auth.py +82 -0
  13. mr_piply-0.1.3/piply/api/routes/__init__.py +1 -0
  14. mr_piply-0.1.3/piply/api/routes/dashboard.py +37 -0
  15. mr_piply-0.1.3/piply/api/routes/execution.py +83 -0
  16. mr_piply-0.1.3/piply/api/routes/pipelines.py +158 -0
  17. mr_piply-0.1.3/piply/api/routes/runs.py +165 -0
  18. mr_piply-0.1.3/piply/api/routes/ui.py +308 -0
  19. mr_piply-0.1.3/piply/api/schemas.py +413 -0
  20. mr_piply-0.1.3/piply/cli/__init__.py +1 -0
  21. mr_piply-0.1.3/piply/cli/main.py +540 -0
  22. mr_piply-0.1.3/piply/core/__init__.py +29 -0
  23. mr_piply-0.1.3/piply/core/context.py +69 -0
  24. mr_piply-0.1.3/piply/core/graph.py +69 -0
  25. mr_piply-0.1.3/piply/core/loader.py +982 -0
  26. mr_piply-0.1.3/piply/core/models.py +462 -0
  27. mr_piply-0.1.3/piply/core/outputs.py +101 -0
  28. mr_piply-0.1.3/piply/core/retry.py +67 -0
  29. mr_piply-0.1.3/piply/core/scheduler.py +61 -0
  30. mr_piply-0.1.3/piply/core/scheduling.py +166 -0
  31. mr_piply-0.1.3/piply/core/secrets.py +159 -0
  32. mr_piply-0.1.3/piply/core/sensors.py +335 -0
  33. mr_piply-0.1.3/piply/core/service.py +1097 -0
  34. mr_piply-0.1.3/piply/core/sql_adapters.py +112 -0
  35. mr_piply-0.1.3/piply/core/store.py +1301 -0
  36. mr_piply-0.1.3/piply/engine/base.py +37 -0
  37. mr_piply-0.1.3/piply/engine/heartbeat.py +42 -0
  38. mr_piply-0.1.3/piply/engine/local_engine.py +478 -0
  39. mr_piply-0.1.3/piply/engine/task_runner.py +414 -0
  40. mr_piply-0.1.3/piply/models/__init__.py +3 -0
  41. mr_piply-0.1.3/piply/pipeline/__init__.py +14 -0
  42. mr_piply-0.1.3/piply/plugins/__init__.py +3 -0
  43. mr_piply-0.1.3/piply/scheduler/__init__.py +5 -0
  44. mr_piply-0.1.3/piply/services/__init__.py +5 -0
  45. mr_piply-0.1.3/piply/services/pipeline_service.py +5 -0
  46. mr_piply-0.1.3/piply/settings.py +158 -0
  47. mr_piply-0.1.3/piply/tasks/__init__.py +6 -0
  48. mr_piply-0.1.3/piply/ui/static/app.js +172 -0
  49. mr_piply-0.1.3/piply/ui/static/dag.js +450 -0
  50. mr_piply-0.1.3/piply/ui/static/styles.css +1303 -0
  51. mr_piply-0.1.3/piply/ui/templates/base.html +45 -0
  52. mr_piply-0.1.3/piply/ui/templates/dashboard.html +252 -0
  53. mr_piply-0.1.3/piply/ui/templates/execution_matrix.html +163 -0
  54. mr_piply-0.1.3/piply/ui/templates/logs.html +48 -0
  55. mr_piply-0.1.3/piply/ui/templates/pipeline_detail.html +364 -0
  56. mr_piply-0.1.3/piply/ui/templates/pipelines.html +88 -0
  57. mr_piply-0.1.3/piply/ui/templates/run_detail.html +435 -0
  58. mr_piply-0.1.3/piply/ui/templates/runs.html +72 -0
  59. mr_piply-0.1.3/piply/ui/templates/settings.html +118 -0
  60. mr_piply-0.1.3/piply/utils/__init__.py +5 -0
  61. mr_piply-0.1.3/pyproject.toml +120 -0
  62. mr_piply-0.1.3/setup.cfg +4 -0
  63. mr_piply-0.1.3/tests/test_cli.py +108 -0
  64. mr_piply-0.1.3/tests/test_context_outputs.py +173 -0
  65. mr_piply-0.1.3/tests/test_core.py +285 -0
  66. mr_piply-0.1.3/tests/test_helpers.py +503 -0
  67. mr_piply-0.1.3/tests/test_plugins.py +199 -0
  68. mr_piply-0.1.3/tests/test_runtime.py +301 -0
  69. mr_piply-0.1.3/tests/test_scheduler.py +207 -0
@@ -0,0 +1 @@
1
+ recursive-include piply/ui *
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: mr-piply
3
+ Version: 0.1.3
4
+ Summary: Lightweight Python workflow orchestration platform
5
+ Author: Medrcm Piply Team
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/gurudevkumar51/piply
8
+ Project-URL: Repository, https://github.com/gurudevkumar51/piply
9
+ Project-URL: Issues, https://github.com/gurudevkumar51/piply/issues
10
+ Keywords: workflow,scheduler,orchestration,automation,pipeline
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ Requires-Dist: fastapi<1.0,>=0.110
23
+ Requires-Dist: uvicorn<1.0,>=0.29
24
+ Requires-Dist: pydantic<3,>=2
25
+ Requires-Dist: jinja2<4,>=3.1
26
+ Requires-Dist: pyyaml<7,>=6
27
+ Requires-Dist: typer<1,>=0.12
28
+ Requires-Dist: httpx<1,>=0.27
29
+ Requires-Dist: python-dotenv<2,>=1
30
+ Provides-Extra: dev
31
+ Requires-Dist: ruff<1,>=0.6; extra == "dev"
32
+ Requires-Dist: pre-commit<4,>=3; extra == "dev"
33
+ Provides-Extra: test
34
+ Requires-Dist: pytest<9,>=8; extra == "test"
35
+ Requires-Dist: pytest-cov<6,>=5; extra == "test"
36
+ Provides-Extra: types
37
+ Requires-Dist: mypy<2,>=1; extra == "types"
38
+ Provides-Extra: build
39
+ Requires-Dist: build<2,>=1; extra == "build"
40
+ Requires-Dist: twine<7,>=6.2; extra == "build"
41
+ Requires-Dist: pkginfo>=1.12; extra == "build"
42
+
43
+ # Piply
44
+
45
+ Piply is a lightweight Python pipeline framework for teams that want script orchestration, schedules, retries, logs, sensors, and a usable operations UI without adopting a heavy orchestration stack.
46
+
47
+ It is intentionally small:
48
+
49
+ - YAML-first pipeline definitions
50
+ - local execution with dependency-aware DAG scheduling
51
+ - SQLite for runs, logs, task outputs, queue state, sensors, and pause overrides
52
+ - FastAPI + server-rendered UI
53
+ - no Redis, Celery, Prefect, Airflow, or external queue required
54
+
55
+ ## What You Get
56
+
57
+ - Multi-task pipelines with `depends_on`
58
+ - Sequential or parallel execution inferred from the DAG
59
+ - Python script and Python callable tasks
60
+ - CLI, API, webhook, email, and SSH task types
61
+ - Task output passing with `context["task_id"]`
62
+ - Pipeline-to-pipeline JSON output passing
63
+ - Per-task upstream failure behavior: `skip`, `fail`, or `continue`
64
+ - Schedule backfill through an internal SQLite queue
65
+ - File, SQL, and API sensors
66
+ - Reusable SQL connections and explicit secret references
67
+ - Retries, resume-from-failure, cancellation, and logs
68
+ - Queue and local worker metrics
69
+ - Dashboard, Pipelines, Execution Matrix, Logs, Settings, and run detail pages
70
+
71
+ ## Quick Start
72
+
73
+ ```bash
74
+ pip install -e .
75
+ copy .env.example .env
76
+ piply validate --config piply-demo/piply.yaml
77
+ piply start --config piply-demo/piply.yaml
78
+ ```
79
+
80
+ Open `http://127.0.0.1:8000`.
81
+
82
+ Create a starter project:
83
+
84
+ ```bash
85
+ piply init my-piply-project
86
+ piply validate --config my-piply-project/piply.yaml
87
+ piply start --config my-piply-project/piply.yaml
88
+ ```
89
+
90
+ The generated starter includes a runnable `extract_flow -> report_flow` chain plus disabled reference pipelines for optional operators and sensors.
91
+
92
+ ## Example YAML
93
+
94
+ ```yaml
95
+ version: "1"
96
+ title: Piply Workspace
97
+ workspace: .
98
+
99
+ secrets:
100
+ backend: env
101
+ prefix: PIPLY_SECRET_
102
+
103
+ connections:
104
+ app_db: sqlite:///sensor_demo.db
105
+
106
+ pipelines:
107
+ extract_flow:
108
+ schedule:
109
+ every: 15m
110
+ retry:
111
+ attempts: 2
112
+ mode: resume
113
+ delay_seconds: 10
114
+ max_parallel_tasks: 2
115
+ triggers_on_success:
116
+ - report_flow
117
+ sensors:
118
+ inbound_rows:
119
+ type: sql_sensor
120
+ connection_ref: app_db
121
+ table: inbound_events
122
+ cursor_column: id
123
+ tasks:
124
+ extract:
125
+ type: python
126
+ path: pipelines/extract.py
127
+ function: extract_data
128
+ kwargs:
129
+ records: 120
130
+
131
+ transform:
132
+ type: python
133
+ path: pipelines/extract.py
134
+ function: transform_data
135
+ depends_on: [extract]
136
+
137
+ validate:
138
+ type: cli
139
+ command: python -c "print('validated')"
140
+ depends_on: [transform]
141
+
142
+ publish_manifest:
143
+ type: cli
144
+ command: python -c "print('published')"
145
+ depends_on: [transform]
146
+ on_upstream_failure: skip
147
+
148
+ report_flow:
149
+ tasks:
150
+ build_report:
151
+ type: python
152
+ path: pipelines/report.py
153
+ function: build_report
154
+ ```
155
+
156
+ Python callable tasks can consume upstream outputs:
157
+
158
+ ```python
159
+ def transform_data(context):
160
+ extracted = context["extract"]
161
+ return {"records": extracted["records"] + 1}
162
+ ```
163
+
164
+ When `extract_flow` triggers `report_flow`, JSON outputs are also passed into the downstream context.
165
+
166
+ ## CLI
167
+
168
+ ```bash
169
+ piply init
170
+ piply validate --config piply-demo/piply.yaml
171
+ piply list --config piply-demo/piply.yaml
172
+ piply run extract_flow --config piply-demo/piply.yaml --wait
173
+ piply tasks list extract_flow --config piply-demo/piply.yaml
174
+ piply tasks run extract_flow publish_manifest --config piply-demo/piply.yaml
175
+ piply tasks retry <run_id> <task_id> --mode resume --config piply-demo/piply.yaml
176
+ piply runs --config piply-demo/piply.yaml
177
+ piply logs <run_id> --config piply-demo/piply.yaml
178
+ piply pause extract_flow --config piply-demo/piply.yaml
179
+ piply resume extract_flow --config piply-demo/piply.yaml
180
+ piply start --config piply-demo/piply.yaml
181
+ piply stop --config piply-demo/piply.yaml
182
+ ```
183
+
184
+ ## API Highlights
185
+
186
+ - `GET /api/dashboard`
187
+ - `GET /api/pipelines`
188
+ - `GET /api/pipelines/{pipeline_id}`
189
+ - `POST /api/pipelines/{pipeline_id}/run`
190
+ - `POST /api/pipelines/{pipeline_id}/tasks/{task_id}/run`
191
+ - `POST /api/pipelines/{pipeline_id}/chain/{target_pipeline_id}`
192
+ - `GET /api/runs`
193
+ - `GET /api/runs/{run_id}`
194
+ - `GET /api/runs/{run_id}/tasks/{task_id}`
195
+ - `GET /api/runs/{run_id}/tasks/{task_id}/output`
196
+ - `POST /api/runs/{run_id}/retry`
197
+ - `POST /api/runs/{run_id}/tasks/{task_id}/retry`
198
+ - `GET /api/metrics`
199
+ - `GET /api/execution-matrix`
200
+ - `GET /api/logs`
201
+
202
+ ## Runtime Model
203
+
204
+ Piply runs locally and keeps state in SQLite. The scheduler materializes due schedules and sensor events into an internal queue, then dispatches work with per-pipeline backpressure. The engine executes tasks through lightweight local workers and records task runs, logs, output metadata, retries, lineage, and parent/child pipeline relationships. CLI `--wait` runs complete downstream pipeline triggers inline so chained smoke tests finish deterministically.
205
+
206
+ ## Roadmap
207
+
208
+ Planned features:
209
+
210
+ - `piply logs --follow`
211
+ - reusable task templates / profiles
212
+ - plugin hooks for custom operators
213
+ - UI controls for editing pipeline definitions safely
214
+ - artifact retention policies for large outputs
215
+ - optional distributed runner while keeping local mode as the default
216
+
217
+ ## More Docs
218
+
219
+ - `wiki/USAGE_GUIDE.md`
220
+ - `wiki/README.md`
221
+ - `wiki/UI_API_GUIDE.md`
222
+ - `wiki/IMPLEMENTATION_SUMMARY.md`
@@ -0,0 +1,180 @@
1
+ # Piply
2
+
3
+ Piply is a lightweight Python pipeline framework for teams that want script orchestration, schedules, retries, logs, sensors, and a usable operations UI without adopting a heavy orchestration stack.
4
+
5
+ It is intentionally small:
6
+
7
+ - YAML-first pipeline definitions
8
+ - local execution with dependency-aware DAG scheduling
9
+ - SQLite for runs, logs, task outputs, queue state, sensors, and pause overrides
10
+ - FastAPI + server-rendered UI
11
+ - no Redis, Celery, Prefect, Airflow, or external queue required
12
+
13
+ ## What You Get
14
+
15
+ - Multi-task pipelines with `depends_on`
16
+ - Sequential or parallel execution inferred from the DAG
17
+ - Python script and Python callable tasks
18
+ - CLI, API, webhook, email, and SSH task types
19
+ - Task output passing with `context["task_id"]`
20
+ - Pipeline-to-pipeline JSON output passing
21
+ - Per-task upstream failure behavior: `skip`, `fail`, or `continue`
22
+ - Schedule backfill through an internal SQLite queue
23
+ - File, SQL, and API sensors
24
+ - Reusable SQL connections and explicit secret references
25
+ - Retries, resume-from-failure, cancellation, and logs
26
+ - Queue and local worker metrics
27
+ - Dashboard, Pipelines, Execution Matrix, Logs, Settings, and run detail pages
28
+
29
+ ## Quick Start
30
+
31
+ ```bash
32
+ pip install -e .
33
+ copy .env.example .env
34
+ piply validate --config piply-demo/piply.yaml
35
+ piply start --config piply-demo/piply.yaml
36
+ ```
37
+
38
+ Open `http://127.0.0.1:8000`.
39
+
40
+ Create a starter project:
41
+
42
+ ```bash
43
+ piply init my-piply-project
44
+ piply validate --config my-piply-project/piply.yaml
45
+ piply start --config my-piply-project/piply.yaml
46
+ ```
47
+
48
+ The generated starter includes a runnable `extract_flow -> report_flow` chain plus disabled reference pipelines for optional operators and sensors.
49
+
50
+ ## Example YAML
51
+
52
+ ```yaml
53
+ version: "1"
54
+ title: Piply Workspace
55
+ workspace: .
56
+
57
+ secrets:
58
+ backend: env
59
+ prefix: PIPLY_SECRET_
60
+
61
+ connections:
62
+ app_db: sqlite:///sensor_demo.db
63
+
64
+ pipelines:
65
+ extract_flow:
66
+ schedule:
67
+ every: 15m
68
+ retry:
69
+ attempts: 2
70
+ mode: resume
71
+ delay_seconds: 10
72
+ max_parallel_tasks: 2
73
+ triggers_on_success:
74
+ - report_flow
75
+ sensors:
76
+ inbound_rows:
77
+ type: sql_sensor
78
+ connection_ref: app_db
79
+ table: inbound_events
80
+ cursor_column: id
81
+ tasks:
82
+ extract:
83
+ type: python
84
+ path: pipelines/extract.py
85
+ function: extract_data
86
+ kwargs:
87
+ records: 120
88
+
89
+ transform:
90
+ type: python
91
+ path: pipelines/extract.py
92
+ function: transform_data
93
+ depends_on: [extract]
94
+
95
+ validate:
96
+ type: cli
97
+ command: python -c "print('validated')"
98
+ depends_on: [transform]
99
+
100
+ publish_manifest:
101
+ type: cli
102
+ command: python -c "print('published')"
103
+ depends_on: [transform]
104
+ on_upstream_failure: skip
105
+
106
+ report_flow:
107
+ tasks:
108
+ build_report:
109
+ type: python
110
+ path: pipelines/report.py
111
+ function: build_report
112
+ ```
113
+
114
+ Python callable tasks can consume upstream outputs:
115
+
116
+ ```python
117
+ def transform_data(context):
118
+ extracted = context["extract"]
119
+ return {"records": extracted["records"] + 1}
120
+ ```
121
+
122
+ When `extract_flow` triggers `report_flow`, JSON outputs are also passed into the downstream context.
123
+
124
+ ## CLI
125
+
126
+ ```bash
127
+ piply init
128
+ piply validate --config piply-demo/piply.yaml
129
+ piply list --config piply-demo/piply.yaml
130
+ piply run extract_flow --config piply-demo/piply.yaml --wait
131
+ piply tasks list extract_flow --config piply-demo/piply.yaml
132
+ piply tasks run extract_flow publish_manifest --config piply-demo/piply.yaml
133
+ piply tasks retry <run_id> <task_id> --mode resume --config piply-demo/piply.yaml
134
+ piply runs --config piply-demo/piply.yaml
135
+ piply logs <run_id> --config piply-demo/piply.yaml
136
+ piply pause extract_flow --config piply-demo/piply.yaml
137
+ piply resume extract_flow --config piply-demo/piply.yaml
138
+ piply start --config piply-demo/piply.yaml
139
+ piply stop --config piply-demo/piply.yaml
140
+ ```
141
+
142
+ ## API Highlights
143
+
144
+ - `GET /api/dashboard`
145
+ - `GET /api/pipelines`
146
+ - `GET /api/pipelines/{pipeline_id}`
147
+ - `POST /api/pipelines/{pipeline_id}/run`
148
+ - `POST /api/pipelines/{pipeline_id}/tasks/{task_id}/run`
149
+ - `POST /api/pipelines/{pipeline_id}/chain/{target_pipeline_id}`
150
+ - `GET /api/runs`
151
+ - `GET /api/runs/{run_id}`
152
+ - `GET /api/runs/{run_id}/tasks/{task_id}`
153
+ - `GET /api/runs/{run_id}/tasks/{task_id}/output`
154
+ - `POST /api/runs/{run_id}/retry`
155
+ - `POST /api/runs/{run_id}/tasks/{task_id}/retry`
156
+ - `GET /api/metrics`
157
+ - `GET /api/execution-matrix`
158
+ - `GET /api/logs`
159
+
160
+ ## Runtime Model
161
+
162
+ Piply runs locally and keeps state in SQLite. The scheduler materializes due schedules and sensor events into an internal queue, then dispatches work with per-pipeline backpressure. The engine executes tasks through lightweight local workers and records task runs, logs, output metadata, retries, lineage, and parent/child pipeline relationships. CLI `--wait` runs complete downstream pipeline triggers inline so chained smoke tests finish deterministically.
163
+
164
+ ## Roadmap
165
+
166
+ Planned features:
167
+
168
+ - `piply logs --follow`
169
+ - reusable task templates / profiles
170
+ - plugin hooks for custom operators
171
+ - UI controls for editing pipeline definitions safely
172
+ - artifact retention policies for large outputs
173
+ - optional distributed runner while keeping local mode as the default
174
+
175
+ ## More Docs
176
+
177
+ - `wiki/USAGE_GUIDE.md`
178
+ - `wiki/README.md`
179
+ - `wiki/UI_API_GUIDE.md`
180
+ - `wiki/IMPLEMENTATION_SUMMARY.md`
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: mr-piply
3
+ Version: 0.1.3
4
+ Summary: Lightweight Python workflow orchestration platform
5
+ Author: Medrcm Piply Team
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/gurudevkumar51/piply
8
+ Project-URL: Repository, https://github.com/gurudevkumar51/piply
9
+ Project-URL: Issues, https://github.com/gurudevkumar51/piply/issues
10
+ Keywords: workflow,scheduler,orchestration,automation,pipeline
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ Requires-Dist: fastapi<1.0,>=0.110
23
+ Requires-Dist: uvicorn<1.0,>=0.29
24
+ Requires-Dist: pydantic<3,>=2
25
+ Requires-Dist: jinja2<4,>=3.1
26
+ Requires-Dist: pyyaml<7,>=6
27
+ Requires-Dist: typer<1,>=0.12
28
+ Requires-Dist: httpx<1,>=0.27
29
+ Requires-Dist: python-dotenv<2,>=1
30
+ Provides-Extra: dev
31
+ Requires-Dist: ruff<1,>=0.6; extra == "dev"
32
+ Requires-Dist: pre-commit<4,>=3; extra == "dev"
33
+ Provides-Extra: test
34
+ Requires-Dist: pytest<9,>=8; extra == "test"
35
+ Requires-Dist: pytest-cov<6,>=5; extra == "test"
36
+ Provides-Extra: types
37
+ Requires-Dist: mypy<2,>=1; extra == "types"
38
+ Provides-Extra: build
39
+ Requires-Dist: build<2,>=1; extra == "build"
40
+ Requires-Dist: twine<7,>=6.2; extra == "build"
41
+ Requires-Dist: pkginfo>=1.12; extra == "build"
42
+
43
+ # Piply
44
+
45
+ Piply is a lightweight Python pipeline framework for teams that want script orchestration, schedules, retries, logs, sensors, and a usable operations UI without adopting a heavy orchestration stack.
46
+
47
+ It is intentionally small:
48
+
49
+ - YAML-first pipeline definitions
50
+ - local execution with dependency-aware DAG scheduling
51
+ - SQLite for runs, logs, task outputs, queue state, sensors, and pause overrides
52
+ - FastAPI + server-rendered UI
53
+ - no Redis, Celery, Prefect, Airflow, or external queue required
54
+
55
+ ## What You Get
56
+
57
+ - Multi-task pipelines with `depends_on`
58
+ - Sequential or parallel execution inferred from the DAG
59
+ - Python script and Python callable tasks
60
+ - CLI, API, webhook, email, and SSH task types
61
+ - Task output passing with `context["task_id"]`
62
+ - Pipeline-to-pipeline JSON output passing
63
+ - Per-task upstream failure behavior: `skip`, `fail`, or `continue`
64
+ - Schedule backfill through an internal SQLite queue
65
+ - File, SQL, and API sensors
66
+ - Reusable SQL connections and explicit secret references
67
+ - Retries, resume-from-failure, cancellation, and logs
68
+ - Queue and local worker metrics
69
+ - Dashboard, Pipelines, Execution Matrix, Logs, Settings, and run detail pages
70
+
71
+ ## Quick Start
72
+
73
+ ```bash
74
+ pip install -e .
75
+ copy .env.example .env
76
+ piply validate --config piply-demo/piply.yaml
77
+ piply start --config piply-demo/piply.yaml
78
+ ```
79
+
80
+ Open `http://127.0.0.1:8000`.
81
+
82
+ Create a starter project:
83
+
84
+ ```bash
85
+ piply init my-piply-project
86
+ piply validate --config my-piply-project/piply.yaml
87
+ piply start --config my-piply-project/piply.yaml
88
+ ```
89
+
90
+ The generated starter includes a runnable `extract_flow -> report_flow` chain plus disabled reference pipelines for optional operators and sensors.
91
+
92
+ ## Example YAML
93
+
94
+ ```yaml
95
+ version: "1"
96
+ title: Piply Workspace
97
+ workspace: .
98
+
99
+ secrets:
100
+ backend: env
101
+ prefix: PIPLY_SECRET_
102
+
103
+ connections:
104
+ app_db: sqlite:///sensor_demo.db
105
+
106
+ pipelines:
107
+ extract_flow:
108
+ schedule:
109
+ every: 15m
110
+ retry:
111
+ attempts: 2
112
+ mode: resume
113
+ delay_seconds: 10
114
+ max_parallel_tasks: 2
115
+ triggers_on_success:
116
+ - report_flow
117
+ sensors:
118
+ inbound_rows:
119
+ type: sql_sensor
120
+ connection_ref: app_db
121
+ table: inbound_events
122
+ cursor_column: id
123
+ tasks:
124
+ extract:
125
+ type: python
126
+ path: pipelines/extract.py
127
+ function: extract_data
128
+ kwargs:
129
+ records: 120
130
+
131
+ transform:
132
+ type: python
133
+ path: pipelines/extract.py
134
+ function: transform_data
135
+ depends_on: [extract]
136
+
137
+ validate:
138
+ type: cli
139
+ command: python -c "print('validated')"
140
+ depends_on: [transform]
141
+
142
+ publish_manifest:
143
+ type: cli
144
+ command: python -c "print('published')"
145
+ depends_on: [transform]
146
+ on_upstream_failure: skip
147
+
148
+ report_flow:
149
+ tasks:
150
+ build_report:
151
+ type: python
152
+ path: pipelines/report.py
153
+ function: build_report
154
+ ```
155
+
156
+ Python callable tasks can consume upstream outputs:
157
+
158
+ ```python
159
+ def transform_data(context):
160
+ extracted = context["extract"]
161
+ return {"records": extracted["records"] + 1}
162
+ ```
163
+
164
+ When `extract_flow` triggers `report_flow`, JSON outputs are also passed into the downstream context.
165
+
166
+ ## CLI
167
+
168
+ ```bash
169
+ piply init
170
+ piply validate --config piply-demo/piply.yaml
171
+ piply list --config piply-demo/piply.yaml
172
+ piply run extract_flow --config piply-demo/piply.yaml --wait
173
+ piply tasks list extract_flow --config piply-demo/piply.yaml
174
+ piply tasks run extract_flow publish_manifest --config piply-demo/piply.yaml
175
+ piply tasks retry <run_id> <task_id> --mode resume --config piply-demo/piply.yaml
176
+ piply runs --config piply-demo/piply.yaml
177
+ piply logs <run_id> --config piply-demo/piply.yaml
178
+ piply pause extract_flow --config piply-demo/piply.yaml
179
+ piply resume extract_flow --config piply-demo/piply.yaml
180
+ piply start --config piply-demo/piply.yaml
181
+ piply stop --config piply-demo/piply.yaml
182
+ ```
183
+
184
+ ## API Highlights
185
+
186
+ - `GET /api/dashboard`
187
+ - `GET /api/pipelines`
188
+ - `GET /api/pipelines/{pipeline_id}`
189
+ - `POST /api/pipelines/{pipeline_id}/run`
190
+ - `POST /api/pipelines/{pipeline_id}/tasks/{task_id}/run`
191
+ - `POST /api/pipelines/{pipeline_id}/chain/{target_pipeline_id}`
192
+ - `GET /api/runs`
193
+ - `GET /api/runs/{run_id}`
194
+ - `GET /api/runs/{run_id}/tasks/{task_id}`
195
+ - `GET /api/runs/{run_id}/tasks/{task_id}/output`
196
+ - `POST /api/runs/{run_id}/retry`
197
+ - `POST /api/runs/{run_id}/tasks/{task_id}/retry`
198
+ - `GET /api/metrics`
199
+ - `GET /api/execution-matrix`
200
+ - `GET /api/logs`
201
+
202
+ ## Runtime Model
203
+
204
+ Piply runs locally and keeps state in SQLite. The scheduler materializes due schedules and sensor events into an internal queue, then dispatches work with per-pipeline backpressure. The engine executes tasks through lightweight local workers and records task runs, logs, output metadata, retries, lineage, and parent/child pipeline relationships. CLI `--wait` runs complete downstream pipeline triggers inline so chained smoke tests finish deterministically.
205
+
206
+ ## Roadmap
207
+
208
+ Planned features:
209
+
210
+ - `piply logs --follow`
211
+ - reusable task templates / profiles
212
+ - plugin hooks for custom operators
213
+ - UI controls for editing pipeline definitions safely
214
+ - artifact retention policies for large outputs
215
+ - optional distributed runner while keeping local mode as the default
216
+
217
+ ## More Docs
218
+
219
+ - `wiki/USAGE_GUIDE.md`
220
+ - `wiki/README.md`
221
+ - `wiki/UI_API_GUIDE.md`
222
+ - `wiki/IMPLEMENTATION_SUMMARY.md`