ddeutil-workflow 0.0.40__py3-none-any.whl → 0.0.41__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.
@@ -1 +1 @@
1
- __version__: str = "0.0.40"
1
+ __version__: str = "0.0.41"
@@ -5,17 +5,6 @@
5
5
  # ------------------------------------------------------------------------------
6
6
  from .__cron import CronJob, CronRunner
7
7
  from .__types import Re
8
- from .audit import (
9
- Audit,
10
- get_audit,
11
- )
12
- from .caller import (
13
- ReturnTagFunc,
14
- TagFunc,
15
- extract_call,
16
- make_registry,
17
- tag,
18
- )
19
8
  from .conf import (
20
9
  Config,
21
10
  Loader,
@@ -43,8 +32,10 @@ from .job import (
43
32
  local_execute_strategy,
44
33
  )
45
34
  from .logs import (
35
+ Audit,
46
36
  TraceData,
47
37
  TraceLog,
38
+ get_audit,
48
39
  get_dt_tznow,
49
40
  get_trace,
50
41
  )
@@ -58,7 +49,24 @@ from .params import (
58
49
  from .result import (
59
50
  Result,
60
51
  Status,
61
- default_gen_id,
52
+ )
53
+ from .reusables import (
54
+ FILTERS,
55
+ FilterFunc,
56
+ FilterRegistry,
57
+ ReturnTagFunc,
58
+ TagFunc,
59
+ custom_filter,
60
+ extract_call,
61
+ get_args_const,
62
+ has_template,
63
+ make_filter_registry,
64
+ make_registry,
65
+ map_post_filter,
66
+ not_in_template,
67
+ param2template,
68
+ str2template,
69
+ tag,
62
70
  )
63
71
  from .scheduler import (
64
72
  Schedule,
@@ -77,22 +85,10 @@ from .stages import (
77
85
  Stage,
78
86
  TriggerStage,
79
87
  )
80
- from .templates import (
81
- FILTERS,
82
- FilterFunc,
83
- FilterRegistry,
84
- custom_filter,
85
- get_args_const,
86
- has_template,
87
- make_filter_registry,
88
- map_post_filter,
89
- not_in_template,
90
- param2template,
91
- str2template,
92
- )
93
88
  from .utils import (
94
89
  batch,
95
90
  cross_product,
91
+ default_gen_id,
96
92
  delay,
97
93
  filter_func,
98
94
  gen_id,
@@ -109,7 +109,7 @@ if config.enable_route_workflow:
109
109
 
110
110
  # NOTE: Enable the schedules route.
111
111
  if config.enable_route_schedule:
112
- from ..audit import get_audit
112
+ from ..logs import get_audit
113
113
  from ..scheduler import schedule_task
114
114
  from .routes import schedule
115
115
 
@@ -10,8 +10,7 @@ from fastapi import APIRouter, Path, Query
10
10
  from fastapi import status as st
11
11
  from fastapi.responses import UJSONResponse
12
12
 
13
- from ...audit import get_audit
14
- from ...logs import get_trace_obj
13
+ from ...logs import get_audit, get_trace_obj
15
14
 
16
15
  log_route = APIRouter(
17
16
  prefix="/logs",
@@ -15,8 +15,8 @@ from fastapi.responses import UJSONResponse
15
15
  from pydantic import BaseModel
16
16
 
17
17
  from ...__types import DictData
18
- from ...audit import Audit, get_audit
19
18
  from ...conf import Loader, get_logger
19
+ from ...logs import Audit, get_audit
20
20
  from ...result import Result
21
21
  from ...workflow import Workflow
22
22
 
ddeutil/workflow/conf.py CHANGED
@@ -24,6 +24,7 @@ PREFIX: str = "WORKFLOW"
24
24
 
25
25
 
26
26
  def env(var: str, default: str | None = None) -> str | None: # pragma: no cov
27
+ """Get environment variable with uppercase and adding prefix string."""
27
28
  return os.getenv(f"{PREFIX}_{var.upper().replace(' ', '_')}", default)
28
29
 
29
30
 
@@ -94,11 +95,19 @@ class Config(BaseConfig): # pragma: no cov
94
95
  # NOTE: Register
95
96
  @property
96
97
  def regis_call(self) -> list[str]:
98
+ """Register Caller module importer str.
99
+
100
+ :rtype: list[str]
101
+ """
97
102
  regis_call_str: str = env("CORE_REGISTRY", ".")
98
103
  return [r.strip() for r in regis_call_str.split(",")]
99
104
 
100
105
  @property
101
106
  def regis_filter(self) -> list[str]:
107
+ """Register Filter module.
108
+
109
+ :rtype: list[str]
110
+ """
102
111
  regis_filter_str: str = env(
103
112
  "CORE_REGISTRY_FILTER", "ddeutil.workflow.templates"
104
113
  )
@@ -326,7 +335,8 @@ class SimLoad:
326
335
  def filter_yaml(cls, file: Path, name: str | None = None) -> DictData:
327
336
  if any(file.suffix.endswith(s) for s in (".yml", ".yaml")):
328
337
  values: DictData = YamlFlResolve(file).read()
329
- return values.get(name, {}) if name else values
338
+ if values is not None:
339
+ return values.get(name, {}) if name else values
330
340
  return {}
331
341
 
332
342
  @cached_property
ddeutil/workflow/job.py CHANGED
@@ -39,8 +39,8 @@ from .exceptions import (
39
39
  UtilException,
40
40
  )
41
41
  from .result import Result, Status
42
+ from .reusables import has_template, param2template
42
43
  from .stages import Stage
43
- from .templates import has_template, param2template
44
44
  from .utils import cross_product, filter_func, gen_id
45
45
 
46
46
  MatrixFilter = list[dict[str, Union[str, int]]]
@@ -344,6 +344,10 @@ class Job(BaseModel):
344
344
  default_factory=Strategy,
345
345
  description="A strategy matrix that want to generate.",
346
346
  )
347
+ extras: DictData = Field(
348
+ default_factory=dict,
349
+ description="An extra override values.",
350
+ )
347
351
 
348
352
  @field_validator("desc", mode="after")
349
353
  def ___prepare_desc__(cls, value: str) -> str:
@@ -394,6 +398,8 @@ class Job(BaseModel):
394
398
  """
395
399
  for stage in self.stages:
396
400
  if stage_id == (stage.id or ""):
401
+ if self.extras:
402
+ stage.extras = self.extras
397
403
  return stage
398
404
  raise ValueError(f"Stage ID {stage_id} does not exists")
399
405
 
@@ -596,7 +602,7 @@ def local_execute_strategy(
596
602
  *,
597
603
  result: Result | None = None,
598
604
  event: Event | None = None,
599
- raise_error: bool = False,
605
+ raise_error: bool | None = None,
600
606
  ) -> Result:
601
607
  """Local job strategy execution with passing dynamic parameters from the
602
608
  workflow execution to strategy matrix.
@@ -694,12 +700,16 @@ def local_execute_strategy(
694
700
  params=context,
695
701
  run_id=result.run_id,
696
702
  parent_run_id=result.parent_run_id,
703
+ event=event,
697
704
  ).context,
698
705
  to=context,
699
706
  )
700
707
  except (StageException, UtilException) as err:
701
708
  result.trace.error(f"[JOB]: {err.__class__.__name__}: {err}")
702
- if raise_error or config.job_raise_error:
709
+ do_raise: bool = (
710
+ config.job_raise_error if raise_error is None else raise_error
711
+ )
712
+ if do_raise:
703
713
  raise JobException(
704
714
  f"Stage execution error: {err.__class__.__name__}: "
705
715
  f"{err}"
@@ -735,7 +745,7 @@ def local_execute(
735
745
  parent_run_id: str | None = None,
736
746
  result: Result | None = None,
737
747
  event: Event | None = None,
738
- raise_error: bool = False,
748
+ raise_error: bool | None = None,
739
749
  ) -> Result:
740
750
  """Local job execution with passing dynamic parameters from the workflow
741
751
  execution. It will generate matrix values at the first step and run
@@ -865,3 +875,44 @@ def local_execute(
865
875
  context.update({"errors": err.to_dict()})
866
876
 
867
877
  return result.catch(status=status, context=context)
878
+
879
+
880
+ def self_hosted_execute(
881
+ job: Job,
882
+ params: DictData,
883
+ *,
884
+ run_id: str | None = None,
885
+ parent_run_id: str | None = None,
886
+ result: Result | None = None,
887
+ event: Event | None = None,
888
+ raise_error: bool | None = None,
889
+ ) -> Result: # pragma: no cov
890
+ result: Result = Result.construct_with_rs_or_id(
891
+ result,
892
+ run_id=run_id,
893
+ parent_run_id=parent_run_id,
894
+ id_logic=(job.id or "not-set"),
895
+ )
896
+
897
+ if event and event.is_set():
898
+ return result.catch(status=Status.FAILED)
899
+
900
+ import requests
901
+
902
+ resp = requests.post(
903
+ job.runs_on.args.host,
904
+ data={"job": job.model_dump(), "params": params},
905
+ )
906
+
907
+ if resp.status_code != 200:
908
+ do_raise: bool = (
909
+ config.job_raise_error if raise_error is None else raise_error
910
+ )
911
+ if do_raise:
912
+ raise JobException(
913
+ f"Job execution error from request to self-hosted: "
914
+ f"{job.runs_on.args.host!r}"
915
+ )
916
+
917
+ return result.catch(status=Status.FAILED)
918
+ return result.catch(status=Status.SUCCESS)