ddeutil-workflow 0.0.34__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 +8 -3
- ddeutil/workflow/api/api.py +58 -14
- ddeutil/workflow/api/repeat.py +21 -11
- ddeutil/workflow/api/routes/__init__.py +9 -0
- ddeutil/workflow/api/routes/job.py +73 -0
- ddeutil/workflow/api/routes/logs.py +64 -0
- ddeutil/workflow/api/{route.py → routes/schedules.py} +3 -131
- ddeutil/workflow/api/routes/workflows.py +137 -0
- ddeutil/workflow/audit.py +9 -6
- ddeutil/workflow/{call.py → caller.py} +4 -4
- ddeutil/workflow/job.py +63 -24
- ddeutil/workflow/logs.py +326 -0
- ddeutil/workflow/params.py +87 -22
- ddeutil/workflow/result.py +17 -141
- ddeutil/workflow/scheduler.py +69 -41
- ddeutil/workflow/stages.py +68 -14
- ddeutil/workflow/utils.py +7 -1
- ddeutil/workflow/workflow.py +2 -16
- {ddeutil_workflow-0.0.34.dist-info → ddeutil_workflow-0.0.36.dist-info}/METADATA +32 -27
- ddeutil_workflow-0.0.36.dist-info/RECORD +31 -0
- {ddeutil_workflow-0.0.34.dist-info → ddeutil_workflow-0.0.36.dist-info}/WHEEL +1 -1
- ddeutil_workflow-0.0.34.dist-info/RECORD +0 -26
- {ddeutil_workflow-0.0.34.dist-info → ddeutil_workflow-0.0.36.dist-info}/LICENSE +0 -0
- {ddeutil_workflow-0.0.34.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
|
@@ -42,7 +42,7 @@ from pydantic.functional_validators import model_validator
|
|
42
42
|
from typing_extensions import Self
|
43
43
|
|
44
44
|
from .__types import DictData, DictStr, TupleStr
|
45
|
-
from .
|
45
|
+
from .caller import TagFunc, extract_call
|
46
46
|
from .conf import config, get_logger
|
47
47
|
from .exceptions import StageException
|
48
48
|
from .result import Result, Status
|
@@ -174,15 +174,12 @@ class BaseStage(BaseModel, ABC):
|
|
174
174
|
|
175
175
|
:rtype: Result
|
176
176
|
"""
|
177
|
-
|
178
|
-
result
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
)
|
184
|
-
elif parent_run_id:
|
185
|
-
result.set_parent_run_id(parent_run_id)
|
177
|
+
result: Result = Result.construct_with_rs_or_id(
|
178
|
+
result,
|
179
|
+
run_id=run_id,
|
180
|
+
parent_run_id=parent_run_id,
|
181
|
+
id_logic=(self.name + (self.id or "")),
|
182
|
+
)
|
186
183
|
|
187
184
|
try:
|
188
185
|
return self.execute(params, result=result)
|
@@ -736,6 +733,26 @@ Stage = Union[
|
|
736
733
|
|
737
734
|
# TODO: Not implement this stages yet
|
738
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
|
+
|
739
756
|
parallel: list[Stage]
|
740
757
|
max_parallel_core: int = Field(default=2)
|
741
758
|
|
@@ -746,6 +763,22 @@ class ParallelStage(BaseStage): # pragma: no cov
|
|
746
763
|
|
747
764
|
# TODO: Not implement this stages yet
|
748
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
|
+
|
749
782
|
foreach: list[str]
|
750
783
|
stages: list[Stage]
|
751
784
|
|
@@ -756,9 +789,30 @@ class ForEachStage(BaseStage): # pragma: no cov
|
|
756
789
|
|
757
790
|
# TODO: Not implement this stages yet
|
758
791
|
class HookStage(BaseStage): # pragma: no cov
|
759
|
-
|
760
|
-
|
792
|
+
hook: str
|
793
|
+
args: DictData
|
794
|
+
callback: str
|
795
|
+
|
796
|
+
def execute(
|
797
|
+
self, params: DictData, *, result: Result | None = None
|
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)
|
761
805
|
|
762
806
|
def execute(
|
763
807
|
self, params: DictData, *, result: Result | None = None
|
764
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
|
@@ -529,7 +515,7 @@ class Workflow(BaseModel):
|
|
529
515
|
run_id=(run_id or gen_id(name, unique=True)),
|
530
516
|
parent_run_id=parent_run_id,
|
531
517
|
)
|
532
|
-
elif parent_run_id:
|
518
|
+
elif parent_run_id: # pragma: no cov
|
533
519
|
result.set_parent_run_id(parent_run_id)
|
534
520
|
|
535
521
|
if queue is not None and not isinstance(queue, ReleaseQueue):
|
@@ -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
|
|
@@ -62,7 +64,7 @@ configuration. It called **Metadata Driven Data Workflow**.
|
|
62
64
|
1. The Minimum frequency unit of scheduling is **1 minute** :warning:
|
63
65
|
2. Can not re-run only failed stage and its pending downstream :rotating_light:
|
64
66
|
3. All parallel tasks inside workflow engine use Multi-Threading
|
65
|
-
(Python 3.13 unlock GIL :unlock:)
|
67
|
+
(🐍 Python 3.13 unlock GIL :unlock:)
|
66
68
|
|
67
69
|
---
|
68
70
|
|
@@ -78,45 +80,48 @@ 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
|
-
A
|
90
|
-
B
|
91
|
-
G
|
91
|
+
A <-->|action &<br>response| B
|
92
|
+
B -...-> |response| G
|
93
|
+
G -...-> |request| B
|
92
94
|
|
93
95
|
subgraph Data Context
|
94
|
-
|
95
|
-
|
96
|
+
D@{ shape: processes, label: "Logs" }
|
97
|
+
E@{ shape: lin-cyl, label: "Audit<br>Logs" }
|
96
98
|
end
|
97
99
|
|
98
|
-
subgraph
|
99
|
-
|
100
|
+
subgraph Config Context
|
101
|
+
F@{ shape: tag-rect, label: "YAML<br>files" }
|
100
102
|
end
|
101
103
|
|
102
|
-
|
103
|
-
|
104
|
+
A ---> |push| H(Repo)
|
105
|
+
H -.-> |pull| F
|
104
106
|
|
105
|
-
B
|
106
|
-
|
107
|
-
B
|
107
|
+
B <-->|disable &<br>read| F
|
108
|
+
|
109
|
+
B <-->|read &<br>write| E
|
110
|
+
|
111
|
+
B -->|write| D
|
108
112
|
|
109
113
|
D -.->|read| G
|
110
114
|
E -.->|read| G
|
111
115
|
```
|
112
116
|
|
113
117
|
> [!WARNING]
|
114
|
-
>
|
115
|
-
>
|
116
|
-
>
|
117
|
-
|
118
|
-
>
|
119
|
-
>
|
118
|
+
> _**Disclaimer**_: I inspire the dynamic YAML statement from the [**GitHub Action**](https://github.com/features/actions),
|
119
|
+
> and all configs pattern from several data orchestration framework tools from
|
120
|
+
> my data engineering experience. :grimacing:
|
121
|
+
|
122
|
+
> [!NOTE]
|
123
|
+
> Other workflow orchestration tools that I interest and pick them to be inspiration
|
124
|
+
> some for this package:
|
120
125
|
>
|
121
126
|
> - [Google **Workflows**](https://cloud.google.com/workflows)
|
122
127
|
> - [AWS **Step Functions**](https://aws.amazon.com/step-functions/)
|
@@ -127,10 +132,10 @@ This project need `ddeutil` and `ddeutil-io` extension namespace packages.
|
|
127
132
|
If you want to install this package with application add-ons, you should add
|
128
133
|
`app` in installation;
|
129
134
|
|
130
|
-
| Use-case | Install Optional |
|
131
|
-
|
132
|
-
| Python | `ddeutil-workflow` | :heavy_check_mark:
|
133
|
-
| 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: |
|
134
139
|
|
135
140
|
## :beers: Usage
|
136
141
|
|
@@ -292,7 +297,7 @@ like crontab job but via Python API.
|
|
292
297
|
### API Server
|
293
298
|
|
294
299
|
```shell
|
295
|
-
(venv) $ uvicorn
|
300
|
+
(venv) $ uvicorn ddeutil.workflow.api:app \
|
296
301
|
--host 127.0.0.1 \
|
297
302
|
--port 80 \
|
298
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,26 +0,0 @@
|
|
1
|
-
ddeutil/workflow/__about__.py,sha256=lXPz0LJuQJgNzG0V-1UIfdYsebVctya1i8YqUhNgkXU,28
|
2
|
-
ddeutil/workflow/__cron.py,sha256=3i-wmjTlh0ADCzN9pLKaWHzJkXzC72aIBmVEQSbyCCE,26895
|
3
|
-
ddeutil/workflow/__init__.py,sha256=ucsWC4fWdD3ZJu3mDLwe1BCS7wHR0-43jtxm8eZe53o,1779
|
4
|
-
ddeutil/workflow/__types.py,sha256=CK1jfzyHP9P-MB0ElhpJZ59ZFGJC9MkQuAop5739_9k,4304
|
5
|
-
ddeutil/workflow/audit.py,sha256=LZDgZbWioy0ctEWBmTUXJY_cAdFEMxvkvamJbkVAhdc,8066
|
6
|
-
ddeutil/workflow/call.py,sha256=gkEmrYZT1KFVMVy6uyXcl2wBPQXyg1onPLkXN3q9JJk,5469
|
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=cm4u_l3fopL6tgUZYy-apZMGektaFyB5qu9uja3Nups,23776
|
11
|
-
ddeutil/workflow/params.py,sha256=LKR7jXyxTb5NVrFav_fl2y9xo3p7qL1S9h-i6CtvNwE,5851
|
12
|
-
ddeutil/workflow/result.py,sha256=z3C1V9C8D736gqTefBH0uUFr40pNU5Z2TwV2Pndoxmw,7800
|
13
|
-
ddeutil/workflow/scheduler.py,sha256=5xlgzunC-eDOc0uSxJZhphywVOwrtmuF0mT5YYc83BY,24943
|
14
|
-
ddeutil/workflow/stages.py,sha256=5UhmcDgJ214NSNyTwgYcX2hvSW1Rcgk_Qq71n1VMdZ4,26555
|
15
|
-
ddeutil/workflow/templates.py,sha256=A0JgZFGkBv-AX-EskZj656nG5zFd3j1PpLpyXihf6Xg,10967
|
16
|
-
ddeutil/workflow/utils.py,sha256=MctJmvklTYtiqZ-nZ7fazQeDoe77UvU0YUEqQZSlbCs,7225
|
17
|
-
ddeutil/workflow/workflow.py,sha256=7SvF80y4GrrwL-0X46wlct76qPp_fttZpEgxu5xjcBY,45148
|
18
|
-
ddeutil/workflow/api/__init__.py,sha256=F53NMBWtb9IKaDWkPU5KvybGGfKAcbehgn6TLBwHuuM,21
|
19
|
-
ddeutil/workflow/api/api.py,sha256=TfgJtu-yREsrRveLcqTjxoJszuhq21qKkl4oyQpSzvQ,3959
|
20
|
-
ddeutil/workflow/api/repeat.py,sha256=zyvsrXKk-3-_N8ZRZSki0Mueshugum2jtqctEOp9QSc,4927
|
21
|
-
ddeutil/workflow/api/route.py,sha256=fKs5zlG4prwL8HplXYjYsyuxelOKgV-54VBgBufIBcQ,8629
|
22
|
-
ddeutil_workflow-0.0.34.dist-info/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
|
23
|
-
ddeutil_workflow-0.0.34.dist-info/METADATA,sha256=J-Y3CGyv6r39SVYlasXC6-fVNFYhAtmWjM46CDoYz_0,19221
|
24
|
-
ddeutil_workflow-0.0.34.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
25
|
-
ddeutil_workflow-0.0.34.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
|
26
|
-
ddeutil_workflow-0.0.34.dist-info/RECORD,,
|
File without changes
|
File without changes
|