ddeutil-workflow 0.0.65__tar.gz → 0.0.67__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.65 → ddeutil_workflow-0.0.67}/PKG-INFO +13 -35
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/README.md +9 -22
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/pyproject.toml +6 -22
- ddeutil_workflow-0.0.67/src/ddeutil/workflow/__about__.py +1 -0
- ddeutil_workflow-0.0.67/src/ddeutil/workflow/__main__.py +4 -0
- ddeutil_workflow-0.0.67/src/ddeutil/workflow/cli.py +68 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/conf.py +1 -5
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/errors.py +0 -6
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/job.py +6 -10
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/logs.py +1 -1
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/result.py +13 -10
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/stages.py +120 -26
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/workflow.py +25 -11
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil_workflow.egg-info/PKG-INFO +13 -35
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil_workflow.egg-info/SOURCES.txt +1 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil_workflow.egg-info/requires.txt +2 -14
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_conf.py +0 -6
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_job_exec_strategy.py +4 -2
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_result.py +4 -1
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_workflow_release.py +52 -0
- ddeutil_workflow-0.0.65/src/ddeutil/workflow/__about__.py +0 -1
- ddeutil_workflow-0.0.65/src/ddeutil/workflow/__main__.py +0 -30
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/LICENSE +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/setup.cfg +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/__cron.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/__init__.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/__types.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/api/__init__.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/api/logs.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/api/routes/__init__.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/api/routes/job.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/api/routes/logs.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/api/routes/workflows.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/event.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/params.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/reusables.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil/workflow/utils.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil_workflow.egg-info/dependency_links.txt +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil_workflow.egg-info/entry_points.txt +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/src/ddeutil_workflow.egg-info/top_level.txt +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test__cron.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test__regex.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_errors.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_event.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_job.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_job_exec.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_logs_audit.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_logs_trace.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_params.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_reusables_call_tag.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_reusables_func_model.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_reusables_template.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_reusables_template_filter.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_strategy.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_utils.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_workflow.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_workflow_exec.py +0 -0
- {ddeutil_workflow-0.0.65 → ddeutil_workflow-0.0.67}/tests/test_workflow_exec_job.py +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ddeutil-workflow
|
3
|
-
Version: 0.0.
|
4
|
-
Summary: Lightweight workflow orchestration
|
3
|
+
Version: 0.0.67
|
4
|
+
Summary: Lightweight workflow orchestration with YAML template
|
5
5
|
Author-email: ddeutils <korawich.anu@gmail.com>
|
6
6
|
License: MIT
|
7
7
|
Project-URL: Homepage, https://github.com/ddeutils/ddeutil-workflow/
|
@@ -27,7 +27,7 @@ Requires-Dist: ddeutil-io[toml,yaml]>=0.2.14
|
|
27
27
|
Requires-Dist: pydantic==2.11.4
|
28
28
|
Requires-Dist: pydantic-extra-types==2.10.4
|
29
29
|
Requires-Dist: python-dotenv==1.1.0
|
30
|
-
Requires-Dist:
|
30
|
+
Requires-Dist: typer==0.15.4
|
31
31
|
Provides-Extra: all
|
32
32
|
Requires-Dist: fastapi<1.0.0,>=0.115.0; extra == "all"
|
33
33
|
Requires-Dist: uvicorn; extra == "all"
|
@@ -35,18 +35,9 @@ Requires-Dist: httpx; extra == "all"
|
|
35
35
|
Requires-Dist: ujson; extra == "all"
|
36
36
|
Requires-Dist: aiofiles; extra == "all"
|
37
37
|
Requires-Dist: aiohttp; extra == "all"
|
38
|
-
|
39
|
-
Requires-Dist: fastapi<1.0.0,>=0.115.0; extra == "api"
|
40
|
-
Requires-Dist: uvicorn; extra == "api"
|
41
|
-
Requires-Dist: httpx; extra == "api"
|
42
|
-
Requires-Dist: ujson; extra == "api"
|
43
|
-
Provides-Extra: async
|
44
|
-
Requires-Dist: aiofiles; extra == "async"
|
45
|
-
Requires-Dist: aiohttp; extra == "async"
|
38
|
+
Requires-Dist: requests==2.32.3; extra == "all"
|
46
39
|
Provides-Extra: docker
|
47
40
|
Requires-Dist: docker==7.1.0; extra == "docker"
|
48
|
-
Provides-Extra: self-hosted
|
49
|
-
Requires-Dist: requests==2.32.3; extra == "self-hosted"
|
50
41
|
Dynamic: license-file
|
51
42
|
|
52
43
|
# Workflow Orchestration
|
@@ -142,10 +133,10 @@ the base deps.
|
|
142
133
|
If you want to install this package with application add-ons, you should add
|
143
134
|
`app` in installation;
|
144
135
|
|
145
|
-
| Use-case | Install Optional
|
146
|
-
|
147
|
-
| Python | `ddeutil-workflow`
|
148
|
-
| FastAPI Server | `ddeutil-workflow[
|
136
|
+
| Use-case | Install Optional | Support |
|
137
|
+
|----------------|-------------------------|:-------:|
|
138
|
+
| Python | `ddeutil-workflow` | ✅ |
|
139
|
+
| FastAPI Server | `ddeutil-workflow[all]` | ✅ |
|
149
140
|
|
150
141
|
## 🎯 Usage
|
151
142
|
|
@@ -300,40 +291,27 @@ it will use default value and do not raise any error to you.
|
|
300
291
|
## :rocket: Deployment
|
301
292
|
|
302
293
|
This package able to run as an application service for receive manual trigger
|
303
|
-
from any node via RestAPI
|
304
|
-
like crontab job but via Python API or FastAPI app.
|
294
|
+
from any node via RestAPI with the FastAPI package.
|
305
295
|
|
306
296
|
### API Server
|
307
297
|
|
308
298
|
This server use FastAPI package to be the base application.
|
309
299
|
|
310
300
|
```shell
|
311
|
-
(.venv) $
|
312
|
-
--host 127.0.0.1 \
|
313
|
-
--port 80 \
|
314
|
-
--no-access-log
|
301
|
+
(.venv) $ workflow-cli api --host 127.0.0.1 --port 80
|
315
302
|
```
|
316
303
|
|
317
304
|
> [!NOTE]
|
318
305
|
> If this package already deploy, it is able to use multiprocess;
|
319
|
-
>
|
320
|
-
|
321
|
-
### Local Schedule
|
322
|
-
|
323
|
-
> [!WARNING]
|
324
|
-
> This CLI does not implement yet.
|
325
|
-
|
326
|
-
```shell
|
327
|
-
(.venv) $ ddeutil-workflow schedule
|
328
|
-
```
|
306
|
+
> `$ workflow-cli api --host 127.0.0.1 --port 80 --workers 4`
|
329
307
|
|
330
308
|
### Docker Container
|
331
309
|
|
332
310
|
Build a Docker container from this package.
|
333
311
|
|
334
312
|
```shell
|
335
|
-
$ docker
|
336
|
-
$ docker run
|
313
|
+
$ docker pull ghcr.io/ddeutils/ddeutil-workflow:latest
|
314
|
+
$ docker run --rm ghcr.io/ddeutils/ddeutil-workflow:latest ddeutil-worker
|
337
315
|
```
|
338
316
|
|
339
317
|
## :speech_balloon: Contribute
|
@@ -91,10 +91,10 @@ the base deps.
|
|
91
91
|
If you want to install this package with application add-ons, you should add
|
92
92
|
`app` in installation;
|
93
93
|
|
94
|
-
| Use-case | Install Optional
|
95
|
-
|
96
|
-
| Python | `ddeutil-workflow`
|
97
|
-
| FastAPI Server | `ddeutil-workflow[
|
94
|
+
| Use-case | Install Optional | Support |
|
95
|
+
|----------------|-------------------------|:-------:|
|
96
|
+
| Python | `ddeutil-workflow` | ✅ |
|
97
|
+
| FastAPI Server | `ddeutil-workflow[all]` | ✅ |
|
98
98
|
|
99
99
|
## 🎯 Usage
|
100
100
|
|
@@ -249,40 +249,27 @@ it will use default value and do not raise any error to you.
|
|
249
249
|
## :rocket: Deployment
|
250
250
|
|
251
251
|
This package able to run as an application service for receive manual trigger
|
252
|
-
from any node via RestAPI
|
253
|
-
like crontab job but via Python API or FastAPI app.
|
252
|
+
from any node via RestAPI with the FastAPI package.
|
254
253
|
|
255
254
|
### API Server
|
256
255
|
|
257
256
|
This server use FastAPI package to be the base application.
|
258
257
|
|
259
258
|
```shell
|
260
|
-
(.venv) $
|
261
|
-
--host 127.0.0.1 \
|
262
|
-
--port 80 \
|
263
|
-
--no-access-log
|
259
|
+
(.venv) $ workflow-cli api --host 127.0.0.1 --port 80
|
264
260
|
```
|
265
261
|
|
266
262
|
> [!NOTE]
|
267
263
|
> If this package already deploy, it is able to use multiprocess;
|
268
|
-
>
|
269
|
-
|
270
|
-
### Local Schedule
|
271
|
-
|
272
|
-
> [!WARNING]
|
273
|
-
> This CLI does not implement yet.
|
274
|
-
|
275
|
-
```shell
|
276
|
-
(.venv) $ ddeutil-workflow schedule
|
277
|
-
```
|
264
|
+
> `$ workflow-cli api --host 127.0.0.1 --port 80 --workers 4`
|
278
265
|
|
279
266
|
### Docker Container
|
280
267
|
|
281
268
|
Build a Docker container from this package.
|
282
269
|
|
283
270
|
```shell
|
284
|
-
$ docker
|
285
|
-
$ docker run
|
271
|
+
$ docker pull ghcr.io/ddeutils/ddeutil-workflow:latest
|
272
|
+
$ docker run --rm ghcr.io/ddeutils/ddeutil-workflow:latest ddeutil-worker
|
286
273
|
```
|
287
274
|
|
288
275
|
## :speech_balloon: Contribute
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "ddeutil-workflow"
|
7
|
-
description = "Lightweight workflow orchestration"
|
7
|
+
description = "Lightweight workflow orchestration with YAML template"
|
8
8
|
readme = {file = "README.md", content-type = "text/markdown"}
|
9
9
|
license = {text = "MIT"}
|
10
10
|
authors = [{ name = "ddeutils", email = "korawich.anu@gmail.com" }]
|
@@ -30,7 +30,7 @@ dependencies = [
|
|
30
30
|
"pydantic==2.11.4",
|
31
31
|
"pydantic-extra-types==2.10.4",
|
32
32
|
"python-dotenv==1.1.0",
|
33
|
-
"
|
33
|
+
"typer==0.15.4",
|
34
34
|
]
|
35
35
|
dynamic = ["version"]
|
36
36
|
|
@@ -42,23 +42,11 @@ all = [
|
|
42
42
|
"ujson",
|
43
43
|
"aiofiles",
|
44
44
|
"aiohttp",
|
45
|
-
|
46
|
-
api = [
|
47
|
-
"fastapi>=0.115.0,<1.0.0",
|
48
|
-
"uvicorn",
|
49
|
-
"httpx",
|
50
|
-
"ujson",
|
51
|
-
]
|
52
|
-
async = [
|
53
|
-
"aiofiles",
|
54
|
-
"aiohttp",
|
45
|
+
"requests==2.32.3",
|
55
46
|
]
|
56
47
|
docker = [
|
57
48
|
"docker==7.1.0",
|
58
49
|
]
|
59
|
-
self_hosted = [
|
60
|
-
"requests==2.32.3",
|
61
|
-
]
|
62
50
|
|
63
51
|
[project.urls]
|
64
52
|
Homepage = "https://github.com/ddeutils/ddeutil-workflow/"
|
@@ -90,15 +78,13 @@ omit = [
|
|
90
78
|
"src/ddeutil/workflow/__about__.py",
|
91
79
|
"src/ddeutil/workflow/__cron.py",
|
92
80
|
"src/ddeutil/workflow/__main__.py",
|
81
|
+
"src/ddeutil/workflow/cli.py",
|
93
82
|
"src/ddeutil/workflow/api/__init__.py",
|
94
83
|
"src/ddeutil/workflow/api/logs.py",
|
95
|
-
"src/ddeutil/workflow/api/utils.py",
|
96
84
|
"src/ddeutil/workflow/api/routes/__init__.py",
|
97
85
|
"src/ddeutil/workflow/api/routes/job.py",
|
98
86
|
"src/ddeutil/workflow/api/routes/logs.py",
|
99
|
-
"src/ddeutil/workflow/api/routes/schedules.py",
|
100
87
|
"src/ddeutil/workflow/api/routes/workflows.py",
|
101
|
-
"app.py",
|
102
88
|
]
|
103
89
|
|
104
90
|
[tool.coverage.report]
|
@@ -110,12 +96,10 @@ exclude_lines = [
|
|
110
96
|
[tool.pytest.ini_options]
|
111
97
|
pythonpath = ["src"]
|
112
98
|
asyncio_default_fixture_loop_scope = "fuction"
|
113
|
-
# NOTE: You can deslect multiple markers by '-m "not (
|
99
|
+
# NOTE: You can deslect multiple markers by '-m "not (asyncio or api)"'
|
114
100
|
markers = [
|
115
|
-
"poke: marks tests as slow by poking (deselect with '-m \"not poke\"')",
|
116
|
-
"schedule: marks tests as schedule (deselect with '-m \"not schedule\"')",
|
117
101
|
"api: marks tests as api (deselect with '-m \"not api\"')",
|
118
|
-
"asyncio: marks async
|
102
|
+
"asyncio: marks async test cases",
|
119
103
|
]
|
120
104
|
console_output_style = "count"
|
121
105
|
addopts = [
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__: str = "0.0.67"
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import json
|
2
|
+
from typing import Annotated, Any
|
3
|
+
|
4
|
+
import typer
|
5
|
+
import uvicorn
|
6
|
+
|
7
|
+
from .__about__ import __version__
|
8
|
+
from .api import app as fastapp
|
9
|
+
from .api.logs import LOGGING_CONFIG
|
10
|
+
|
11
|
+
app = typer.Typer(
|
12
|
+
pretty_exceptions_enable=True,
|
13
|
+
)
|
14
|
+
|
15
|
+
|
16
|
+
@app.callback()
|
17
|
+
def callback():
|
18
|
+
"""
|
19
|
+
Awesome Portal Gun
|
20
|
+
"""
|
21
|
+
typer.echo("Start call from callback function")
|
22
|
+
|
23
|
+
|
24
|
+
@app.command()
|
25
|
+
def version():
|
26
|
+
"""Get the ddeutil-workflow package version."""
|
27
|
+
typer.echo(__version__)
|
28
|
+
|
29
|
+
|
30
|
+
@app.command()
|
31
|
+
def job(
|
32
|
+
params: Annotated[str, typer.Option(help="A job execute parameters")],
|
33
|
+
):
|
34
|
+
"""Job execution on the local.
|
35
|
+
|
36
|
+
Example:
|
37
|
+
... workflow-cli job --params "{\"test\": 1}"
|
38
|
+
"""
|
39
|
+
try:
|
40
|
+
params_dict: dict[str, Any] = json.loads(params)
|
41
|
+
except json.JSONDecodeError as e:
|
42
|
+
raise ValueError(f"params does not support format: {params!r}.") from e
|
43
|
+
typer.echo(f"Job params: {params_dict}")
|
44
|
+
|
45
|
+
|
46
|
+
@app.command()
|
47
|
+
def api(
|
48
|
+
host: Annotated[str, typer.Option(help="A host url.")] = "0.0.0.0",
|
49
|
+
port: Annotated[int, typer.Option(help="A port url.")] = 80,
|
50
|
+
debug: Annotated[bool, typer.Option(help="A debug mode flag")] = True,
|
51
|
+
worker: Annotated[int, typer.Option(help="A worker number")] = None,
|
52
|
+
):
|
53
|
+
"""
|
54
|
+
Provision API application from the FastAPI.
|
55
|
+
"""
|
56
|
+
|
57
|
+
uvicorn.run(
|
58
|
+
fastapp,
|
59
|
+
host=host,
|
60
|
+
port=port,
|
61
|
+
log_config=uvicorn.config.LOGGING_CONFIG | LOGGING_CONFIG,
|
62
|
+
log_level=("DEBUG" if debug else "INFO"),
|
63
|
+
workers=worker,
|
64
|
+
)
|
65
|
+
|
66
|
+
|
67
|
+
if __name__ == "__main__":
|
68
|
+
app()
|
@@ -18,7 +18,7 @@ from zoneinfo import ZoneInfo
|
|
18
18
|
from ddeutil.core import str2bool
|
19
19
|
from ddeutil.io import YamlFlResolve, search_env_replace
|
20
20
|
from ddeutil.io.paths import glob_files, is_ignored, read_ignore
|
21
|
-
from pydantic import SecretStr
|
21
|
+
from pydantic import SecretStr
|
22
22
|
|
23
23
|
from .__types import DictData
|
24
24
|
|
@@ -470,7 +470,3 @@ class CallerSecret(SecretStr): # pragma: no cov
|
|
470
470
|
:rtype: str
|
471
471
|
"""
|
472
472
|
return pass_env(super().get_secret_value())
|
473
|
-
|
474
|
-
|
475
|
-
# NOTE: Define the caller secret type for use it directly in the caller func.
|
476
|
-
CallerSecretType = TypeAdapter(CallerSecret)
|
@@ -90,9 +90,6 @@ class ResultError(UtilError): ...
|
|
90
90
|
class StageError(BaseError): ...
|
91
91
|
|
92
92
|
|
93
|
-
class StageRetryError(StageError): ...
|
94
|
-
|
95
|
-
|
96
93
|
class StageCancelError(StageError): ...
|
97
94
|
|
98
95
|
|
@@ -114,9 +111,6 @@ class WorkflowError(BaseError): ...
|
|
114
111
|
class WorkflowCancelError(WorkflowError): ...
|
115
112
|
|
116
113
|
|
117
|
-
class WorkflowSkipError(WorkflowError): ...
|
118
|
-
|
119
|
-
|
120
114
|
class WorkflowTimeoutError(WorkflowError): ...
|
121
115
|
|
122
116
|
|
@@ -39,7 +39,6 @@ from pydantic import BaseModel, Discriminator, Field, SecretStr, Tag
|
|
39
39
|
from pydantic.functional_validators import field_validator, model_validator
|
40
40
|
from typing_extensions import Self
|
41
41
|
|
42
|
-
from . import JobSkipError
|
43
42
|
from .__types import DictData, DictStr, Matrix, StrOrNone
|
44
43
|
from .errors import JobCancelError, JobError, to_dict
|
45
44
|
from .result import (
|
@@ -774,7 +773,7 @@ def local_execute_strategy(
|
|
774
773
|
*,
|
775
774
|
result: Optional[Result] = None,
|
776
775
|
event: Optional[Event] = None,
|
777
|
-
) -> Result:
|
776
|
+
) -> tuple[Status, Result]:
|
778
777
|
"""Local strategy execution with passing dynamic parameters from the
|
779
778
|
job execution and strategy matrix.
|
780
779
|
|
@@ -799,7 +798,7 @@ def local_execute_strategy(
|
|
799
798
|
:raise JobError: If stage execution raise any error as `StageError`.
|
800
799
|
:raise JobError: If the result from execution has `FAILED` status.
|
801
800
|
|
802
|
-
:rtype: Result
|
801
|
+
:rtype: tuple[Status, Result]
|
803
802
|
"""
|
804
803
|
result: Result = result or Result(
|
805
804
|
run_id=gen_id(job.id or "EMPTY", unique=True),
|
@@ -899,9 +898,7 @@ def local_execute_strategy(
|
|
899
898
|
},
|
900
899
|
},
|
901
900
|
)
|
902
|
-
|
903
|
-
raise JobSkipError("All stage was skipped.")
|
904
|
-
return result
|
901
|
+
return status, result
|
905
902
|
|
906
903
|
|
907
904
|
def local_execute(
|
@@ -1017,14 +1014,13 @@ def local_execute(
|
|
1017
1014
|
|
1018
1015
|
for i, future in enumerate(done, start=0):
|
1019
1016
|
try:
|
1020
|
-
statuses[i] = future.result()
|
1017
|
+
statuses[i], _ = future.result()
|
1021
1018
|
except JobError as e:
|
1022
1019
|
statuses[i] = get_status_from_error(e)
|
1023
1020
|
result.trace.error(
|
1024
|
-
f"[JOB]: {ls}
|
1021
|
+
f"[JOB]: {ls} Handler:||{e.__class__.__name__}: {e}"
|
1025
1022
|
)
|
1026
|
-
|
1027
|
-
mark_errors(context, e)
|
1023
|
+
mark_errors(context, e)
|
1028
1024
|
except CancelledError:
|
1029
1025
|
pass
|
1030
1026
|
|
@@ -848,7 +848,7 @@ class FileAudit(BaseAudit):
|
|
848
848
|
"audit_path", extras=self.extras
|
849
849
|
) / self.filename_fmt.format(name=self.name, release=self.release)
|
850
850
|
|
851
|
-
def save(self, excluded: Optional[list[str]]) -> Self:
|
851
|
+
def save(self, excluded: Optional[list[str]] = None) -> Self:
|
852
852
|
"""Save logging data that receive a context data from a workflow
|
853
853
|
execution result.
|
854
854
|
|
@@ -11,7 +11,7 @@ from __future__ import annotations
|
|
11
11
|
|
12
12
|
from dataclasses import field
|
13
13
|
from datetime import datetime
|
14
|
-
from enum import
|
14
|
+
from enum import Enum
|
15
15
|
from typing import Optional, Union
|
16
16
|
|
17
17
|
from pydantic import ConfigDict
|
@@ -28,7 +28,6 @@ from . import (
|
|
28
28
|
StageSkipError,
|
29
29
|
WorkflowCancelError,
|
30
30
|
WorkflowError,
|
31
|
-
WorkflowSkipError,
|
32
31
|
)
|
33
32
|
from .__types import DictData
|
34
33
|
from .conf import dynamic
|
@@ -37,16 +36,16 @@ from .logs import TraceModel, get_dt_tznow, get_trace
|
|
37
36
|
from .utils import default_gen_id, gen_id, get_dt_now
|
38
37
|
|
39
38
|
|
40
|
-
class Status(
|
39
|
+
class Status(str, Enum):
|
41
40
|
"""Status Int Enum object that use for tracking execution status to the
|
42
41
|
Result dataclass object.
|
43
42
|
"""
|
44
43
|
|
45
|
-
SUCCESS =
|
46
|
-
FAILED =
|
47
|
-
WAIT =
|
48
|
-
SKIP =
|
49
|
-
CANCEL =
|
44
|
+
SUCCESS = "SUCCESS"
|
45
|
+
FAILED = "FAILED"
|
46
|
+
WAIT = "WAIT"
|
47
|
+
SKIP = "SKIP"
|
48
|
+
CANCEL = "CANCEL"
|
50
49
|
|
51
50
|
@property
|
52
51
|
def emoji(self) -> str: # pragma: no cov
|
@@ -68,6 +67,9 @@ class Status(IntEnum):
|
|
68
67
|
def __str__(self) -> str:
|
69
68
|
return self.name
|
70
69
|
|
70
|
+
def is_result(self) -> bool:
|
71
|
+
return self in ResultStatuses
|
72
|
+
|
71
73
|
|
72
74
|
SUCCESS = Status.SUCCESS
|
73
75
|
FAILED = Status.FAILED
|
@@ -75,6 +77,8 @@ WAIT = Status.WAIT
|
|
75
77
|
SKIP = Status.SKIP
|
76
78
|
CANCEL = Status.CANCEL
|
77
79
|
|
80
|
+
ResultStatuses: list[Status] = [SUCCESS, FAILED, CANCEL, SKIP]
|
81
|
+
|
78
82
|
|
79
83
|
def validate_statuses(statuses: list[Status]) -> Status:
|
80
84
|
"""Validate the final status from list of Status object.
|
@@ -106,13 +110,12 @@ def get_status_from_error(
|
|
106
110
|
JobSkipError,
|
107
111
|
WorkflowError,
|
108
112
|
WorkflowCancelError,
|
109
|
-
WorkflowSkipError,
|
110
113
|
Exception,
|
111
114
|
BaseException,
|
112
115
|
]
|
113
116
|
) -> Status:
|
114
117
|
"""Get the Status from the error object."""
|
115
|
-
if isinstance(error, (StageSkipError, JobSkipError
|
118
|
+
if isinstance(error, (StageSkipError, JobSkipError)):
|
116
119
|
return SKIP
|
117
120
|
elif isinstance(
|
118
121
|
error, (StageCancelError, JobCancelError, WorkflowCancelError)
|