ddeutil-workflow 0.0.35__py3-none-any.whl → 0.0.36__py3-none-any.whl
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.
- ddeutil/workflow/__about__.py +1 -1
- ddeutil/workflow/__init__.py +2 -0
- ddeutil/workflow/api/api.py +47 -8
- ddeutil/workflow/api/repeat.py +21 -11
- ddeutil/workflow/api/routes/__init__.py +1 -0
- ddeutil/workflow/api/routes/job.py +73 -0
- ddeutil/workflow/api/routes/logs.py +41 -13
- ddeutil/workflow/api/routes/schedules.py +1 -0
- ddeutil/workflow/audit.py +6 -3
- ddeutil/workflow/job.py +6 -16
- ddeutil/workflow/logs.py +164 -52
- ddeutil/workflow/params.py +52 -15
- ddeutil/workflow/result.py +3 -5
- ddeutil/workflow/scheduler.py +31 -10
- ddeutil/workflow/stages.py +61 -4
- ddeutil/workflow/utils.py +7 -1
- ddeutil/workflow/workflow.py +1 -15
- {ddeutil_workflow-0.0.35.dist-info → ddeutil_workflow-0.0.36.dist-info}/METADATA +11 -9
- ddeutil_workflow-0.0.36.dist-info/RECORD +31 -0
- {ddeutil_workflow-0.0.35.dist-info → ddeutil_workflow-0.0.36.dist-info}/WHEEL +1 -1
- ddeutil_workflow-0.0.35.dist-info/RECORD +0 -30
- {ddeutil_workflow-0.0.35.dist-info → ddeutil_workflow-0.0.36.dist-info}/LICENSE +0 -0
- {ddeutil_workflow-0.0.35.dist-info → ddeutil_workflow-0.0.36.dist-info}/top_level.txt +0 -0
ddeutil/workflow/stages.py
CHANGED
@@ -14,8 +14,8 @@ use-case, and it does not worry when I want to create a new one.
|
|
14
14
|
|
15
15
|
Execution --> Ok --> Result with 0
|
16
16
|
|
17
|
-
--> Error
|
18
|
-
|
17
|
+
--> Error ┬-> Result with 1 (if env var was set)
|
18
|
+
╰-> Raise StageException(...)
|
19
19
|
|
20
20
|
On the context I/O that pass to a stage object at execute process. The
|
21
21
|
execute method receives a `params={"params": {...}}` value for mapping to
|
@@ -733,6 +733,26 @@ Stage = Union[
|
|
733
733
|
|
734
734
|
# TODO: Not implement this stages yet
|
735
735
|
class ParallelStage(BaseStage): # pragma: no cov
|
736
|
+
"""Parallel execution stage that execute child stages with parallel.
|
737
|
+
|
738
|
+
Data Validate:
|
739
|
+
>>> stage = {
|
740
|
+
... "name": "Parallel stage execution.",
|
741
|
+
... "parallel": [
|
742
|
+
... {
|
743
|
+
... "name": "Echo first stage",
|
744
|
+
... "echo": "Start run with branch 1",
|
745
|
+
... "sleep": 3,
|
746
|
+
... },
|
747
|
+
... {
|
748
|
+
... "name": "Echo second stage",
|
749
|
+
... "echo": "Start run with branch 2",
|
750
|
+
... "sleep": 1,
|
751
|
+
... },
|
752
|
+
... ]
|
753
|
+
... }
|
754
|
+
"""
|
755
|
+
|
736
756
|
parallel: list[Stage]
|
737
757
|
max_parallel_core: int = Field(default=2)
|
738
758
|
|
@@ -743,6 +763,22 @@ class ParallelStage(BaseStage): # pragma: no cov
|
|
743
763
|
|
744
764
|
# TODO: Not implement this stages yet
|
745
765
|
class ForEachStage(BaseStage): # pragma: no cov
|
766
|
+
"""For-Each execution stage that execute child stages with an item in list of
|
767
|
+
item values.
|
768
|
+
|
769
|
+
Data Validate:
|
770
|
+
>>> stage = {
|
771
|
+
... "name": "For-each stage execution",
|
772
|
+
... "foreach": [1, 2, 3]
|
773
|
+
... "stages": [
|
774
|
+
... {
|
775
|
+
... "name": "Echo stage",
|
776
|
+
... "echo": "Start run with item {{ item }}"
|
777
|
+
... },
|
778
|
+
... ],
|
779
|
+
... }
|
780
|
+
"""
|
781
|
+
|
746
782
|
foreach: list[str]
|
747
783
|
stages: list[Stage]
|
748
784
|
|
@@ -753,9 +789,30 @@ class ForEachStage(BaseStage): # pragma: no cov
|
|
753
789
|
|
754
790
|
# TODO: Not implement this stages yet
|
755
791
|
class HookStage(BaseStage): # pragma: no cov
|
756
|
-
|
757
|
-
|
792
|
+
hook: str
|
793
|
+
args: DictData
|
794
|
+
callback: str
|
758
795
|
|
759
796
|
def execute(
|
760
797
|
self, params: DictData, *, result: Result | None = None
|
761
798
|
) -> Result: ...
|
799
|
+
|
800
|
+
|
801
|
+
# TODO: Not implement this stages yet
|
802
|
+
class DockerStage(BaseStage): # pragma: no cov
|
803
|
+
image: str
|
804
|
+
env: DictData = Field(default_factory=dict)
|
805
|
+
|
806
|
+
def execute(
|
807
|
+
self, params: DictData, *, result: Result | None = None
|
808
|
+
) -> Result: ...
|
809
|
+
|
810
|
+
|
811
|
+
# TODO: Not implement this stages yet
|
812
|
+
class VirtualPyStage(PyStage): # pragma: no cov
|
813
|
+
"""Python Virtual Environment stage execution."""
|
814
|
+
|
815
|
+
run: str
|
816
|
+
vars: DictData
|
817
|
+
|
818
|
+
def create_py_file(self, py: str, run_id: str | None): ...
|
ddeutil/workflow/utils.py
CHANGED
@@ -9,7 +9,7 @@ import logging
|
|
9
9
|
import stat
|
10
10
|
import time
|
11
11
|
from collections.abc import Iterator, Mapping
|
12
|
-
from datetime import datetime, timedelta
|
12
|
+
from datetime import date, datetime, timedelta
|
13
13
|
from hashlib import md5
|
14
14
|
from inspect import isfunction
|
15
15
|
from itertools import chain, islice, product
|
@@ -39,6 +39,12 @@ def get_dt_now(
|
|
39
39
|
return datetime.now(tz=(tz or UTC)) - timedelta(seconds=offset)
|
40
40
|
|
41
41
|
|
42
|
+
def get_d_now(
|
43
|
+
tz: ZoneInfo | None = None, offset: float = 0.0
|
44
|
+
) -> date: # pragma: no cov
|
45
|
+
return (datetime.now(tz=(tz or UTC)) - timedelta(seconds=offset)).date()
|
46
|
+
|
47
|
+
|
42
48
|
def get_diff_sec(
|
43
49
|
dt: datetime, tz: ZoneInfo | None = None, offset: float = 0.0
|
44
50
|
) -> int: # pragma: no cov
|
ddeutil/workflow/workflow.py
CHANGED
@@ -3,21 +3,7 @@
|
|
3
3
|
# Licensed under the MIT License. See LICENSE in the project root for
|
4
4
|
# license information.
|
5
5
|
# ------------------------------------------------------------------------------
|
6
|
-
"""
|
7
|
-
multiprocess of `workflow_control` function for listing schedules on the
|
8
|
-
config by `Loader.finds(Schedule)`.
|
9
|
-
|
10
|
-
The `workflow_control` is the scheduler function that release 2 schedule
|
11
|
-
functions; `workflow_task`, and ``workflow_monitor``.
|
12
|
-
|
13
|
-
``workflow_control`` --- Every minute at :02 --> ``workflow_task``
|
14
|
-
|
15
|
-
--- Every 5 minutes --> ``workflow_monitor``
|
16
|
-
|
17
|
-
The ``workflow_task`` will run ``task.release`` method in threading object
|
18
|
-
for multithreading strategy. This ``release`` method will run only one crontab
|
19
|
-
value with the on field.
|
20
|
-
"""
|
6
|
+
"""A Workflow module."""
|
21
7
|
from __future__ import annotations
|
22
8
|
|
23
9
|
import copy
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: ddeutil-workflow
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.36
|
4
4
|
Summary: Lightweight workflow orchestration
|
5
5
|
Author-email: ddeutils <korawich.anu@gmail.com>
|
6
6
|
License: MIT
|
@@ -29,6 +29,8 @@ Requires-Dist: python-dotenv==1.0.1
|
|
29
29
|
Requires-Dist: schedule<2.0.0,==1.2.2
|
30
30
|
Provides-Extra: api
|
31
31
|
Requires-Dist: fastapi<1.0.0,>=0.115.0; extra == "api"
|
32
|
+
Requires-Dist: httpx; extra == "api"
|
33
|
+
Requires-Dist: ujson; extra == "api"
|
32
34
|
|
33
35
|
# Workflow Orchestration
|
34
36
|
|
@@ -78,12 +80,12 @@ flowchart LR
|
|
78
80
|
|
79
81
|
subgraph Docker Container
|
80
82
|
direction TB
|
81
|
-
G@{ shape: rounded, label: "Observe<br>Application" }
|
83
|
+
G@{ shape: rounded, label: "📡Observe<br>Application" }
|
82
84
|
end
|
83
85
|
|
84
86
|
subgraph Docker Container
|
85
87
|
direction TB
|
86
|
-
B@{ shape: rounded, label: "Workflow<br>Application" }
|
88
|
+
B@{ shape: rounded, label: "🏃Workflow<br>Application" }
|
87
89
|
end
|
88
90
|
|
89
91
|
A <-->|action &<br>response| B
|
@@ -95,7 +97,7 @@ flowchart LR
|
|
95
97
|
E@{ shape: lin-cyl, label: "Audit<br>Logs" }
|
96
98
|
end
|
97
99
|
|
98
|
-
subgraph
|
100
|
+
subgraph Config Context
|
99
101
|
F@{ shape: tag-rect, label: "YAML<br>files" }
|
100
102
|
end
|
101
103
|
|
@@ -130,10 +132,10 @@ This project need `ddeutil` and `ddeutil-io` extension namespace packages.
|
|
130
132
|
If you want to install this package with application add-ons, you should add
|
131
133
|
`app` in installation;
|
132
134
|
|
133
|
-
| Use-case | Install Optional |
|
134
|
-
|
135
|
-
| Python | `ddeutil-workflow` | :heavy_check_mark:
|
136
|
-
| FastAPI Server | `ddeutil-workflow[api]` | :heavy_check_mark:
|
135
|
+
| Use-case | Install Optional | Support |
|
136
|
+
|----------------|--------------------------|:-------------------:|
|
137
|
+
| Python | `ddeutil-workflow` | :heavy_check_mark: |
|
138
|
+
| FastAPI Server | `ddeutil-workflow[api]` | :heavy_check_mark: |
|
137
139
|
|
138
140
|
## :beers: Usage
|
139
141
|
|
@@ -295,7 +297,7 @@ like crontab job but via Python API.
|
|
295
297
|
### API Server
|
296
298
|
|
297
299
|
```shell
|
298
|
-
(venv) $ uvicorn
|
300
|
+
(venv) $ uvicorn ddeutil.workflow.api:app \
|
299
301
|
--host 127.0.0.1 \
|
300
302
|
--port 80 \
|
301
303
|
--no-access-log
|
@@ -0,0 +1,31 @@
|
|
1
|
+
ddeutil/workflow/__about__.py,sha256=sUrITqcQ8T6XPgdiHuk6l8YqDYHRQk2RjtNlY0SjLcs,28
|
2
|
+
ddeutil/workflow/__cron.py,sha256=3i-wmjTlh0ADCzN9pLKaWHzJkXzC72aIBmVEQSbyCCE,26895
|
3
|
+
ddeutil/workflow/__init__.py,sha256=d643WDkk93MjCt9ujD46hX07Mb7yc9eTzKV3QwnEZQg,1845
|
4
|
+
ddeutil/workflow/__types.py,sha256=CK1jfzyHP9P-MB0ElhpJZ59ZFGJC9MkQuAop5739_9k,4304
|
5
|
+
ddeutil/workflow/audit.py,sha256=wx70RKRdHj1d2431ilpt9OPTInMByjqXkYff7l5pvF4,8230
|
6
|
+
ddeutil/workflow/caller.py,sha256=qNfrr0B2ykLm6Y8JfhU1rnf5XGmp-usXrPmXM5uGRnM,5473
|
7
|
+
ddeutil/workflow/conf.py,sha256=cFc2cd_SGXg9PMrkvCT7WWE85a5UN-DdH53_JIbFyzs,14031
|
8
|
+
ddeutil/workflow/cron.py,sha256=j8EeoHst70toRfnD_frix41vrI-eLYVJkZ9yeJtpfnI,8871
|
9
|
+
ddeutil/workflow/exceptions.py,sha256=5ghT443VLq0IeU87loHNEqqrrrctklP7YfxwJ51ImWU,949
|
10
|
+
ddeutil/workflow/job.py,sha256=lpuWQdAFlFUmP0H7ha217sDwbvFlqSuqyAo4Q1yhAa8,24527
|
11
|
+
ddeutil/workflow/logs.py,sha256=EJDb9Xt3XWjTGE8CeEvw0eDU8kyaeStALQNAtTl5HQw,10027
|
12
|
+
ddeutil/workflow/params.py,sha256=qw9XJyjh2ocf9pf6h_XiYHLOvQN4R5TMqPElmItKnRM,8019
|
13
|
+
ddeutil/workflow/result.py,sha256=fbM2An3VyweMjAy4Iw7h8H-KkoQsDrZe_KjGztXAFkE,4319
|
14
|
+
ddeutil/workflow/scheduler.py,sha256=6KozyZZSXtDqQxpUwS4o-J1h_HhGbwFV5Abul3_I4W4,25940
|
15
|
+
ddeutil/workflow/stages.py,sha256=euT_v_xk0iqxWOFVZCHuFN8zREgc3-d06j5LMY8AJaE,28020
|
16
|
+
ddeutil/workflow/templates.py,sha256=A0JgZFGkBv-AX-EskZj656nG5zFd3j1PpLpyXihf6Xg,10967
|
17
|
+
ddeutil/workflow/utils.py,sha256=Djzd7Bz5QYAw0GqTFv6a0yWm_D8Md0XDxjWudmscQI0,7406
|
18
|
+
ddeutil/workflow/workflow.py,sha256=_LYfs15AcXWVpM8CaO4oH6SWoJnqzF5FU08QTDoHT5w,44529
|
19
|
+
ddeutil/workflow/api/__init__.py,sha256=F53NMBWtb9IKaDWkPU5KvybGGfKAcbehgn6TLBwHuuM,21
|
20
|
+
ddeutil/workflow/api/api.py,sha256=fBFfJtpf7CL4Vym4iiZtWsrrnICGnwYKHBTwLoatPB4,5151
|
21
|
+
ddeutil/workflow/api/repeat.py,sha256=g7VAP4O8ocKj5Uts5Q9P-OAfeDhKk7a4VWQDlOttTXA,5280
|
22
|
+
ddeutil/workflow/api/routes/__init__.py,sha256=qoGtOMyVgQ5nTUc8J8wH27A8isaxl3IFCX8qoyibeCY,484
|
23
|
+
ddeutil/workflow/api/routes/job.py,sha256=BXh8ikYKicCgzt13MysbtGgLrAPuts4dpgkD7iHTjrs,1901
|
24
|
+
ddeutil/workflow/api/routes/logs.py,sha256=sHhQuigOQ6YQ34V56d9Is6eHbV-zE45v6gPntD7lgS8,1909
|
25
|
+
ddeutil/workflow/api/routes/schedules.py,sha256=Oj8QLJJ852Lv2y40wGhuXjY2IEdhjAoGBxSWCkxe3YY,4675
|
26
|
+
ddeutil/workflow/api/routes/workflows.py,sha256=LQiLlB3tESUtOZWcuLUKIHKvnit_yX3fKzYB4FqhavI,4354
|
27
|
+
ddeutil_workflow-0.0.36.dist-info/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
|
28
|
+
ddeutil_workflow-0.0.36.dist-info/METADATA,sha256=OwDce5Gz0qVtJLQbmvbgthMfH6bD68Xaqm-B8RfLeRg,19354
|
29
|
+
ddeutil_workflow-0.0.36.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
30
|
+
ddeutil_workflow-0.0.36.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
|
31
|
+
ddeutil_workflow-0.0.36.dist-info/RECORD,,
|
@@ -1,30 +0,0 @@
|
|
1
|
-
ddeutil/workflow/__about__.py,sha256=nntH3Ja8ABeB5HcYg4Fy7-Z6jDBj67mjILrr2_dJHiw,28
|
2
|
-
ddeutil/workflow/__cron.py,sha256=3i-wmjTlh0ADCzN9pLKaWHzJkXzC72aIBmVEQSbyCCE,26895
|
3
|
-
ddeutil/workflow/__init__.py,sha256=SX48GHuEMoxJiKKXbBWT8IxcIk9AnibB-T8cUj1Dx1k,1818
|
4
|
-
ddeutil/workflow/__types.py,sha256=CK1jfzyHP9P-MB0ElhpJZ59ZFGJC9MkQuAop5739_9k,4304
|
5
|
-
ddeutil/workflow/audit.py,sha256=kWymGFEy4WBUXDez1QLRU3FvqLMYQhKJHAzAvIms_Vk,8077
|
6
|
-
ddeutil/workflow/caller.py,sha256=qNfrr0B2ykLm6Y8JfhU1rnf5XGmp-usXrPmXM5uGRnM,5473
|
7
|
-
ddeutil/workflow/conf.py,sha256=cFc2cd_SGXg9PMrkvCT7WWE85a5UN-DdH53_JIbFyzs,14031
|
8
|
-
ddeutil/workflow/cron.py,sha256=j8EeoHst70toRfnD_frix41vrI-eLYVJkZ9yeJtpfnI,8871
|
9
|
-
ddeutil/workflow/exceptions.py,sha256=5ghT443VLq0IeU87loHNEqqrrrctklP7YfxwJ51ImWU,949
|
10
|
-
ddeutil/workflow/job.py,sha256=iUrmNbpBCpxMJyK_hAxpnyLBtrVhyDCoua4X12CH_BI,24702
|
11
|
-
ddeutil/workflow/logs.py,sha256=fmtZl7lQYhKre_auADN64jqD2cqN4aMkNUZdMdhKioM,6398
|
12
|
-
ddeutil/workflow/params.py,sha256=bqFDOcfAGcZ-HYa2n_5tO31uw3KXc66wHpUZ5cgpsTk,6702
|
13
|
-
ddeutil/workflow/result.py,sha256=iuMvKv5OAzKWDbQf3yfrMHNEse6VdqvsKjv-DXKk-aQ,4349
|
14
|
-
ddeutil/workflow/scheduler.py,sha256=DTD5HbCB8oQaxvAQ51-hvpec-NmDIYpyAXsMTODWuoc,25401
|
15
|
-
ddeutil/workflow/stages.py,sha256=4SJcseBw4hv9WahJIXfaPdgn9-1Rbti_awMxO-AiP8s,26438
|
16
|
-
ddeutil/workflow/templates.py,sha256=A0JgZFGkBv-AX-EskZj656nG5zFd3j1PpLpyXihf6Xg,10967
|
17
|
-
ddeutil/workflow/utils.py,sha256=MctJmvklTYtiqZ-nZ7fazQeDoe77UvU0YUEqQZSlbCs,7225
|
18
|
-
ddeutil/workflow/workflow.py,sha256=-n-8C0P-SY0BRc1ak6YhP_J2tT924O6ZkCnDJQFu-z8,45156
|
19
|
-
ddeutil/workflow/api/__init__.py,sha256=F53NMBWtb9IKaDWkPU5KvybGGfKAcbehgn6TLBwHuuM,21
|
20
|
-
ddeutil/workflow/api/api.py,sha256=q7wE0CDPCzpwmhnqKO5qSVO2Mjl1folqwF5E4W-l_UE,4042
|
21
|
-
ddeutil/workflow/api/repeat.py,sha256=zyvsrXKk-3-_N8ZRZSki0Mueshugum2jtqctEOp9QSc,4927
|
22
|
-
ddeutil/workflow/api/routes/__init__.py,sha256=HRUg4yB3023Iml8FQKuY0X6u9FavJe-HqEl6V8N_4hs,450
|
23
|
-
ddeutil/workflow/api/routes/logs.py,sha256=uC8daeCrH_vpVJ-9Um5dMGfHR8JVtwwrDH5I1-Vp6Sw,971
|
24
|
-
ddeutil/workflow/api/routes/schedules.py,sha256=9Q4cPYQWOyiZ1lnanpwtIaLWQtLRX1Vwx7uE30cd_1w,4644
|
25
|
-
ddeutil/workflow/api/routes/workflows.py,sha256=LQiLlB3tESUtOZWcuLUKIHKvnit_yX3fKzYB4FqhavI,4354
|
26
|
-
ddeutil_workflow-0.0.35.dist-info/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
|
27
|
-
ddeutil_workflow-0.0.35.dist-info/METADATA,sha256=FGRFLyia45WdWsiJin8fuTmLoD5-MqKDO63tflCJCzI,19269
|
28
|
-
ddeutil_workflow-0.0.35.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
|
29
|
-
ddeutil_workflow-0.0.35.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
|
30
|
-
ddeutil_workflow-0.0.35.dist-info/RECORD,,
|
File without changes
|
File without changes
|