ddeutil-workflow 0.0.14__tar.gz → 0.0.16__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.
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/PKG-INFO +39 -23
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/README.md +36 -20
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/pyproject.toml +7 -6
- ddeutil_workflow-0.0.16/src/ddeutil/workflow/__about__.py +1 -0
- ddeutil_workflow-0.0.16/src/ddeutil/workflow/__types.py +125 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/api.py +3 -4
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/cli.py +2 -5
- ddeutil_workflow-0.0.16/src/ddeutil/workflow/conf.py +318 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/job.py +44 -25
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/log.py +5 -8
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/on.py +1 -1
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/repeat.py +2 -5
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/route.py +4 -11
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/scheduler.py +97 -64
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/stage.py +44 -30
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/utils.py +91 -266
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/PKG-INFO +39 -23
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/SOURCES.txt +8 -10
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/requires.txt +2 -2
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test__conf_exist.py +1 -1
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test__regex.py +11 -2
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_poke.py +1 -1
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_scheduler.py +12 -7
- ddeutil_workflow-0.0.16/tests/test_stage.py +62 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_stage_bash.py +6 -12
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_stage_py.py +16 -31
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_stage_trigger.py +1 -3
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_utils.py +8 -2
- ddeutil_workflow-0.0.16/tests/test_utils_params.py +59 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_utils_result.py +5 -18
- ddeutil_workflow-0.0.16/tests/test_utils_tag.py +42 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_workflow.py +29 -2
- ddeutil_workflow-0.0.16/tests/test_workflow_depends.py +74 -0
- ddeutil_workflow-0.0.14/tests/test_pipeline_matrix.py → ddeutil_workflow-0.0.16/tests/test_workflow_matrix.py +4 -4
- ddeutil_workflow-0.0.14/tests/test_pipeline_on.py → ddeutil_workflow-0.0.16/tests/test_workflow_on.py +1 -1
- ddeutil_workflow-0.0.14/tests/test_pipeline_params.py → ddeutil_workflow-0.0.16/tests/test_workflow_params.py +1 -1
- ddeutil_workflow-0.0.14/tests/test_pipeline_run.py → ddeutil_workflow-0.0.16/tests/test_workflow_run.py +15 -4
- ddeutil_workflow-0.0.14/tests/test_pipeline_task.py → ddeutil_workflow-0.0.16/tests/test_workflow_task.py +3 -3
- ddeutil_workflow-0.0.14/src/ddeutil/workflow/__about__.py +0 -1
- ddeutil_workflow-0.0.14/src/ddeutil/workflow/__types.py +0 -80
- ddeutil_workflow-0.0.14/src/ddeutil/workflow/conf.py +0 -41
- ddeutil_workflow-0.0.14/tests/test_conf.py +0 -8
- ddeutil_workflow-0.0.14/tests/test_pipeline_if.py +0 -28
- ddeutil_workflow-0.0.14/tests/test_pipeline_run_raise.py +0 -12
- ddeutil_workflow-0.0.14/tests/test_stage.py +0 -44
- ddeutil_workflow-0.0.14/tests/test_stage_condition.py +0 -14
- ddeutil_workflow-0.0.14/tests/test_workflow_desc.py +0 -11
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/LICENSE +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/setup.cfg +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/__init__.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/cron.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/exceptions.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/dependency_links.txt +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/entry_points.txt +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/top_level.txt +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_cron.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_job.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_job_py.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_job_strategy.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_log.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_on.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_params.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_stage_hook.py +0 -0
- {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_utils_template.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ddeutil-workflow
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.16
|
4
4
|
Summary: Lightweight workflow orchestration with less dependencies
|
5
5
|
Author-email: ddeutils <korawich.anu@gmail.com>
|
6
6
|
License: MIT
|
@@ -22,8 +22,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
22
22
|
Requires-Python: >=3.9.13
|
23
23
|
Description-Content-Type: text/markdown
|
24
24
|
License-File: LICENSE
|
25
|
-
Requires-Dist: ddeutil>=0.4.
|
26
|
-
Requires-Dist: ddeutil-io>=0.
|
25
|
+
Requires-Dist: ddeutil>=0.4.3
|
26
|
+
Requires-Dist: ddeutil-io[yaml]>=0.2.3
|
27
27
|
Requires-Dist: python-dotenv==1.0.1
|
28
28
|
Requires-Dist: typer<1.0.0,==0.12.5
|
29
29
|
Requires-Dist: schedule<2.0.0,==1.2.2
|
@@ -179,29 +179,31 @@ The main configuration that use to dynamic changing with your propose of this
|
|
179
179
|
application. If any configuration values do not set yet, it will use default value
|
180
180
|
and do not raise any error to you.
|
181
181
|
|
182
|
-
| Environment
|
183
|
-
|
184
|
-
| `WORKFLOW_ROOT_PATH`
|
185
|
-
| `WORKFLOW_CORE_REGISTRY`
|
186
|
-
| `WORKFLOW_CORE_REGISTRY_FILTER`
|
187
|
-
| `WORKFLOW_CORE_PATH_CONF`
|
188
|
-
| `WORKFLOW_CORE_TIMEZONE`
|
189
|
-
| `WORKFLOW_CORE_STAGE_DEFAULT_ID`
|
190
|
-
| `WORKFLOW_CORE_STAGE_RAISE_ERROR`
|
191
|
-
| `
|
192
|
-
| `
|
193
|
-
| `
|
194
|
-
| `
|
195
|
-
| `
|
196
|
-
| `
|
197
|
-
| `
|
182
|
+
| Environment | Component | Default | Description | Remark |
|
183
|
+
|:----------------------------------------|-----------|----------------------------------|--------------------------------------------------------------------------------------------------------------------|--------|
|
184
|
+
| `WORKFLOW_ROOT_PATH` | Core | . | The root path of the workflow application | |
|
185
|
+
| `WORKFLOW_CORE_REGISTRY` | Core | src.ddeutil.workflow,tests.utils | List of importable string for the hook stage | |
|
186
|
+
| `WORKFLOW_CORE_REGISTRY_FILTER` | Core | ddeutil.workflow.utils | List of importable string for the filter template | |
|
187
|
+
| `WORKFLOW_CORE_PATH_CONF` | Core | conf | The config path that keep all template `.yaml` files | |
|
188
|
+
| `WORKFLOW_CORE_TIMEZONE` | Core | Asia/Bangkok | A Timezone string value that will pass to `ZoneInfo` object | |
|
189
|
+
| `WORKFLOW_CORE_STAGE_DEFAULT_ID` | Core | true | A flag that enable default stage ID that use for catch an execution output | |
|
190
|
+
| `WORKFLOW_CORE_STAGE_RAISE_ERROR` | Core | false | A flag that all stage raise StageException from stage execution | |
|
191
|
+
| `WORKFLOW_CORE_JOB_DEFAULT_ID` | Core | false | A flag that enable default job ID that use for catch an execution output. The ID that use will be sequence number. | |
|
192
|
+
| `WORKFLOW_CORE_MAX_NUM_POKING` | Core | 4 | | |
|
193
|
+
| `WORKFLOW_CORE_MAX_JOB_PARALLEL` | Core | 2 | The maximum job number that able to run parallel in workflow executor | |
|
194
|
+
| `WORKFLOW_CORE_WORKFLOW_ID_SIMPLE_MODE` | Core | true | | |
|
195
|
+
| `WORKFLOW_LOG_DEBUG_MODE` | Log | true | A flag that enable logging with debug level mode | |
|
196
|
+
| `WORKFLOW_LOG_ENABLE_WRITE` | Log | true | A flag that enable logging object saving log to its destination | |
|
197
|
+
| `WORKFLOW_APP_MAX_PROCESS` | Schedule | 2 | The maximum process worker number that run in scheduler app module | |
|
198
|
+
| `WORKFLOW_APP_MAX_SCHEDULE_PER_PROCESS` | Schedule | 100 | A schedule per process that run parallel | |
|
199
|
+
| `WORKFLOW_APP_STOP_BOUNDARY_DELTA` | Schedule | '{"minutes": 5, "seconds": 20}' | A time delta value that use to stop scheduler app in json string format | |
|
198
200
|
|
199
201
|
**API Application**:
|
200
202
|
|
201
|
-
| Environment
|
202
|
-
|
203
|
-
| `WORKFLOW_API_ENABLE_ROUTE_WORKFLOW`
|
204
|
-
| `WORKFLOW_API_ENABLE_ROUTE_SCHEDULE`
|
203
|
+
| Environment | Component | Default | Description | Remark |
|
204
|
+
|:--------------------------------------|-----------|---------|-----------------------------------------------------------------------------------|--------|
|
205
|
+
| `WORKFLOW_API_ENABLE_ROUTE_WORKFLOW` | API | true | A flag that enable workflow route to manage execute manually and workflow logging | |
|
206
|
+
| `WORKFLOW_API_ENABLE_ROUTE_SCHEDULE` | API | true | A flag that enable run scheduler | |
|
205
207
|
|
206
208
|
## :rocket: Deployment
|
207
209
|
|
@@ -224,3 +226,17 @@ like crontab job but via Python API.
|
|
224
226
|
> [!NOTE]
|
225
227
|
> If this package already deploy, it able to use
|
226
228
|
> `uvicorn ddeutil.workflow.api:app --host 127.0.0.1 --port 80 --workers 4`
|
229
|
+
|
230
|
+
### Docker Container
|
231
|
+
|
232
|
+
Create Docker image;
|
233
|
+
|
234
|
+
```shell
|
235
|
+
$ docker build -t ddeutil-workflow:latest -f .container/Dockerfile .
|
236
|
+
```
|
237
|
+
|
238
|
+
Run the above Docker image;
|
239
|
+
|
240
|
+
```shell
|
241
|
+
$ docker run -i ddeutil-workflow:latest
|
242
|
+
```
|
@@ -147,29 +147,31 @@ The main configuration that use to dynamic changing with your propose of this
|
|
147
147
|
application. If any configuration values do not set yet, it will use default value
|
148
148
|
and do not raise any error to you.
|
149
149
|
|
150
|
-
| Environment
|
151
|
-
|
152
|
-
| `WORKFLOW_ROOT_PATH`
|
153
|
-
| `WORKFLOW_CORE_REGISTRY`
|
154
|
-
| `WORKFLOW_CORE_REGISTRY_FILTER`
|
155
|
-
| `WORKFLOW_CORE_PATH_CONF`
|
156
|
-
| `WORKFLOW_CORE_TIMEZONE`
|
157
|
-
| `WORKFLOW_CORE_STAGE_DEFAULT_ID`
|
158
|
-
| `WORKFLOW_CORE_STAGE_RAISE_ERROR`
|
159
|
-
| `
|
160
|
-
| `
|
161
|
-
| `
|
162
|
-
| `
|
163
|
-
| `
|
164
|
-
| `
|
165
|
-
| `
|
150
|
+
| Environment | Component | Default | Description | Remark |
|
151
|
+
|:----------------------------------------|-----------|----------------------------------|--------------------------------------------------------------------------------------------------------------------|--------|
|
152
|
+
| `WORKFLOW_ROOT_PATH` | Core | . | The root path of the workflow application | |
|
153
|
+
| `WORKFLOW_CORE_REGISTRY` | Core | src.ddeutil.workflow,tests.utils | List of importable string for the hook stage | |
|
154
|
+
| `WORKFLOW_CORE_REGISTRY_FILTER` | Core | ddeutil.workflow.utils | List of importable string for the filter template | |
|
155
|
+
| `WORKFLOW_CORE_PATH_CONF` | Core | conf | The config path that keep all template `.yaml` files | |
|
156
|
+
| `WORKFLOW_CORE_TIMEZONE` | Core | Asia/Bangkok | A Timezone string value that will pass to `ZoneInfo` object | |
|
157
|
+
| `WORKFLOW_CORE_STAGE_DEFAULT_ID` | Core | true | A flag that enable default stage ID that use for catch an execution output | |
|
158
|
+
| `WORKFLOW_CORE_STAGE_RAISE_ERROR` | Core | false | A flag that all stage raise StageException from stage execution | |
|
159
|
+
| `WORKFLOW_CORE_JOB_DEFAULT_ID` | Core | false | A flag that enable default job ID that use for catch an execution output. The ID that use will be sequence number. | |
|
160
|
+
| `WORKFLOW_CORE_MAX_NUM_POKING` | Core | 4 | | |
|
161
|
+
| `WORKFLOW_CORE_MAX_JOB_PARALLEL` | Core | 2 | The maximum job number that able to run parallel in workflow executor | |
|
162
|
+
| `WORKFLOW_CORE_WORKFLOW_ID_SIMPLE_MODE` | Core | true | | |
|
163
|
+
| `WORKFLOW_LOG_DEBUG_MODE` | Log | true | A flag that enable logging with debug level mode | |
|
164
|
+
| `WORKFLOW_LOG_ENABLE_WRITE` | Log | true | A flag that enable logging object saving log to its destination | |
|
165
|
+
| `WORKFLOW_APP_MAX_PROCESS` | Schedule | 2 | The maximum process worker number that run in scheduler app module | |
|
166
|
+
| `WORKFLOW_APP_MAX_SCHEDULE_PER_PROCESS` | Schedule | 100 | A schedule per process that run parallel | |
|
167
|
+
| `WORKFLOW_APP_STOP_BOUNDARY_DELTA` | Schedule | '{"minutes": 5, "seconds": 20}' | A time delta value that use to stop scheduler app in json string format | |
|
166
168
|
|
167
169
|
**API Application**:
|
168
170
|
|
169
|
-
| Environment
|
170
|
-
|
171
|
-
| `WORKFLOW_API_ENABLE_ROUTE_WORKFLOW`
|
172
|
-
| `WORKFLOW_API_ENABLE_ROUTE_SCHEDULE`
|
171
|
+
| Environment | Component | Default | Description | Remark |
|
172
|
+
|:--------------------------------------|-----------|---------|-----------------------------------------------------------------------------------|--------|
|
173
|
+
| `WORKFLOW_API_ENABLE_ROUTE_WORKFLOW` | API | true | A flag that enable workflow route to manage execute manually and workflow logging | |
|
174
|
+
| `WORKFLOW_API_ENABLE_ROUTE_SCHEDULE` | API | true | A flag that enable run scheduler | |
|
173
175
|
|
174
176
|
## :rocket: Deployment
|
175
177
|
|
@@ -192,3 +194,17 @@ like crontab job but via Python API.
|
|
192
194
|
> [!NOTE]
|
193
195
|
> If this package already deploy, it able to use
|
194
196
|
> `uvicorn ddeutil.workflow.api:app --host 127.0.0.1 --port 80 --workers 4`
|
197
|
+
|
198
|
+
### Docker Container
|
199
|
+
|
200
|
+
Create Docker image;
|
201
|
+
|
202
|
+
```shell
|
203
|
+
$ docker build -t ddeutil-workflow:latest -f .container/Dockerfile .
|
204
|
+
```
|
205
|
+
|
206
|
+
Run the above Docker image;
|
207
|
+
|
208
|
+
```shell
|
209
|
+
$ docker run -i ddeutil-workflow:latest
|
210
|
+
```
|
@@ -26,8 +26,8 @@ classifiers = [
|
|
26
26
|
]
|
27
27
|
requires-python = ">=3.9.13"
|
28
28
|
dependencies = [
|
29
|
-
"ddeutil>=0.4.
|
30
|
-
"ddeutil-io>=0.
|
29
|
+
"ddeutil>=0.4.3",
|
30
|
+
"ddeutil-io[yaml]>=0.2.3",
|
31
31
|
"python-dotenv==1.0.1",
|
32
32
|
"typer==0.12.5,<1.0.0",
|
33
33
|
"schedule==1.2.2,<2.0.0",
|
@@ -60,7 +60,7 @@ changelog = "CHANGELOG.md"
|
|
60
60
|
branch = true
|
61
61
|
relative_files = true
|
62
62
|
concurrency = ["thread", "multiprocessing"]
|
63
|
-
source = ["ddeutil.workflow"
|
63
|
+
source = ["ddeutil.workflow"]
|
64
64
|
omit = [
|
65
65
|
"src/ddeutil/workflow/__about__.py",
|
66
66
|
# Omit this files because it does not ready to production.
|
@@ -68,12 +68,13 @@ omit = [
|
|
68
68
|
"src/ddeutil/workflow/cli.py",
|
69
69
|
"src/ddeutil/workflow/repeat.py",
|
70
70
|
"src/ddeutil/workflow/route.py",
|
71
|
-
"tests/utils.py",
|
72
|
-
"tests/tasks/dummy.py",
|
73
71
|
]
|
74
72
|
|
75
73
|
[tool.coverage.report]
|
76
|
-
exclude_lines = [
|
74
|
+
exclude_lines = [
|
75
|
+
"raise NotImplementedError",
|
76
|
+
"pragma: no cov",
|
77
|
+
]
|
77
78
|
|
78
79
|
[tool.pytest.ini_options]
|
79
80
|
pythonpath = ["src"]
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__: str = "0.0.16"
|
@@ -0,0 +1,125 @@
|
|
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 re
|
9
|
+
from collections.abc import Iterator
|
10
|
+
from dataclasses import dataclass
|
11
|
+
from re import (
|
12
|
+
IGNORECASE,
|
13
|
+
MULTILINE,
|
14
|
+
UNICODE,
|
15
|
+
VERBOSE,
|
16
|
+
Match,
|
17
|
+
Pattern,
|
18
|
+
)
|
19
|
+
from typing import Any, Optional, TypedDict, Union
|
20
|
+
|
21
|
+
from typing_extensions import Self
|
22
|
+
|
23
|
+
TupleStr = tuple[str, ...]
|
24
|
+
DictData = dict[str, Any]
|
25
|
+
DictStr = dict[str, str]
|
26
|
+
Matrix = dict[str, Union[list[str], list[int]]]
|
27
|
+
|
28
|
+
|
29
|
+
class Context(TypedDict):
|
30
|
+
params: dict[str, Any]
|
31
|
+
jobs: dict[str, Any]
|
32
|
+
|
33
|
+
|
34
|
+
@dataclass(frozen=True)
|
35
|
+
class CallerRe:
|
36
|
+
"""Caller dataclass that catching result from the matching regex with the
|
37
|
+
Re.RE_CALLER value.
|
38
|
+
"""
|
39
|
+
|
40
|
+
full: str
|
41
|
+
caller: str
|
42
|
+
caller_prefix: Optional[str]
|
43
|
+
caller_last: str
|
44
|
+
post_filters: str
|
45
|
+
|
46
|
+
@classmethod
|
47
|
+
def from_regex(cls, match: Match[str]) -> Self:
|
48
|
+
"""Class construct from matching result.
|
49
|
+
|
50
|
+
:rtype: Self
|
51
|
+
"""
|
52
|
+
return cls(full=match.group(0), **match.groupdict())
|
53
|
+
|
54
|
+
|
55
|
+
class Re:
|
56
|
+
"""Regular expression config for this package."""
|
57
|
+
|
58
|
+
# NOTE:
|
59
|
+
# Regular expression:
|
60
|
+
# - Version 1:
|
61
|
+
# \${{\s*(?P<caller>[a-zA-Z0-9_.\s'\"\[\]\(\)\-\{}]+?)\s*(?P<post_filters>(?:\|\s*(?:[a-zA-Z0-9_]{3,}[a-zA-Z0-9_.,-\\%\s'\"[\]()\{}]+)\s*)*)}}
|
62
|
+
# - Version 2: (2024-09-30):
|
63
|
+
# \${{\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*)*)}}
|
64
|
+
# - Version 3: (2024-10-05):
|
65
|
+
# \${{\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*)*)}}
|
66
|
+
#
|
67
|
+
# Examples:
|
68
|
+
# - ${{ params.data_dt }}
|
69
|
+
# - ${{ params.source.table }}
|
70
|
+
# - ${{ params.datetime | fmt('%Y-%m-%d') }}
|
71
|
+
# - ${{ params.source?.schema }}
|
72
|
+
#
|
73
|
+
__re_caller: str = r"""
|
74
|
+
\$
|
75
|
+
{{
|
76
|
+
\s*
|
77
|
+
(?P<caller>
|
78
|
+
(?P<caller_prefix>(?:[a-zA-Z_-]+\??\.)*)
|
79
|
+
(?P<caller_last>[a-zA-Z0-9_\-.'\"(\)[\]{}]+\??)
|
80
|
+
)
|
81
|
+
\s*
|
82
|
+
(?P<post_filters>
|
83
|
+
(?:
|
84
|
+
\|\s*
|
85
|
+
(?:
|
86
|
+
[a-zA-Z0-9_]{3,}
|
87
|
+
[a-zA-Z0-9_.,-\\%\s'\"[\]()\{}]*
|
88
|
+
)\s*
|
89
|
+
)*
|
90
|
+
)
|
91
|
+
}}
|
92
|
+
"""
|
93
|
+
RE_CALLER: Pattern = re.compile(
|
94
|
+
__re_caller, MULTILINE | IGNORECASE | UNICODE | VERBOSE
|
95
|
+
)
|
96
|
+
|
97
|
+
# NOTE:
|
98
|
+
# Regular expression:
|
99
|
+
# - Version 1:
|
100
|
+
# ^(?P<path>[^/@]+)/(?P<func>[^@]+)@(?P<tag>.+)$
|
101
|
+
#
|
102
|
+
# Examples:
|
103
|
+
# - tasks/function@dummy
|
104
|
+
__re_task_fmt: str = r"""
|
105
|
+
^
|
106
|
+
(?P<path>[^/@]+)
|
107
|
+
/
|
108
|
+
(?P<func>[^@]+)
|
109
|
+
@
|
110
|
+
(?P<tag>.+)
|
111
|
+
$
|
112
|
+
"""
|
113
|
+
RE_TASK_FMT: Pattern = re.compile(
|
114
|
+
__re_task_fmt, MULTILINE | IGNORECASE | UNICODE | VERBOSE
|
115
|
+
)
|
116
|
+
|
117
|
+
@classmethod
|
118
|
+
def finditer_caller(cls, value) -> Iterator[CallerRe]:
|
119
|
+
"""Generate CallerRe object that create from matching object that
|
120
|
+
extract with re.finditer function.
|
121
|
+
|
122
|
+
:rtype: Iterator[CallerRe]
|
123
|
+
"""
|
124
|
+
for found in cls.RE_CALLER.finditer(value):
|
125
|
+
yield CallerRe.from_regex(found)
|
@@ -7,7 +7,6 @@ from __future__ import annotations
|
|
7
7
|
|
8
8
|
import asyncio
|
9
9
|
import contextlib
|
10
|
-
import os
|
11
10
|
import uuid
|
12
11
|
from collections.abc import AsyncIterator
|
13
12
|
from datetime import datetime, timedelta
|
@@ -15,7 +14,6 @@ from queue import Empty, Queue
|
|
15
14
|
from threading import Thread
|
16
15
|
from typing import TypedDict
|
17
16
|
|
18
|
-
from ddeutil.core import str2bool
|
19
17
|
from dotenv import load_dotenv
|
20
18
|
from fastapi import FastAPI
|
21
19
|
from fastapi.middleware.gzip import GZipMiddleware
|
@@ -23,6 +21,7 @@ from fastapi.responses import UJSONResponse
|
|
23
21
|
from pydantic import BaseModel
|
24
22
|
|
25
23
|
from .__about__ import __version__
|
24
|
+
from .conf import config
|
26
25
|
from .log import get_logger
|
27
26
|
from .repeat import repeat_at, repeat_every
|
28
27
|
from .scheduler import WorkflowTaskData
|
@@ -131,12 +130,12 @@ async def message_upper(payload: Payload):
|
|
131
130
|
return await get_result(request_id)
|
132
131
|
|
133
132
|
|
134
|
-
if
|
133
|
+
if config.enable_route_workflow:
|
135
134
|
from .route import workflow
|
136
135
|
|
137
136
|
app.include_router(workflow)
|
138
137
|
|
139
|
-
if
|
138
|
+
if config.enable_route_schedule:
|
140
139
|
from .route import schedule
|
141
140
|
from .scheduler import workflow_task
|
142
141
|
|
@@ -6,15 +6,14 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import json
|
9
|
-
import os
|
10
9
|
from datetime import datetime
|
11
10
|
from enum import Enum
|
12
11
|
from typing import Annotated, Optional
|
13
|
-
from zoneinfo import ZoneInfo
|
14
12
|
|
15
13
|
from ddeutil.core import str2list
|
16
14
|
from typer import Argument, Option, Typer
|
17
15
|
|
16
|
+
from .conf import config
|
18
17
|
from .log import get_logger
|
19
18
|
|
20
19
|
logger = get_logger("ddeutil.workflow")
|
@@ -73,9 +72,7 @@ def schedule(
|
|
73
72
|
excluded: list[str] = str2list(excluded) if excluded else []
|
74
73
|
externals: str = externals or "{}"
|
75
74
|
if stop:
|
76
|
-
stop: datetime = stop.astimezone(
|
77
|
-
tz=ZoneInfo(os.getenv("WORKFLOW_CORE_TIMEZONE", "UTC"))
|
78
|
-
)
|
75
|
+
stop: datetime = stop.astimezone(tz=config.tz)
|
79
76
|
|
80
77
|
from .scheduler import workflow_runner
|
81
78
|
|