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.
Files changed (64) hide show
  1. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/PKG-INFO +39 -23
  2. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/README.md +36 -20
  3. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/pyproject.toml +7 -6
  4. ddeutil_workflow-0.0.16/src/ddeutil/workflow/__about__.py +1 -0
  5. ddeutil_workflow-0.0.16/src/ddeutil/workflow/__types.py +125 -0
  6. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/api.py +3 -4
  7. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/cli.py +2 -5
  8. ddeutil_workflow-0.0.16/src/ddeutil/workflow/conf.py +318 -0
  9. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/job.py +44 -25
  10. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/log.py +5 -8
  11. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/on.py +1 -1
  12. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/repeat.py +2 -5
  13. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/route.py +4 -11
  14. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/scheduler.py +97 -64
  15. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/stage.py +44 -30
  16. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/utils.py +91 -266
  17. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/PKG-INFO +39 -23
  18. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/SOURCES.txt +8 -10
  19. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/requires.txt +2 -2
  20. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test__conf_exist.py +1 -1
  21. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test__regex.py +11 -2
  22. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_poke.py +1 -1
  23. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_scheduler.py +12 -7
  24. ddeutil_workflow-0.0.16/tests/test_stage.py +62 -0
  25. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_stage_bash.py +6 -12
  26. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_stage_py.py +16 -31
  27. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_stage_trigger.py +1 -3
  28. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_utils.py +8 -2
  29. ddeutil_workflow-0.0.16/tests/test_utils_params.py +59 -0
  30. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_utils_result.py +5 -18
  31. ddeutil_workflow-0.0.16/tests/test_utils_tag.py +42 -0
  32. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_workflow.py +29 -2
  33. ddeutil_workflow-0.0.16/tests/test_workflow_depends.py +74 -0
  34. ddeutil_workflow-0.0.14/tests/test_pipeline_matrix.py → ddeutil_workflow-0.0.16/tests/test_workflow_matrix.py +4 -4
  35. ddeutil_workflow-0.0.14/tests/test_pipeline_on.py → ddeutil_workflow-0.0.16/tests/test_workflow_on.py +1 -1
  36. ddeutil_workflow-0.0.14/tests/test_pipeline_params.py → ddeutil_workflow-0.0.16/tests/test_workflow_params.py +1 -1
  37. ddeutil_workflow-0.0.14/tests/test_pipeline_run.py → ddeutil_workflow-0.0.16/tests/test_workflow_run.py +15 -4
  38. ddeutil_workflow-0.0.14/tests/test_pipeline_task.py → ddeutil_workflow-0.0.16/tests/test_workflow_task.py +3 -3
  39. ddeutil_workflow-0.0.14/src/ddeutil/workflow/__about__.py +0 -1
  40. ddeutil_workflow-0.0.14/src/ddeutil/workflow/__types.py +0 -80
  41. ddeutil_workflow-0.0.14/src/ddeutil/workflow/conf.py +0 -41
  42. ddeutil_workflow-0.0.14/tests/test_conf.py +0 -8
  43. ddeutil_workflow-0.0.14/tests/test_pipeline_if.py +0 -28
  44. ddeutil_workflow-0.0.14/tests/test_pipeline_run_raise.py +0 -12
  45. ddeutil_workflow-0.0.14/tests/test_stage.py +0 -44
  46. ddeutil_workflow-0.0.14/tests/test_stage_condition.py +0 -14
  47. ddeutil_workflow-0.0.14/tests/test_workflow_desc.py +0 -11
  48. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/LICENSE +0 -0
  49. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/setup.cfg +0 -0
  50. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/__init__.py +0 -0
  51. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/cron.py +0 -0
  52. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil/workflow/exceptions.py +0 -0
  53. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/dependency_links.txt +0 -0
  54. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/entry_points.txt +0 -0
  55. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/src/ddeutil_workflow.egg-info/top_level.txt +0 -0
  56. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_cron.py +0 -0
  57. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_job.py +0 -0
  58. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_job_py.py +0 -0
  59. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_job_strategy.py +0 -0
  60. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_log.py +0 -0
  61. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_on.py +0 -0
  62. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_params.py +0 -0
  63. {ddeutil_workflow-0.0.14 → ddeutil_workflow-0.0.16}/tests/test_stage_hook.py +0 -0
  64. {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.14
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.0
26
- Requires-Dist: ddeutil-io>=0.1.13
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 | Component | Default | Description |
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 | true | A flag that all stage raise StageException from stage execution |
191
- | `WORKFLOW_CORE_MAX_NUM_POKING` | Core | 4 | |
192
- | `WORKFLOW_CORE_MAX_JOB_PARALLEL` | Core | 2 | The maximum job number that able to run parallel in workflow executor |
193
- | `WORKFLOW_LOG_DEBUG_MODE` | Log | true | A flag that enable logging with debug level mode |
194
- | `WORKFLOW_LOG_ENABLE_WRITE` | Log | true | A flag that enable logging object saving log to its destination |
195
- | `WORKFLOW_APP_PROCESS_WORKER` | Schedule | 2 | The maximum process worker number that run in scheduler app module |
196
- | `WORKFLOW_APP_SCHEDULE_PER_PROCESS` | Schedule | 100 | A schedule per process that run parallel |
197
- | `WORKFLOW_APP_STOP_BOUNDARY_DELTA` | Schedule | '{"minutes": 5, "seconds": 20}' | A time delta value that use to stop scheduler app in json string format |
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 | Component | Default | Description |
202
- |--------------------------------------|-----------|---------|-----------------------------------------------------------------------------------|
203
- | `WORKFLOW_API_ENABLE_ROUTE_WORKFLOW` | API | true | A flag that enable workflow route to manage execute manually and workflow logging |
204
- | `WORKFLOW_API_ENABLE_ROUTE_SCHEDULE` | API | true | A flag that enable run scheduler |
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 | Component | Default | Description |
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 | true | A flag that all stage raise StageException from stage execution |
159
- | `WORKFLOW_CORE_MAX_NUM_POKING` | Core | 4 | |
160
- | `WORKFLOW_CORE_MAX_JOB_PARALLEL` | Core | 2 | The maximum job number that able to run parallel in workflow executor |
161
- | `WORKFLOW_LOG_DEBUG_MODE` | Log | true | A flag that enable logging with debug level mode |
162
- | `WORKFLOW_LOG_ENABLE_WRITE` | Log | true | A flag that enable logging object saving log to its destination |
163
- | `WORKFLOW_APP_PROCESS_WORKER` | Schedule | 2 | The maximum process worker number that run in scheduler app module |
164
- | `WORKFLOW_APP_SCHEDULE_PER_PROCESS` | Schedule | 100 | A schedule per process that run parallel |
165
- | `WORKFLOW_APP_STOP_BOUNDARY_DELTA` | Schedule | '{"minutes": 5, "seconds": 20}' | A time delta value that use to stop scheduler app in json string format |
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 | Component | Default | Description |
170
- |--------------------------------------|-----------|---------|-----------------------------------------------------------------------------------|
171
- | `WORKFLOW_API_ENABLE_ROUTE_WORKFLOW` | API | true | A flag that enable workflow route to manage execute manually and workflow logging |
172
- | `WORKFLOW_API_ENABLE_ROUTE_SCHEDULE` | API | true | A flag that enable run scheduler |
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.0",
30
- "ddeutil-io>=0.1.13",
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", "tests"]
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 = ["raise NotImplementedError"]
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 str2bool(os.getenv("WORKFLOW_API_ENABLE_ROUTE_WORKFLOW", "true")):
133
+ if config.enable_route_workflow:
135
134
  from .route import workflow
136
135
 
137
136
  app.include_router(workflow)
138
137
 
139
- if str2bool(os.getenv("WORKFLOW_API_ENABLE_ROUTE_SCHEDULE", "true")):
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