ddeutil-workflow 0.0.45__tar.gz → 0.0.46__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 (68) hide show
  1. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/PKG-INFO +2 -2
  2. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/pyproject.toml +1 -2
  3. ddeutil_workflow-0.0.46/src/ddeutil/workflow/__about__.py +1 -0
  4. ddeutil_workflow-0.0.46/src/ddeutil/workflow/__main__.py +0 -0
  5. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/conf.py +6 -24
  6. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/job.py +3 -0
  7. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/stages.py +16 -0
  8. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/workflow.py +2 -2
  9. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil_workflow.egg-info/PKG-INFO +2 -2
  10. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil_workflow.egg-info/SOURCES.txt +1 -0
  11. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_workflow_exec.py +52 -1
  12. ddeutil_workflow-0.0.45/src/ddeutil/workflow/__about__.py +0 -1
  13. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/LICENSE +0 -0
  14. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/README.md +0 -0
  15. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/setup.cfg +0 -0
  16. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/__cron.py +0 -0
  17. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/__init__.py +0 -0
  18. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/__types.py +0 -0
  19. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/api/__init__.py +0 -0
  20. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/api/api.py +0 -0
  21. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/api/log.py +0 -0
  22. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/api/repeat.py +0 -0
  23. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/api/routes/__init__.py +0 -0
  24. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/api/routes/job.py +0 -0
  25. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/api/routes/logs.py +0 -0
  26. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/api/routes/schedules.py +0 -0
  27. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/api/routes/workflows.py +0 -0
  28. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/cron.py +0 -0
  29. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/exceptions.py +0 -0
  30. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/logs.py +0 -0
  31. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/params.py +0 -0
  32. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/result.py +0 -0
  33. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/reusables.py +0 -0
  34. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/scheduler.py +0 -0
  35. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil/workflow/utils.py +0 -0
  36. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil_workflow.egg-info/dependency_links.txt +0 -0
  37. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil_workflow.egg-info/requires.txt +0 -0
  38. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/src/ddeutil_workflow.egg-info/top_level.txt +0 -0
  39. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test__cron.py +0 -0
  40. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test__regex.py +0 -0
  41. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_conf.py +0 -0
  42. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_cron_on.py +0 -0
  43. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_job.py +0 -0
  44. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_job_exec.py +0 -0
  45. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_job_exec_strategy.py +0 -0
  46. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_job_strategy.py +0 -0
  47. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_logs_audit.py +0 -0
  48. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_logs_trace.py +0 -0
  49. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_params.py +0 -0
  50. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_release.py +0 -0
  51. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_release_queue.py +0 -0
  52. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_result.py +0 -0
  53. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_reusables_call_tag.py +0 -0
  54. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_reusables_template.py +0 -0
  55. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_reusables_template_filter.py +0 -0
  56. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_schedule.py +0 -0
  57. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_schedule_pending.py +0 -0
  58. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_schedule_tasks.py +0 -0
  59. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_schedule_workflow.py +0 -0
  60. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_scheduler_control.py +0 -0
  61. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_stage.py +0 -0
  62. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_stage_handler_exec.py +0 -0
  63. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_utils.py +0 -0
  64. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_workflow.py +0 -0
  65. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_workflow_exec_job.py +0 -0
  66. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_workflow_exec_poke.py +0 -0
  67. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_workflow_exec_release.py +0 -0
  68. {ddeutil_workflow-0.0.45 → ddeutil_workflow-0.0.46}/tests/test_workflow_task.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ddeutil-workflow
3
- Version: 0.0.45
3
+ Version: 0.0.46
4
4
  Summary: Lightweight workflow orchestration
5
5
  Author-email: ddeutils <korawich.anu@gmail.com>
6
6
  License: MIT
@@ -9,7 +9,7 @@ Project-URL: Source Code, https://github.com/ddeutils/ddeutil-workflow/
9
9
  Keywords: orchestration,workflow
10
10
  Classifier: Topic :: Utilities
11
11
  Classifier: Natural Language :: English
12
- Classifier: Development Status :: 4 - Beta
12
+ Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Programming Language :: Python
@@ -12,8 +12,7 @@ keywords = ['orchestration', 'workflow']
12
12
  classifiers = [
13
13
  "Topic :: Utilities",
14
14
  "Natural Language :: English",
15
- "Development Status :: 4 - Beta",
16
- # "Development Status :: 5 - Production/Stable",
15
+ "Development Status :: 5 - Production/Stable",
17
16
  "Intended Audience :: Developers",
18
17
  "Operating System :: OS Independent",
19
18
  "Programming Language :: Python",
@@ -0,0 +1 @@
1
+ __version__: str = "0.0.46"
@@ -26,7 +26,10 @@ PREFIX: str = "WORKFLOW"
26
26
 
27
27
 
28
28
  def env(var: str, default: str | None = None) -> str | None: # pragma: no cov
29
- """Get environment variable with uppercase and adding prefix string."""
29
+ """Get environment variable with uppercase and adding prefix string.
30
+
31
+ :rtype: str | None
32
+ """
30
33
  return os.getenv(f"{PREFIX}_{var.upper().replace(' ', '_')}", default)
31
34
 
32
35
 
@@ -42,29 +45,7 @@ __all__: TupleStr = (
42
45
  )
43
46
 
44
47
 
45
- class BaseConfig: # pragma: no cov
46
- """BaseConfig object inheritable."""
47
-
48
- __slots__ = ()
49
-
50
- @property
51
- def root_path(self) -> Path:
52
- """Root path or the project path.
53
-
54
- :rtype: Path
55
- """
56
- return Path(os.getenv("ROOT_PATH", "."))
57
-
58
- @property
59
- def conf_path(self) -> Path:
60
- """Config path that use root_path class argument for this construction.
61
-
62
- :rtype: Path
63
- """
64
- return self.root_path / os.getenv("CONF_PATH", "conf")
65
-
66
-
67
- class Config(BaseConfig): # pragma: no cov
48
+ class Config: # pragma: no cov
68
49
  """Config object for keeping core configurations on the current session
69
50
  without changing when if the application still running.
70
51
 
@@ -217,6 +198,7 @@ class Config(BaseConfig): # pragma: no cov
217
198
 
218
199
 
219
200
  class APIConfig:
201
+ """API Config object."""
220
202
 
221
203
  @property
222
204
  def prefix_path(self) -> str:
@@ -641,6 +641,9 @@ def local_execute_strategy(
641
641
 
642
642
  for stage in job.stages:
643
643
 
644
+ if job.extras:
645
+ stage.extras = job.extras
646
+
644
647
  if stage.is_skipped(params=context):
645
648
  result.trace.info(f"[STAGE]: Skip stage: {stage.iden!r}")
646
649
  stage.set_outputs(output={"skipped": True}, to=context)
@@ -814,6 +814,8 @@ class CallStage(BaseStage):
814
814
  run_id=gen_id(self.name + (self.id or ""), unique=True)
815
815
  )
816
816
 
817
+ print("Extras in CallStage", self.extras)
818
+
817
819
  t_func: TagFunc = extract_call(
818
820
  param2template(self.uses, params, extras=self.extras),
819
821
  registries=self.extras.get("regis_call"),
@@ -976,6 +978,8 @@ class ParallelStage(BaseStage): # pragma: no cov
976
978
  params: DictData,
977
979
  result: Result,
978
980
  stages: list[Stage],
981
+ *,
982
+ extras: DictData | None = None,
979
983
  ) -> DictData:
980
984
  """Task execution method for passing a branch to each thread.
981
985
 
@@ -984,12 +988,16 @@ class ParallelStage(BaseStage): # pragma: no cov
984
988
  :param result: (Result) A result object for keeping context and status
985
989
  data.
986
990
  :param stages:
991
+ :param extras
987
992
 
988
993
  :rtype: DictData
989
994
  """
990
995
  context = {"branch": branch, "stages": {}}
991
996
  result.trace.debug(f"[STAGE]: Execute parallel branch: {branch!r}")
992
997
  for stage in stages:
998
+ if extras:
999
+ stage.extras = extras
1000
+
993
1001
  try:
994
1002
  stage.set_outputs(
995
1003
  stage.handler_execute(
@@ -1048,6 +1056,7 @@ class ParallelStage(BaseStage): # pragma: no cov
1048
1056
  params=params,
1049
1057
  result=result,
1050
1058
  stages=self.parallel[branch],
1059
+ extras=self.extras,
1051
1060
  )
1052
1061
  )
1053
1062
 
@@ -1144,6 +1153,10 @@ class ForEachStage(BaseStage):
1144
1153
  context = {"stages": {}}
1145
1154
 
1146
1155
  for stage in self.stages:
1156
+
1157
+ if self.extras:
1158
+ stage.extras = self.extras
1159
+
1147
1160
  try:
1148
1161
  stage.set_outputs(
1149
1162
  stage.handler_execute(
@@ -1284,6 +1297,9 @@ class CaseStage(BaseStage): # pragma: no cov
1284
1297
 
1285
1298
  if match == _condition:
1286
1299
  stage: Stage = match.stage
1300
+ if self.extras:
1301
+ stage.extras = self.extras
1302
+
1287
1303
  try:
1288
1304
  stage.set_outputs(
1289
1305
  stage.handler_execute(
@@ -1139,7 +1139,7 @@ class Workflow(BaseModel):
1139
1139
  not_timeout_flag := ((time.monotonic() - ts) < timeout)
1140
1140
  ):
1141
1141
  job_id: str = job_queue.get()
1142
- job: Job = self.jobs[job_id]
1142
+ job: Job = self.job(name=job_id)
1143
1143
 
1144
1144
  if (check := job.check_needs(context["jobs"])) == WAIT:
1145
1145
  job_queue.task_done()
@@ -1231,7 +1231,7 @@ class Workflow(BaseModel):
1231
1231
  not_timeout_flag := ((time.monotonic() - ts) < timeout)
1232
1232
  ):
1233
1233
  job_id: str = job_queue.get()
1234
- job: Job = self.jobs[job_id]
1234
+ job: Job = self.job(name=job_id)
1235
1235
 
1236
1236
  if (check := job.check_needs(context["jobs"])) == WAIT:
1237
1237
  job_queue.task_done()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ddeutil-workflow
3
- Version: 0.0.45
3
+ Version: 0.0.46
4
4
  Summary: Lightweight workflow orchestration
5
5
  Author-email: ddeutils <korawich.anu@gmail.com>
6
6
  License: MIT
@@ -9,7 +9,7 @@ Project-URL: Source Code, https://github.com/ddeutils/ddeutil-workflow/
9
9
  Keywords: orchestration,workflow
10
10
  Classifier: Topic :: Utilities
11
11
  Classifier: Natural Language :: English
12
- Classifier: Development Status :: 4 - Beta
12
+ Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Programming Language :: Python
@@ -4,6 +4,7 @@ pyproject.toml
4
4
  src/ddeutil/workflow/__about__.py
5
5
  src/ddeutil/workflow/__cron.py
6
6
  src/ddeutil/workflow/__init__.py
7
+ src/ddeutil/workflow/__main__.py
7
8
  src/ddeutil/workflow/__types.py
8
9
  src/ddeutil/workflow/conf.py
9
10
  src/ddeutil/workflow/cron.py
@@ -1,8 +1,10 @@
1
+ import shutil
1
2
  from datetime import datetime
3
+ from textwrap import dedent
2
4
  from unittest import mock
3
5
 
4
6
  from ddeutil.core import getdot
5
- from ddeutil.workflow import SUCCESS, Workflow
7
+ from ddeutil.workflow import SUCCESS, Workflow, extract_call
6
8
  from ddeutil.workflow.conf import Config
7
9
  from ddeutil.workflow.job import Job
8
10
  from ddeutil.workflow.result import FAILED, Result
@@ -488,6 +490,55 @@ def test_workflow_exec_call(test_path):
488
490
  } == rs.context
489
491
 
490
492
 
493
+ def test_workflow_exec_call_override_registry(test_path):
494
+ task_path = test_path.parent / "mock_tests"
495
+ task_path.mkdir(exist_ok=True)
496
+ (task_path / "__init__.py").open(mode="w")
497
+ (task_path / "mock_tasks").mkdir(exist_ok=True)
498
+
499
+ with (task_path / "mock_tasks/__init__.py").open(mode="w") as f:
500
+ f.write(
501
+ dedent(
502
+ """
503
+ from ddeutil.workflow import tag, Result
504
+
505
+ @tag("v1", alias="get-info")
506
+ def get_info(result: Result):
507
+ result.trace.info("... [CALLER]: Info from mock tasks")
508
+ return {"get-info": "success"}
509
+
510
+ """.strip(
511
+ "\n"
512
+ )
513
+ )
514
+ )
515
+
516
+ with dump_yaml_context(
517
+ test_path / "conf/demo/01_99_wf_test_wf_exec_call_override.yml",
518
+ data="""
519
+ tmp-wf-exec-call-override:
520
+ type: Workflow
521
+ jobs:
522
+ first-job:
523
+ stages:
524
+ - name: "Call from mock tasks"
525
+ uses: mock_tasks/get-info@v1
526
+ """,
527
+ ):
528
+ func = extract_call("mock_tasks/get-info@v1", registries=["mock_tests"])
529
+ assert func().name == "get-info"
530
+
531
+ workflow = Workflow.from_conf(
532
+ name="tmp-wf-exec-call-override",
533
+ extras={"regis_call": ["mock_tests"]},
534
+ )
535
+ rs = workflow.execute(params={})
536
+ assert rs.status == SUCCESS
537
+ print(rs.context)
538
+
539
+ shutil.rmtree(task_path)
540
+
541
+
491
542
  def test_workflow_exec_call_with_prefix(test_path):
492
543
  with dump_yaml_context(
493
544
  test_path / "conf/demo/01_99_wf_test_wf_call_mssql_proc.yml",
@@ -1 +0,0 @@
1
- __version__: str = "0.0.45"