ddeutil-workflow 0.0.14__py3-none-any.whl → 0.0.15__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/__types.py +42 -9
- ddeutil/workflow/conf.py +4 -0
- ddeutil/workflow/job.py +6 -4
- ddeutil/workflow/scheduler.py +33 -18
- ddeutil/workflow/stage.py +11 -2
- ddeutil/workflow/utils.py +24 -12
- {ddeutil_workflow-0.0.14.dist-info → ddeutil_workflow-0.0.15.dist-info}/METADATA +1 -1
- ddeutil_workflow-0.0.15.dist-info/RECORD +22 -0
- ddeutil_workflow-0.0.14.dist-info/RECORD +0 -22
- {ddeutil_workflow-0.0.14.dist-info → ddeutil_workflow-0.0.15.dist-info}/LICENSE +0 -0
- {ddeutil_workflow-0.0.14.dist-info → ddeutil_workflow-0.0.15.dist-info}/WHEEL +0 -0
- {ddeutil_workflow-0.0.14.dist-info → ddeutil_workflow-0.0.15.dist-info}/entry_points.txt +0 -0
- {ddeutil_workflow-0.0.14.dist-info → ddeutil_workflow-0.0.15.dist-info}/top_level.txt +0 -0
ddeutil/workflow/__about__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__: str = "0.0.
|
1
|
+
__version__: str = "0.0.15"
|
ddeutil/workflow/__types.py
CHANGED
@@ -6,14 +6,19 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import re
|
9
|
+
from collections.abc import Iterator
|
10
|
+
from dataclasses import dataclass
|
9
11
|
from re import (
|
10
12
|
IGNORECASE,
|
11
13
|
MULTILINE,
|
12
14
|
UNICODE,
|
13
15
|
VERBOSE,
|
16
|
+
Match,
|
14
17
|
Pattern,
|
15
18
|
)
|
16
|
-
from typing import Any, Union
|
19
|
+
from typing import Any, Optional, Union
|
20
|
+
|
21
|
+
from typing_extensions import Self
|
17
22
|
|
18
23
|
TupleStr = tuple[str, ...]
|
19
24
|
DictData = dict[str, Any]
|
@@ -23,6 +28,27 @@ MatrixInclude = list[dict[str, Union[str, int]]]
|
|
23
28
|
MatrixExclude = list[dict[str, Union[str, int]]]
|
24
29
|
|
25
30
|
|
31
|
+
@dataclass(frozen=True)
|
32
|
+
class CallerRe:
|
33
|
+
"""Caller dataclass that catching result from the matching regex with the
|
34
|
+
Re.RE_CALLER value.
|
35
|
+
"""
|
36
|
+
|
37
|
+
full: str
|
38
|
+
caller: str
|
39
|
+
caller_prefix: Optional[str]
|
40
|
+
caller_last: str
|
41
|
+
post_filters: str
|
42
|
+
|
43
|
+
@classmethod
|
44
|
+
def from_regex(cls, match: Match[str]) -> Self:
|
45
|
+
"""Class construct from matching result.
|
46
|
+
|
47
|
+
:rtype: Self
|
48
|
+
"""
|
49
|
+
return cls(full=match.group(0), **match.groupdict())
|
50
|
+
|
51
|
+
|
26
52
|
class Re:
|
27
53
|
"""Regular expression config for this package."""
|
28
54
|
|
@@ -31,10 +57,10 @@ class Re:
|
|
31
57
|
# - Version 1:
|
32
58
|
# \${{\s*(?P<caller>[a-zA-Z0-9_.\s'\"\[\]\(\)\-\{}]+?)\s*(?P<post_filters>(?:\|\s*(?:[a-zA-Z0-9_]{3,}[a-zA-Z0-9_.,-\\%\s'\"[\]()\{}]+)\s*)*)}}
|
33
59
|
# - Version 2 (2024-09-30):
|
34
|
-
# \${{\s*(?P<caller>(?P<caller_prefix>[a-zA-Z_-]+\.)*(?P<caller_last>[a-zA-Z0-9_\-.'\"(\)[\]{}]+))\s*(?P<post_filters>(?:\|\s*(?:[a-zA-Z0-9_]{3,}[a-zA-Z0-9_.,-\\%\s'\"[\]()\{}]+)\s*)*)}}
|
60
|
+
# \${{\s*(?P<caller>(?P<caller_prefix>(?:[a-zA-Z_-]+\.)*)(?P<caller_last>[a-zA-Z0-9_\-.'\"(\)[\]{}]+))\s*(?P<post_filters>(?:\|\s*(?:[a-zA-Z0-9_]{3,}[a-zA-Z0-9_.,-\\%\s'\"[\]()\{}]+)\s*)*)}}
|
35
61
|
#
|
36
62
|
# Examples:
|
37
|
-
# - ${{ params.
|
63
|
+
# - ${{ params.data_dt }}
|
38
64
|
# - ${{ params.source.table }}
|
39
65
|
#
|
40
66
|
__re_caller: str = r"""
|
@@ -42,16 +68,17 @@ class Re:
|
|
42
68
|
{{
|
43
69
|
\s*
|
44
70
|
(?P<caller>
|
45
|
-
(?P<caller_prefix>[a-zA-Z_-]+\.)*
|
71
|
+
(?P<caller_prefix>(?:[a-zA-Z_-]+\.)*)
|
46
72
|
(?P<caller_last>[a-zA-Z0-9_\-.'\"(\)[\]{}]+)
|
47
73
|
)
|
48
74
|
\s*
|
49
75
|
(?P<post_filters>
|
50
76
|
(?:
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
77
|
+
\|\s*
|
78
|
+
(?:
|
79
|
+
[a-zA-Z0-9_]{3,}
|
80
|
+
[a-zA-Z0-9_.,-\\%\s'\"[\]()\{}]*
|
81
|
+
)\s*
|
55
82
|
)*
|
56
83
|
)
|
57
84
|
}}
|
@@ -62,7 +89,8 @@ class Re:
|
|
62
89
|
|
63
90
|
# NOTE:
|
64
91
|
# Regular expression:
|
65
|
-
#
|
92
|
+
# - Version 1:
|
93
|
+
# ^(?P<path>[^/@]+)/(?P<func>[^@]+)@(?P<tag>.+)$
|
66
94
|
#
|
67
95
|
# Examples:
|
68
96
|
# - tasks/function@dummy
|
@@ -78,3 +106,8 @@ class Re:
|
|
78
106
|
RE_TASK_FMT: Pattern = re.compile(
|
79
107
|
__re_task_fmt, MULTILINE | IGNORECASE | UNICODE | VERBOSE
|
80
108
|
)
|
109
|
+
|
110
|
+
@classmethod
|
111
|
+
def finditer_caller(cls, value) -> Iterator[CallerRe]:
|
112
|
+
for found in cls.RE_CALLER.finditer(value):
|
113
|
+
yield CallerRe.from_regex(found)
|
ddeutil/workflow/conf.py
CHANGED
@@ -16,6 +16,10 @@ env = os.getenv
|
|
16
16
|
|
17
17
|
|
18
18
|
class Config:
|
19
|
+
"""Config object for keeping application configuration on current session
|
20
|
+
without changing when if the application still running.
|
21
|
+
"""
|
22
|
+
|
19
23
|
# NOTE: Core
|
20
24
|
tz: ZoneInfo = ZoneInfo(env("WORKFLOW_CORE_TIMEZONE", "UTC"))
|
21
25
|
|
ddeutil/workflow/job.py
CHANGED
@@ -320,13 +320,15 @@ class Job(BaseModel):
|
|
320
320
|
and want to set on the `to` like;
|
321
321
|
|
322
322
|
... (i) output: {'strategy01': bar, 'strategy02': bar}
|
323
|
-
... (ii) to: {}
|
323
|
+
... (ii) to: {'jobs'}
|
324
324
|
|
325
325
|
The result of the `to` variable will be;
|
326
326
|
|
327
327
|
... (iii) to: {
|
328
|
-
'
|
329
|
-
'
|
328
|
+
'jobs': {
|
329
|
+
'strategies': {
|
330
|
+
'strategy01': bar, 'strategy02': bar
|
331
|
+
}
|
330
332
|
}
|
331
333
|
}
|
332
334
|
|
@@ -339,7 +341,7 @@ class Job(BaseModel):
|
|
339
341
|
"This job do not set the ID before setting output."
|
340
342
|
)
|
341
343
|
|
342
|
-
to[self.id] = (
|
344
|
+
to["jobs"][self.id] = (
|
343
345
|
{"strategies": output}
|
344
346
|
if self.strategy.is_set()
|
345
347
|
# NOTE:
|
ddeutil/workflow/scheduler.py
CHANGED
@@ -513,7 +513,6 @@ class Workflow(BaseModel):
|
|
513
513
|
f"workflow."
|
514
514
|
)
|
515
515
|
|
516
|
-
context: DictData = {}
|
517
516
|
logger.info(f"({self.run_id}) [WORKFLOW]: Start execute: {job_id!r}")
|
518
517
|
|
519
518
|
# IMPORTANT:
|
@@ -523,7 +522,7 @@ class Workflow(BaseModel):
|
|
523
522
|
job: Job = self.jobs[job_id].get_running_id(self.run_id)
|
524
523
|
job.set_outputs(
|
525
524
|
job.execute(params=params).context,
|
526
|
-
to=
|
525
|
+
to=params,
|
527
526
|
)
|
528
527
|
except JobException as err:
|
529
528
|
logger.error(
|
@@ -536,7 +535,7 @@ class Workflow(BaseModel):
|
|
536
535
|
else:
|
537
536
|
raise NotImplementedError() from None
|
538
537
|
|
539
|
-
return Result(status=0, context=
|
538
|
+
return Result(status=0, context=params)
|
540
539
|
|
541
540
|
def execute(
|
542
541
|
self,
|
@@ -587,8 +586,14 @@ class Workflow(BaseModel):
|
|
587
586
|
for job_id in self.jobs:
|
588
587
|
jq.put(job_id)
|
589
588
|
|
590
|
-
# NOTE: Create
|
591
|
-
#
|
589
|
+
# NOTE: Create data context that will pass to any job executions
|
590
|
+
# on this workflow.
|
591
|
+
#
|
592
|
+
# {
|
593
|
+
# 'params': <input-params>,
|
594
|
+
# 'jobs': {},
|
595
|
+
# }
|
596
|
+
#
|
592
597
|
context: DictData = self.parameterize(params)
|
593
598
|
status: int = 0
|
594
599
|
try:
|
@@ -657,15 +662,23 @@ class Workflow(BaseModel):
|
|
657
662
|
job: Job = self.jobs[job_id]
|
658
663
|
|
659
664
|
if any(need not in context["jobs"] for need in job.needs):
|
665
|
+
job_queue.task_done()
|
660
666
|
job_queue.put(job_id)
|
661
667
|
time.sleep(0.25)
|
662
668
|
continue
|
663
669
|
|
670
|
+
# NOTE: Start workflow job execution with deep copy context data
|
671
|
+
# before release.
|
672
|
+
#
|
673
|
+
# {
|
674
|
+
# 'params': <input-params>,
|
675
|
+
# 'jobs': {},
|
676
|
+
# }
|
664
677
|
futures.append(
|
665
678
|
executor.submit(
|
666
679
|
self.execute_job,
|
667
680
|
job_id,
|
668
|
-
params=
|
681
|
+
params=context,
|
669
682
|
),
|
670
683
|
)
|
671
684
|
|
@@ -677,14 +690,13 @@ class Workflow(BaseModel):
|
|
677
690
|
|
678
691
|
for future in as_completed(futures, timeout=1800):
|
679
692
|
if err := future.exception():
|
680
|
-
logger.error(f"{err}")
|
693
|
+
logger.error(f"({self.run_id}) [CORE]: {err}")
|
681
694
|
raise WorkflowException(f"{err}")
|
682
695
|
try:
|
683
|
-
|
684
|
-
context["jobs"].update(future.result(timeout=60).context)
|
696
|
+
future.result(timeout=60)
|
685
697
|
except TimeoutError as err:
|
686
698
|
raise WorkflowException(
|
687
|
-
"
|
699
|
+
"Timeout when getting result from future"
|
688
700
|
) from err
|
689
701
|
|
690
702
|
if not_time_out_flag:
|
@@ -731,18 +743,21 @@ class Workflow(BaseModel):
|
|
731
743
|
job_id: str = job_queue.get()
|
732
744
|
job: Job = self.jobs[job_id]
|
733
745
|
|
734
|
-
# NOTE:
|
746
|
+
# NOTE: Waiting dependency job run successful before release.
|
735
747
|
if any(need not in context["jobs"] for need in job.needs):
|
748
|
+
job_queue.task_done()
|
736
749
|
job_queue.put(job_id)
|
737
|
-
time.sleep(0.
|
750
|
+
time.sleep(0.05)
|
738
751
|
continue
|
739
752
|
|
740
|
-
# NOTE: Start workflow job execution
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
753
|
+
# NOTE: Start workflow job execution with deep copy context data
|
754
|
+
# before release.
|
755
|
+
#
|
756
|
+
# {
|
757
|
+
# 'params': <input-params>,
|
758
|
+
# 'jobs': {},
|
759
|
+
# }
|
760
|
+
self.execute_job(job_id=job_id, params=context)
|
746
761
|
|
747
762
|
# NOTE: Mark this job queue done.
|
748
763
|
job_queue.task_done()
|
ddeutil/workflow/stage.py
CHANGED
@@ -24,6 +24,7 @@ import contextlib
|
|
24
24
|
import inspect
|
25
25
|
import subprocess
|
26
26
|
import sys
|
27
|
+
import time
|
27
28
|
import uuid
|
28
29
|
from abc import ABC, abstractmethod
|
29
30
|
from collections.abc import Iterator
|
@@ -60,6 +61,8 @@ from .utils import (
|
|
60
61
|
)
|
61
62
|
|
62
63
|
P = ParamSpec("P")
|
64
|
+
ReturnResult = Callable[P, Result]
|
65
|
+
DecoratorResult = Callable[[ReturnResult], ReturnResult]
|
63
66
|
logger = get_logger("ddeutil.workflow")
|
64
67
|
|
65
68
|
|
@@ -77,7 +80,7 @@ __all__: TupleStr = (
|
|
77
80
|
)
|
78
81
|
|
79
82
|
|
80
|
-
def handler_result(message: str | None = None) ->
|
83
|
+
def handler_result(message: str | None = None) -> DecoratorResult:
|
81
84
|
"""Decorator function for handler result from the stage execution. This
|
82
85
|
function should to use with execution method only.
|
83
86
|
|
@@ -103,7 +106,7 @@ def handler_result(message: str | None = None) -> Callable[P, Result]:
|
|
103
106
|
#
|
104
107
|
message: str = message or ""
|
105
108
|
|
106
|
-
def decorator(func:
|
109
|
+
def decorator(func: ReturnResult) -> ReturnResult:
|
107
110
|
|
108
111
|
@wraps(func)
|
109
112
|
def wrapped(self: Stage, *args, **kwargs):
|
@@ -293,6 +296,10 @@ class EmptyStage(BaseStage):
|
|
293
296
|
default=None,
|
294
297
|
description="A string statement that want to logging",
|
295
298
|
)
|
299
|
+
sleep: float = Field(
|
300
|
+
default=0,
|
301
|
+
description="A second value to sleep before finish execution",
|
302
|
+
)
|
296
303
|
|
297
304
|
def execute(self, params: DictData) -> Result:
|
298
305
|
"""Execution method for the Empty stage that do only logging out to
|
@@ -310,6 +317,8 @@ class EmptyStage(BaseStage):
|
|
310
317
|
f"({self.run_id}) [STAGE]: Empty-Execute: {self.name!r}: "
|
311
318
|
f"( {param2template(self.echo, params=params) or '...'} )"
|
312
319
|
)
|
320
|
+
if self.sleep > 0:
|
321
|
+
time.sleep(self.sleep)
|
313
322
|
return Result(status=0, context={})
|
314
323
|
|
315
324
|
|
ddeutil/workflow/utils.py
CHANGED
@@ -206,6 +206,12 @@ class SimLoad:
|
|
206
206
|
"""Find all data that match with object type in config path. This class
|
207
207
|
method can use include and exclude list of identity name for filter and
|
208
208
|
adds-on.
|
209
|
+
|
210
|
+
:param obj:
|
211
|
+
:param params:
|
212
|
+
:param include:
|
213
|
+
:param exclude:
|
214
|
+
:rtype: Iterator[tuple[str, DictData]]
|
209
215
|
"""
|
210
216
|
exclude: list[str] = exclude or []
|
211
217
|
for file in PathSearch(params.engine.paths.conf).files:
|
@@ -317,10 +323,14 @@ class TagFunc(Protocol):
|
|
317
323
|
name: str
|
318
324
|
tag: str
|
319
325
|
|
320
|
-
def __call__(self, *args, **kwargs): ...
|
326
|
+
def __call__(self, *args, **kwargs): ... # pragma: no cove
|
327
|
+
|
328
|
+
|
329
|
+
ReturnTagFunc = Callable[P, TagFunc]
|
330
|
+
DecoratorTagFunc = Callable[[Callable[[...], Any]], ReturnTagFunc]
|
321
331
|
|
322
332
|
|
323
|
-
def tag(name: str, alias: str | None = None) ->
|
333
|
+
def tag(name: str, alias: str | None = None) -> DecoratorTagFunc:
|
324
334
|
"""Tag decorator function that set function attributes, ``tag`` and ``name``
|
325
335
|
for making registries variable.
|
326
336
|
|
@@ -330,7 +340,7 @@ def tag(name: str, alias: str | None = None) -> Callable[P, TagFunc]:
|
|
330
340
|
:rtype: Callable[P, TagFunc]
|
331
341
|
"""
|
332
342
|
|
333
|
-
def func_internal(func: Callable[[...], Any]) ->
|
343
|
+
def func_internal(func: Callable[[...], Any]) -> ReturnTagFunc:
|
334
344
|
func.tag = name
|
335
345
|
func.name = alias or func.__name__.replace("_", "-")
|
336
346
|
|
@@ -398,6 +408,10 @@ class BaseParam(BaseModel, ABC):
|
|
398
408
|
|
399
409
|
@field_serializer("type")
|
400
410
|
def __serializer_type(self, value: str) -> str:
|
411
|
+
"""Serialize the value of the type field.
|
412
|
+
|
413
|
+
:rtype: str
|
414
|
+
"""
|
401
415
|
return value
|
402
416
|
|
403
417
|
|
@@ -793,8 +807,8 @@ def not_in_template(value: Any, *, not_in: str = "matrix.") -> bool:
|
|
793
807
|
elif not isinstance(value, str):
|
794
808
|
return False
|
795
809
|
return any(
|
796
|
-
(not found.
|
797
|
-
for found in Re.
|
810
|
+
(not found.caller.strip().startswith(not_in))
|
811
|
+
for found in Re.finditer_caller(value.strip())
|
798
812
|
)
|
799
813
|
|
800
814
|
|
@@ -835,18 +849,16 @@ def str2template(
|
|
835
849
|
|
836
850
|
# NOTE: remove space before and after this string value.
|
837
851
|
value: str = value.strip()
|
838
|
-
for found in Re.
|
852
|
+
for found in Re.finditer_caller(value):
|
839
853
|
# NOTE:
|
840
854
|
# Get caller and filter values that setting inside;
|
841
855
|
#
|
842
856
|
# ... ``${{ <caller-value> [ | <filter-value>] ... }}``
|
843
857
|
#
|
844
|
-
caller: str = found.
|
858
|
+
caller: str = found.caller
|
845
859
|
pfilter: list[str] = [
|
846
860
|
i.strip()
|
847
|
-
for i in (
|
848
|
-
found.group("post_filters").strip().removeprefix("|").split("|")
|
849
|
-
)
|
861
|
+
for i in (found.post_filters.strip().removeprefix("|").split("|"))
|
850
862
|
if i != ""
|
851
863
|
]
|
852
864
|
if not hasdot(caller, params):
|
@@ -859,7 +871,7 @@ def str2template(
|
|
859
871
|
# If type of getter caller is not string type and it does not use to
|
860
872
|
# concat other string value, it will return origin value from the
|
861
873
|
# ``getdot`` function.
|
862
|
-
if value.replace(found.
|
874
|
+
if value.replace(found.full, "", 1) == "":
|
863
875
|
return map_post_filter(getter, pfilter, filters=filters)
|
864
876
|
|
865
877
|
# NOTE: map post-filter function.
|
@@ -867,7 +879,7 @@ def str2template(
|
|
867
879
|
if not isinstance(getter, str):
|
868
880
|
getter: str = str(getter)
|
869
881
|
|
870
|
-
value: str = value.replace(found.
|
882
|
+
value: str = value.replace(found.full, getter, 1)
|
871
883
|
|
872
884
|
return search_env_replace(value)
|
873
885
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
ddeutil/workflow/__about__.py,sha256=w_vBOopUg1crMbDyfdE0LgsxsncnhGYp0D39LSSnSVI,28
|
2
|
+
ddeutil/workflow/__init__.py,sha256=-DIy8SGFsD7_wqp-V-K8v8jTxacmqrcyj_SFx1WS6qg,687
|
3
|
+
ddeutil/workflow/__types.py,sha256=WWugALcayRiP0IQO-eBWK767_XxK7KGlY7SuVgyaJnk,3196
|
4
|
+
ddeutil/workflow/api.py,sha256=cwju_qhY6m0kLtaoa77QLglC9tl7RjjZ4UnJYV3SlQQ,4810
|
5
|
+
ddeutil/workflow/cli.py,sha256=Ikcq526WeIl-737-v55T0PwAZ2pNiZFxlN0Y-DjhDbQ,3374
|
6
|
+
ddeutil/workflow/conf.py,sha256=D0g7rHXilpGwOD36QwVd9I5kEwqsAUA0Z3tAINS2Pws,1287
|
7
|
+
ddeutil/workflow/cron.py,sha256=naWefHc3EnVo41Yf1zQeXOzF27YlTlnfj0XnQ6_HO-U,25514
|
8
|
+
ddeutil/workflow/exceptions.py,sha256=Uf1-Tn8rAzj0aiVHSqo4fBqO80W0za7UFZgKv24E-tg,706
|
9
|
+
ddeutil/workflow/job.py,sha256=9H_2C0ikD5y6jLVdIBj8de4CdSpS632XOfqYVhM4bHI,21582
|
10
|
+
ddeutil/workflow/log.py,sha256=Ev-Szi0KC_MmbFY4g4BWv6tUSmcLKWKZ03ZInmYPmgU,6490
|
11
|
+
ddeutil/workflow/on.py,sha256=vsZG19mNoztDSB_ObD_4ZWPKgHYpBDJMWw97ZiTavNE,7237
|
12
|
+
ddeutil/workflow/repeat.py,sha256=e3dekPTlMlxCCizfBYsZ8dD8Juy4rtfqDZJU3Iky2oA,5011
|
13
|
+
ddeutil/workflow/route.py,sha256=ABEk-WlVo9XGFc7zCPbckX33URCNH7woQFU1keX_8PQ,6970
|
14
|
+
ddeutil/workflow/scheduler.py,sha256=12Dd5CVphOVKjUwoiB8dCHt4WpYRPG3dSOt-pR6NNxc,46167
|
15
|
+
ddeutil/workflow/stage.py,sha256=Avz1Mbb8WAP6kFn0bnN0p14-EnQ_AzdKr435JRxjkao,23844
|
16
|
+
ddeutil/workflow/utils.py,sha256=XUD5hoygAyxi4xo1spTacoDNGKN2TlRob_o8qfCj4Pc,30993
|
17
|
+
ddeutil_workflow-0.0.15.dist-info/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
|
18
|
+
ddeutil_workflow-0.0.15.dist-info/METADATA,sha256=6JvY9y-cT3WnirRva45NS582Iz7ZuXJZpsiCtN57OoA,11653
|
19
|
+
ddeutil_workflow-0.0.15.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
20
|
+
ddeutil_workflow-0.0.15.dist-info/entry_points.txt,sha256=0BVOgO3LdUdXVZ-CiHHDKxzEk2c8J30jEwHeKn2YCWI,62
|
21
|
+
ddeutil_workflow-0.0.15.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
|
22
|
+
ddeutil_workflow-0.0.15.dist-info/RECORD,,
|
@@ -1,22 +0,0 @@
|
|
1
|
-
ddeutil/workflow/__about__.py,sha256=Xas_M3BaGwGfZOJTvMWUlmlW09aGC-Apst-NtkPddY4,28
|
2
|
-
ddeutil/workflow/__init__.py,sha256=-DIy8SGFsD7_wqp-V-K8v8jTxacmqrcyj_SFx1WS6qg,687
|
3
|
-
ddeutil/workflow/__types.py,sha256=aBbytylSPIe_cip2KIyqLN2eUloMOJdkayqKWCBrwhk,2353
|
4
|
-
ddeutil/workflow/api.py,sha256=cwju_qhY6m0kLtaoa77QLglC9tl7RjjZ4UnJYV3SlQQ,4810
|
5
|
-
ddeutil/workflow/cli.py,sha256=Ikcq526WeIl-737-v55T0PwAZ2pNiZFxlN0Y-DjhDbQ,3374
|
6
|
-
ddeutil/workflow/conf.py,sha256=j19G7rDxQRGgSRQW3pxIYtK5lB3fZv0eG_CAoqoIhPw,1140
|
7
|
-
ddeutil/workflow/cron.py,sha256=naWefHc3EnVo41Yf1zQeXOzF27YlTlnfj0XnQ6_HO-U,25514
|
8
|
-
ddeutil/workflow/exceptions.py,sha256=Uf1-Tn8rAzj0aiVHSqo4fBqO80W0za7UFZgKv24E-tg,706
|
9
|
-
ddeutil/workflow/job.py,sha256=zEefiEAxyC34NvbNVpKexTVU1E_031446308zGMdcmE,21488
|
10
|
-
ddeutil/workflow/log.py,sha256=Ev-Szi0KC_MmbFY4g4BWv6tUSmcLKWKZ03ZInmYPmgU,6490
|
11
|
-
ddeutil/workflow/on.py,sha256=vsZG19mNoztDSB_ObD_4ZWPKgHYpBDJMWw97ZiTavNE,7237
|
12
|
-
ddeutil/workflow/repeat.py,sha256=e3dekPTlMlxCCizfBYsZ8dD8Juy4rtfqDZJU3Iky2oA,5011
|
13
|
-
ddeutil/workflow/route.py,sha256=ABEk-WlVo9XGFc7zCPbckX33URCNH7woQFU1keX_8PQ,6970
|
14
|
-
ddeutil/workflow/scheduler.py,sha256=CcUFichnvPbQzSEk_ikNgFwZimTObGHfXxHChuysAo4,45706
|
15
|
-
ddeutil/workflow/stage.py,sha256=Tt5QQrO_dN8MO9gPtiziOqVrd64UTJZwbgifWeXBCIA,23574
|
16
|
-
ddeutil/workflow/utils.py,sha256=epJMTsA4BPQa0gECgcWJ38IENlejpnF3OTBNc0eaqYE,30715
|
17
|
-
ddeutil_workflow-0.0.14.dist-info/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
|
18
|
-
ddeutil_workflow-0.0.14.dist-info/METADATA,sha256=sf9kiPoGazaRxqymTjaxZyH47yNyGj0RElc-NLmUa4w,11653
|
19
|
-
ddeutil_workflow-0.0.14.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
20
|
-
ddeutil_workflow-0.0.14.dist-info/entry_points.txt,sha256=0BVOgO3LdUdXVZ-CiHHDKxzEk2c8J30jEwHeKn2YCWI,62
|
21
|
-
ddeutil_workflow-0.0.14.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
|
22
|
-
ddeutil_workflow-0.0.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|