ddeutil-workflow 0.0.12__py3-none-any.whl → 0.0.14__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 +4 -1
- ddeutil/workflow/__types.py +24 -8
- ddeutil/workflow/api.py +2 -2
- ddeutil/workflow/conf.py +41 -0
- ddeutil/workflow/cron.py +19 -12
- ddeutil/workflow/job.py +251 -184
- ddeutil/workflow/log.py +28 -14
- ddeutil/workflow/on.py +5 -2
- ddeutil/workflow/scheduler.py +262 -140
- ddeutil/workflow/stage.py +105 -39
- ddeutil/workflow/utils.py +106 -40
- {ddeutil_workflow-0.0.12.dist-info → ddeutil_workflow-0.0.14.dist-info}/METADATA +80 -32
- ddeutil_workflow-0.0.14.dist-info/RECORD +22 -0
- {ddeutil_workflow-0.0.12.dist-info → ddeutil_workflow-0.0.14.dist-info}/WHEEL +1 -1
- ddeutil_workflow-0.0.12.dist-info/RECORD +0 -21
- {ddeutil_workflow-0.0.12.dist-info → ddeutil_workflow-0.0.14.dist-info}/LICENSE +0 -0
- {ddeutil_workflow-0.0.12.dist-info → ddeutil_workflow-0.0.14.dist-info}/entry_points.txt +0 -0
- {ddeutil_workflow-0.0.12.dist-info → ddeutil_workflow-0.0.14.dist-info}/top_level.txt +0 -0
ddeutil/workflow/__about__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__: str = "0.0.
|
1
|
+
__version__: str = "0.0.14"
|
ddeutil/workflow/__init__.py
CHANGED
@@ -12,7 +12,10 @@ from .exceptions import (
|
|
12
12
|
)
|
13
13
|
from .job import Job, Strategy
|
14
14
|
from .on import On, interval2crontab
|
15
|
-
from .scheduler import
|
15
|
+
from .scheduler import (
|
16
|
+
Schedule,
|
17
|
+
Workflow,
|
18
|
+
)
|
16
19
|
from .stage import Stage, handler_result
|
17
20
|
from .utils import (
|
18
21
|
Param,
|
ddeutil/workflow/__types.py
CHANGED
@@ -24,20 +24,32 @@ MatrixExclude = list[dict[str, Union[str, int]]]
|
|
24
24
|
|
25
25
|
|
26
26
|
class Re:
|
27
|
-
"""Regular expression config."""
|
27
|
+
"""Regular expression config for this package."""
|
28
28
|
|
29
|
-
# NOTE:
|
30
|
-
#
|
29
|
+
# NOTE:
|
30
|
+
# Regular expression:
|
31
|
+
# - Version 1:
|
32
|
+
# \${{\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
|
+
# - 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*)*)}}
|
35
|
+
#
|
36
|
+
# Examples:
|
37
|
+
# - ${{ params.asat_dt }}
|
38
|
+
# - ${{ params.source.table }}
|
39
|
+
#
|
31
40
|
__re_caller: str = r"""
|
32
41
|
\$
|
33
42
|
{{
|
34
43
|
\s*
|
35
44
|
(?P<caller>
|
36
|
-
[a-zA-
|
37
|
-
|
45
|
+
(?P<caller_prefix>[a-zA-Z_-]+\.)*
|
46
|
+
(?P<caller_last>[a-zA-Z0-9_\-.'\"(\)[\]{}]+)
|
47
|
+
)
|
48
|
+
\s*
|
38
49
|
(?P<post_filters>
|
39
50
|
(?:
|
40
|
-
|
51
|
+
\|
|
52
|
+
\s*
|
41
53
|
(?:[a-zA-Z0-9_]{3,}[a-zA-Z0-9_.,-\\%\s'\"[\]()\{}]*)
|
42
54
|
\s*
|
43
55
|
)*
|
@@ -48,8 +60,12 @@ class Re:
|
|
48
60
|
__re_caller, MULTILINE | IGNORECASE | UNICODE | VERBOSE
|
49
61
|
)
|
50
62
|
|
51
|
-
# NOTE:
|
52
|
-
#
|
63
|
+
# NOTE:
|
64
|
+
# Regular expression:
|
65
|
+
# ^(?P<path>[^/@]+)/(?P<func>[^@]+)@(?P<tag>.+)$
|
66
|
+
#
|
67
|
+
# Examples:
|
68
|
+
# - tasks/function@dummy
|
53
69
|
__re_task_fmt: str = r"""
|
54
70
|
^
|
55
71
|
(?P<path>[^/@]+)
|
ddeutil/workflow/api.py
CHANGED
@@ -25,7 +25,7 @@ from pydantic import BaseModel
|
|
25
25
|
from .__about__ import __version__
|
26
26
|
from .log import get_logger
|
27
27
|
from .repeat import repeat_at, repeat_every
|
28
|
-
from .scheduler import
|
28
|
+
from .scheduler import WorkflowTaskData
|
29
29
|
|
30
30
|
load_dotenv()
|
31
31
|
logger = get_logger("ddeutil.workflow")
|
@@ -36,7 +36,7 @@ class State(TypedDict):
|
|
36
36
|
upper_result: dict[str, str]
|
37
37
|
scheduler: list[str]
|
38
38
|
workflow_threads: dict[str, Thread]
|
39
|
-
workflow_tasks: list[
|
39
|
+
workflow_tasks: list[WorkflowTaskData]
|
40
40
|
workflow_queue: dict[str, list[datetime]]
|
41
41
|
workflow_running: dict[str, list[datetime]]
|
42
42
|
|
ddeutil/workflow/conf.py
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# ------------------------------------------------------------------------------
|
2
|
+
# Copyright (c) 2022 Korawich Anuttra. All rights reserved.
|
3
|
+
# Licensed under the MIT License. See LICENSE in the project root for
|
4
|
+
# license information.
|
5
|
+
# ------------------------------------------------------------------------------
|
6
|
+
from __future__ import annotations
|
7
|
+
|
8
|
+
import os
|
9
|
+
from zoneinfo import ZoneInfo
|
10
|
+
|
11
|
+
from ddeutil.core import str2bool
|
12
|
+
from dotenv import load_dotenv
|
13
|
+
|
14
|
+
load_dotenv()
|
15
|
+
env = os.getenv
|
16
|
+
|
17
|
+
|
18
|
+
class Config:
|
19
|
+
# NOTE: Core
|
20
|
+
tz: ZoneInfo = ZoneInfo(env("WORKFLOW_CORE_TIMEZONE", "UTC"))
|
21
|
+
|
22
|
+
# NOTE: Stage
|
23
|
+
stage_raise_error: bool = str2bool(
|
24
|
+
env("WORKFLOW_CORE_STAGE_RAISE_ERROR", "true")
|
25
|
+
)
|
26
|
+
stage_default_id: bool = str2bool(
|
27
|
+
env("WORKFLOW_CORE_STAGE_DEFAULT_ID", "false")
|
28
|
+
)
|
29
|
+
|
30
|
+
# NOTE: Workflow
|
31
|
+
max_job_parallel: int = int(env("WORKFLOW_CORE_MAX_JOB_PARALLEL", "2"))
|
32
|
+
|
33
|
+
def __init__(self):
|
34
|
+
if self.max_job_parallel < 0:
|
35
|
+
raise ValueError(
|
36
|
+
f"MAX_JOB_PARALLEL should more than 0 but got "
|
37
|
+
f"{self.max_job_parallel}."
|
38
|
+
)
|
39
|
+
|
40
|
+
|
41
|
+
config = Config()
|
ddeutil/workflow/cron.py
CHANGED
@@ -14,7 +14,7 @@ from typing import ClassVar, Optional, Union
|
|
14
14
|
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
15
15
|
|
16
16
|
from ddeutil.core import (
|
17
|
-
|
17
|
+
checker,
|
18
18
|
isinstance_check,
|
19
19
|
must_split,
|
20
20
|
)
|
@@ -38,16 +38,21 @@ class CronYearLimit(Exception): ...
|
|
38
38
|
|
39
39
|
|
40
40
|
def str2cron(value: str) -> str:
|
41
|
-
"""Convert Special String to Crontab.
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
41
|
+
"""Convert Special String with the @ prefix to Crontab value.
|
42
|
+
|
43
|
+
:param value: A string value that want to convert to cron value.
|
44
|
+
:rtype: str
|
45
|
+
|
46
|
+
Table:
|
47
|
+
|
48
|
+
@reboot Run once, at system startup
|
49
|
+
@yearly Run once every year, "0 0 1 1 *"
|
50
|
+
@annually (same as @yearly)
|
51
|
+
@monthly Run once every month, "0 0 1 * *"
|
52
|
+
@weekly Run once every week, "0 0 * * 0"
|
53
|
+
@daily Run once each day, "0 0 * * *"
|
54
|
+
@midnight (same as @daily)
|
55
|
+
@hourly Run once an hour, "0 * * * *"
|
51
56
|
"""
|
52
57
|
mapping_spacial_str = {
|
53
58
|
"@reboot": "",
|
@@ -321,7 +326,9 @@ class CronPart:
|
|
321
326
|
self._parse_range(value_range)
|
322
327
|
)
|
323
328
|
|
324
|
-
if (
|
329
|
+
if (
|
330
|
+
value_step and not checker.is_int(value_step)
|
331
|
+
) or value_step == "":
|
325
332
|
raise ValueError(
|
326
333
|
f"Invalid interval step value {value_step!r} for "
|
327
334
|
f"{self.unit.name!r}"
|