ddeutil-workflow 0.0.3__py3-none-any.whl → 0.0.5__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.
- ddeutil/workflow/__about__.py +1 -1
- ddeutil/workflow/{vendors/__schedule.py → __scheduler.py} +153 -135
- ddeutil/workflow/loader.py +9 -1
- ddeutil/workflow/on.py +143 -0
- ddeutil/workflow/pipeline.py +102 -46
- ddeutil/workflow/tasks/__init__.py +1 -1
- ddeutil/workflow/tasks/dummy.py +52 -0
- ddeutil/workflow/utils.py +33 -5
- {ddeutil_workflow-0.0.3.dist-info → ddeutil_workflow-0.0.5.dist-info}/METADATA +57 -58
- ddeutil_workflow-0.0.5.dist-info/RECORD +17 -0
- {ddeutil_workflow-0.0.3.dist-info → ddeutil_workflow-0.0.5.dist-info}/WHEEL +1 -1
- ddeutil/workflow/conn.py +0 -240
- ddeutil/workflow/schedule.py +0 -82
- ddeutil/workflow/tasks/_pandas.py +0 -54
- ddeutil/workflow/tasks/_polars.py +0 -92
- ddeutil/workflow/vendors/__dataset.py +0 -127
- ddeutil/workflow/vendors/__dict.py +0 -333
- ddeutil/workflow/vendors/__init__.py +0 -0
- ddeutil/workflow/vendors/aws.py +0 -185
- ddeutil/workflow/vendors/az.py +0 -0
- ddeutil/workflow/vendors/minio.py +0 -11
- ddeutil/workflow/vendors/pd.py +0 -13
- ddeutil/workflow/vendors/pg.py +0 -11
- ddeutil/workflow/vendors/pl.py +0 -172
- ddeutil/workflow/vendors/sftp.py +0 -209
- ddeutil_workflow-0.0.3.dist-info/RECORD +0 -29
- {ddeutil_workflow-0.0.3.dist-info → ddeutil_workflow-0.0.5.dist-info}/LICENSE +0 -0
- {ddeutil_workflow-0.0.3.dist-info → ddeutil_workflow-0.0.5.dist-info}/top_level.txt +0 -0
ddeutil/workflow/__about__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__: str = "0.0.
|
1
|
+
__version__: str = "0.0.5"
|
@@ -7,10 +7,10 @@ from __future__ import annotations
|
|
7
7
|
|
8
8
|
import copy
|
9
9
|
from collections.abc import Iterator
|
10
|
+
from dataclasses import dataclass, field
|
10
11
|
from datetime import datetime, timedelta, timezone
|
11
12
|
from functools import partial, total_ordering
|
12
13
|
from typing import (
|
13
|
-
Any,
|
14
14
|
Callable,
|
15
15
|
Optional,
|
16
16
|
Union,
|
@@ -37,31 +37,55 @@ WEEKDAYS: dict[str, int] = {
|
|
37
37
|
"Sat": 6,
|
38
38
|
}
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
40
|
+
|
41
|
+
@dataclass(frozen=True)
|
42
|
+
class Unit:
|
43
|
+
name: str
|
44
|
+
range: partial
|
45
|
+
min: int
|
46
|
+
max: int
|
47
|
+
alt: list[str] = field(default_factory=list)
|
48
|
+
|
49
|
+
def __repr__(self) -> str:
|
50
|
+
return (
|
51
|
+
f"{self.__class__}(name={self.name!r}, range={self.range},"
|
52
|
+
f"min={self.min}, max={self.max}"
|
53
|
+
f"{f', alt={self.alt}' if self.alt else ''})"
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
@dataclass
|
58
|
+
class Options:
|
59
|
+
output_weekday_names: bool = False
|
60
|
+
output_month_names: bool = False
|
61
|
+
output_hashes: bool = False
|
62
|
+
|
63
|
+
|
64
|
+
CRON_UNITS: tuple[Unit, ...] = (
|
65
|
+
Unit(
|
66
|
+
name="minute",
|
67
|
+
range=partial(range, 0, 60),
|
68
|
+
min=0,
|
69
|
+
max=59,
|
70
|
+
),
|
71
|
+
Unit(
|
72
|
+
name="hour",
|
73
|
+
range=partial(range, 0, 24),
|
74
|
+
min=0,
|
75
|
+
max=23,
|
76
|
+
),
|
77
|
+
Unit(
|
78
|
+
name="day",
|
79
|
+
range=partial(range, 1, 32),
|
80
|
+
min=1,
|
81
|
+
max=31,
|
82
|
+
),
|
83
|
+
Unit(
|
84
|
+
name="month",
|
85
|
+
range=partial(range, 1, 13),
|
86
|
+
min=1,
|
87
|
+
max=12,
|
88
|
+
alt=[
|
65
89
|
"JAN",
|
66
90
|
"FEB",
|
67
91
|
"MAR",
|
@@ -75,13 +99,13 @@ CRON_UNITS: tuple[dict[str, Any], ...] = (
|
|
75
99
|
"NOV",
|
76
100
|
"DEC",
|
77
101
|
],
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
102
|
+
),
|
103
|
+
Unit(
|
104
|
+
name="weekday",
|
105
|
+
range=partial(range, 0, 7),
|
106
|
+
min=0,
|
107
|
+
max=6,
|
108
|
+
alt=[
|
85
109
|
"SUN",
|
86
110
|
"MON",
|
87
111
|
"TUE",
|
@@ -90,16 +114,16 @@ CRON_UNITS: tuple[dict[str, Any], ...] = (
|
|
90
114
|
"FRI",
|
91
115
|
"SAT",
|
92
116
|
],
|
93
|
-
|
117
|
+
),
|
94
118
|
)
|
95
119
|
|
96
|
-
CRON_UNITS_AWS: tuple = CRON_UNITS + (
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
120
|
+
CRON_UNITS_AWS: tuple[Unit, ...] = CRON_UNITS + (
|
121
|
+
Unit(
|
122
|
+
name="year",
|
123
|
+
range=partial(range, 1990, 2101),
|
124
|
+
min=1990,
|
125
|
+
max=2100,
|
126
|
+
),
|
103
127
|
)
|
104
128
|
|
105
129
|
|
@@ -115,31 +139,54 @@ class CronPart:
|
|
115
139
|
|
116
140
|
def __init__(
|
117
141
|
self,
|
118
|
-
unit:
|
119
|
-
values:
|
120
|
-
options:
|
121
|
-
):
|
122
|
-
self.unit:
|
123
|
-
self.options:
|
142
|
+
unit: Unit,
|
143
|
+
values: str | list[int],
|
144
|
+
options: Options,
|
145
|
+
) -> None:
|
146
|
+
self.unit: Unit = unit
|
147
|
+
self.options: Options = options
|
148
|
+
|
124
149
|
if isinstance(values, str):
|
125
150
|
values: list[int] = self.from_str(values) if values != "?" else []
|
126
151
|
elif isinstance_check(values, list[int]):
|
127
152
|
values: list[int] = self.replace_weekday(values)
|
128
153
|
else:
|
129
154
|
raise TypeError(f"Invalid type of value in cron part: {values}.")
|
130
|
-
|
155
|
+
self.values: list[int] = self.out_of_range(
|
131
156
|
sorted(dict.fromkeys(values))
|
132
157
|
)
|
133
|
-
self.values: list[int] = unique_values
|
134
158
|
|
135
159
|
def __str__(self) -> str:
|
136
|
-
"""
|
137
|
-
|
160
|
+
"""Generate String value from part of cronjob."""
|
161
|
+
_hash: str = "H" if self.options.output_hashes else "*"
|
162
|
+
|
163
|
+
if self.is_full:
|
164
|
+
return _hash
|
165
|
+
|
166
|
+
if self.is_interval:
|
167
|
+
if self.is_full_interval:
|
168
|
+
return f"{_hash}/{self.step}"
|
169
|
+
_hash: str = (
|
170
|
+
f"H({self.filler(self.min)}-{self.filler(self.max)})"
|
171
|
+
if _hash == "H"
|
172
|
+
else f"{self.filler(self.min)}-{self.filler(self.max)}"
|
173
|
+
)
|
174
|
+
return f"{_hash}/{self.step}"
|
175
|
+
|
176
|
+
cron_range_strings: list[str] = []
|
177
|
+
for cron_range in self.ranges():
|
178
|
+
if isinstance(cron_range, list):
|
179
|
+
cron_range_strings.append(
|
180
|
+
f"{self.filler(cron_range[0])}-{self.filler(cron_range[1])}"
|
181
|
+
)
|
182
|
+
else:
|
183
|
+
cron_range_strings.append(f"{self.filler(cron_range)}")
|
184
|
+
return ",".join(cron_range_strings) if cron_range_strings else "?"
|
138
185
|
|
139
|
-
def __repr__(self):
|
186
|
+
def __repr__(self) -> str:
|
140
187
|
return (
|
141
188
|
f"{self.__class__.__name__}"
|
142
|
-
f"(unit={self.unit}, values={self.
|
189
|
+
f"(unit={self.unit}, values={self.__str__()!r})"
|
143
190
|
)
|
144
191
|
|
145
192
|
def __lt__(self, other) -> bool:
|
@@ -148,10 +195,6 @@ class CronPart:
|
|
148
195
|
def __eq__(self, other) -> bool:
|
149
196
|
return self.values == other.values
|
150
197
|
|
151
|
-
@property
|
152
|
-
def is_weekday(self) -> bool:
|
153
|
-
return self.unit["name"] == "weekday"
|
154
|
-
|
155
198
|
@property
|
156
199
|
def min(self) -> int:
|
157
200
|
"""Returns the smallest value in the range."""
|
@@ -176,15 +219,13 @@ class CronPart:
|
|
176
219
|
@property
|
177
220
|
def is_full(self) -> bool:
|
178
221
|
"""Returns true if range has all the values of the unit."""
|
179
|
-
return len(self.values) == (
|
180
|
-
self.unit.get("max") - self.unit.get("min") + 1
|
181
|
-
)
|
222
|
+
return len(self.values) == (self.unit.max - self.unit.min + 1)
|
182
223
|
|
183
224
|
def from_str(self, value: str) -> tuple[int, ...]:
|
184
225
|
"""Parses a string as a range of positive integers. The string should
|
185
226
|
include only `-` and `,` special strings.
|
186
227
|
|
187
|
-
:param value:
|
228
|
+
:param value: A string value
|
188
229
|
:type value: str
|
189
230
|
|
190
231
|
TODO: support for `L`, `W`, and `#`
|
@@ -247,7 +288,7 @@ class CronPart:
|
|
247
288
|
if (value_step and not is_int(value_step)) or value_step == "":
|
248
289
|
raise ValueError(
|
249
290
|
f"Invalid interval step value {value_step!r} for "
|
250
|
-
f
|
291
|
+
f"{self.unit.name!r}"
|
251
292
|
)
|
252
293
|
|
253
294
|
interval_list.append(self._interval(value_range_list, value_step))
|
@@ -255,16 +296,14 @@ class CronPart:
|
|
255
296
|
|
256
297
|
def replace_alternative(self, value: str) -> str:
|
257
298
|
"""Replaces the alternative representations of numbers in a string."""
|
258
|
-
for i, alt in enumerate(self.unit.
|
299
|
+
for i, alt in enumerate(self.unit.alt):
|
259
300
|
if alt in value:
|
260
|
-
value: str = value.replace(alt, str(self.unit
|
301
|
+
value: str = value.replace(alt, str(self.unit.min + i))
|
261
302
|
return value
|
262
303
|
|
263
|
-
def replace_weekday(
|
264
|
-
self, values: Union[list[int], Iterator[int]]
|
265
|
-
) -> list[int]:
|
304
|
+
def replace_weekday(self, values: list[int] | Iterator[int]) -> list[int]:
|
266
305
|
"""Replaces all 7 with 0 as Sunday can be represented by both."""
|
267
|
-
if self.
|
306
|
+
if self.unit.name == "weekday":
|
268
307
|
return [0 if value == 7 else value for value in values]
|
269
308
|
return list(values)
|
270
309
|
|
@@ -277,20 +316,20 @@ class CronPart:
|
|
277
316
|
:rtype: list[int]
|
278
317
|
"""
|
279
318
|
if values:
|
280
|
-
if (first := values[0]) < self.unit
|
319
|
+
if (first := values[0]) < self.unit.min:
|
281
320
|
raise ValueError(
|
282
|
-
f
|
321
|
+
f"Value {first!r} out of range for {self.unit.name!r}"
|
283
322
|
)
|
284
|
-
elif (last := values[-1]) > self.unit
|
323
|
+
elif (last := values[-1]) > self.unit.max:
|
285
324
|
raise ValueError(
|
286
|
-
f
|
325
|
+
f"Value {last!r} out of range for {self.unit.name!r}"
|
287
326
|
)
|
288
327
|
return values
|
289
328
|
|
290
329
|
def _parse_range(self, value: str) -> list[int]:
|
291
330
|
"""Parses a range string."""
|
292
331
|
if value == "*":
|
293
|
-
return list(self.unit
|
332
|
+
return list(self.unit.range())
|
294
333
|
elif value.count("-") > 1:
|
295
334
|
raise ValueError(f"Invalid value {value}")
|
296
335
|
try:
|
@@ -306,7 +345,9 @@ class CronPart:
|
|
306
345
|
return self.replace_weekday(sub_parts)
|
307
346
|
|
308
347
|
def _interval(
|
309
|
-
self,
|
348
|
+
self,
|
349
|
+
values: list[int],
|
350
|
+
step: int | None = None,
|
310
351
|
) -> list[int]:
|
311
352
|
"""Applies an interval step to a collection of values."""
|
312
353
|
if not step:
|
@@ -314,7 +355,7 @@ class CronPart:
|
|
314
355
|
elif (_step := int(step)) < 1:
|
315
356
|
raise ValueError(
|
316
357
|
f"Invalid interval step value {_step!r} for "
|
317
|
-
f
|
358
|
+
f"{self.unit.name!r}"
|
318
359
|
)
|
319
360
|
min_value: int = values[0]
|
320
361
|
return [
|
@@ -340,8 +381,8 @@ class CronPart:
|
|
340
381
|
"""Returns true if the range contains all the interval values."""
|
341
382
|
if step := self.step:
|
342
383
|
return (
|
343
|
-
self.min == self.unit
|
344
|
-
and (self.max + step) > self.unit
|
384
|
+
self.min == self.unit.min
|
385
|
+
and (self.max + step) > self.unit.max
|
345
386
|
and (
|
346
387
|
len(self.values)
|
347
388
|
== (round((self.max - self.min) / step) + 1)
|
@@ -376,33 +417,6 @@ class CronPart:
|
|
376
417
|
start_number: Optional[int] = value
|
377
418
|
return multi_dim_values
|
378
419
|
|
379
|
-
def to_str(self) -> str:
|
380
|
-
"""Returns the cron range as a string value."""
|
381
|
-
_hash: str = "H" if self.options.get("output_hashes") else "*"
|
382
|
-
|
383
|
-
if self.is_full:
|
384
|
-
return _hash
|
385
|
-
|
386
|
-
if self.is_interval:
|
387
|
-
if self.is_full_interval:
|
388
|
-
return f"{_hash}/{self.step}"
|
389
|
-
_hash: str = (
|
390
|
-
f"H({self.filler(self.min)}-{self.filler(self.max)})"
|
391
|
-
if _hash == "H"
|
392
|
-
else f"{self.filler(self.min)}-{self.filler(self.max)}"
|
393
|
-
)
|
394
|
-
return f"{_hash}/{self.step}"
|
395
|
-
|
396
|
-
cron_range_strings: list[str] = []
|
397
|
-
for cron_range in self.ranges():
|
398
|
-
if isinstance(cron_range, list):
|
399
|
-
cron_range_strings.append(
|
400
|
-
f"{self.filler(cron_range[0])}-{self.filler(cron_range[1])}"
|
401
|
-
)
|
402
|
-
else:
|
403
|
-
cron_range_strings.append(f"{self.filler(cron_range)}")
|
404
|
-
return ",".join(cron_range_strings) if cron_range_strings else "?"
|
405
|
-
|
406
420
|
def filler(self, value: int) -> int | str:
|
407
421
|
"""Formats weekday and month names as string when the relevant options
|
408
422
|
are set.
|
@@ -413,15 +427,15 @@ class CronPart:
|
|
413
427
|
:rtype: int | str
|
414
428
|
"""
|
415
429
|
return (
|
416
|
-
self.unit
|
430
|
+
self.unit.alt[value - self.unit.min]
|
417
431
|
if (
|
418
432
|
(
|
419
|
-
self.options
|
420
|
-
and self.unit
|
433
|
+
self.options.output_weekday_names
|
434
|
+
and self.unit.name == "weekday"
|
421
435
|
)
|
422
436
|
or (
|
423
|
-
self.options
|
424
|
-
and self.unit
|
437
|
+
self.options.output_month_names
|
438
|
+
and self.unit.name == "month"
|
425
439
|
)
|
426
440
|
)
|
427
441
|
else value
|
@@ -433,7 +447,7 @@ class CronJob:
|
|
433
447
|
"""The Cron Job Converter object that generate datetime dimension of cron
|
434
448
|
job schedule format,
|
435
449
|
|
436
|
-
* * * * * <command to execute>
|
450
|
+
... * * * * * <command to execute>
|
437
451
|
|
438
452
|
(i) minute (0 - 59)
|
439
453
|
(ii) hour (0 - 23)
|
@@ -447,25 +461,20 @@ class CronJob:
|
|
447
461
|
Support special value with `/`, `*`, `-`, `,`, and `?` (in day of month
|
448
462
|
and day of week value).
|
449
463
|
|
450
|
-
:
|
464
|
+
References:
|
451
465
|
- https://github.com/Sonic0/cron-converter
|
452
466
|
- https://pypi.org/project/python-crontab/
|
453
467
|
"""
|
454
468
|
|
455
469
|
cron_length: int = 5
|
456
|
-
|
457
|
-
options_defaults: dict[str, bool] = {
|
458
|
-
"output_weekday_names": False,
|
459
|
-
"output_month_names": False,
|
460
|
-
"output_hashes": False,
|
461
|
-
}
|
470
|
+
cron_units: tuple[Unit, ...] = CRON_UNITS
|
462
471
|
|
463
472
|
def __init__(
|
464
473
|
self,
|
465
474
|
value: Union[list[list[int]], str],
|
466
475
|
*,
|
467
476
|
option: Optional[dict[str, bool]] = None,
|
468
|
-
):
|
477
|
+
) -> None:
|
469
478
|
if isinstance(value, str):
|
470
479
|
value: list[str] = value.strip().split()
|
471
480
|
elif not isinstance_check(value, list[list[int]]):
|
@@ -473,16 +482,22 @@ class CronJob:
|
|
473
482
|
f"{self.__class__.__name__} cron value does not support "
|
474
483
|
f"type: {type(value)}."
|
475
484
|
)
|
485
|
+
|
486
|
+
# NOTE: Validate length of crontab of this class.
|
476
487
|
if len(value) != self.cron_length:
|
477
488
|
raise ValueError(
|
478
489
|
f"Invalid cron value does not have length equal "
|
479
490
|
f"{self.cron_length}: {value}."
|
480
491
|
)
|
481
|
-
self.
|
482
|
-
|
483
|
-
|
484
|
-
|
492
|
+
self.options: Options = Options(**(option or {}))
|
493
|
+
|
494
|
+
# NOTE: Start initial crontab for each part
|
495
|
+
self.parts: list[CronPart] = [
|
496
|
+
CronPart(unit, values=item, options=self.options)
|
497
|
+
for item, unit in zip(value, self.cron_units)
|
485
498
|
]
|
499
|
+
|
500
|
+
# NOTE: Validate values of `day` and `dow` from parts.
|
486
501
|
if self.day == self.dow == []:
|
487
502
|
raise ValueError(
|
488
503
|
"Invalid cron value when set the `?` on day of month and "
|
@@ -490,12 +505,13 @@ class CronJob:
|
|
490
505
|
)
|
491
506
|
|
492
507
|
def __str__(self) -> str:
|
493
|
-
|
508
|
+
"""Return joining with space of each value in parts."""
|
509
|
+
return " ".join(str(part) for part in self.parts)
|
494
510
|
|
495
511
|
def __repr__(self) -> str:
|
496
512
|
return (
|
497
513
|
f"{self.__class__.__name__}(value={self.__str__()!r}, "
|
498
|
-
f"option={self.
|
514
|
+
f"option={self.options.__dict__})"
|
499
515
|
)
|
500
516
|
|
501
517
|
def __lt__(self, other) -> bool:
|
@@ -510,10 +526,6 @@ class CronJob:
|
|
510
526
|
for part, other_part in zip(self.parts, other.parts)
|
511
527
|
)
|
512
528
|
|
513
|
-
@property
|
514
|
-
def parts(self) -> list[CronPart]:
|
515
|
-
return self._parts
|
516
|
-
|
517
529
|
@property
|
518
530
|
def parts_order(self) -> Iterator[CronPart]:
|
519
531
|
return reversed(self.parts[:3] + [self.parts[4], self.parts[3]])
|
@@ -521,31 +533,31 @@ class CronJob:
|
|
521
533
|
@property
|
522
534
|
def minute(self):
|
523
535
|
"""Return part of minute."""
|
524
|
-
return self.
|
536
|
+
return self.parts[0]
|
525
537
|
|
526
538
|
@property
|
527
539
|
def hour(self):
|
528
540
|
"""Return part of hour."""
|
529
|
-
return self.
|
541
|
+
return self.parts[1]
|
530
542
|
|
531
543
|
@property
|
532
544
|
def day(self):
|
533
545
|
"""Return part of day."""
|
534
|
-
return self.
|
546
|
+
return self.parts[2]
|
535
547
|
|
536
548
|
@property
|
537
549
|
def month(self):
|
538
550
|
"""Return part of month."""
|
539
|
-
return self.
|
551
|
+
return self.parts[3]
|
540
552
|
|
541
553
|
@property
|
542
554
|
def dow(self):
|
543
555
|
"""Return part of day of month."""
|
544
|
-
return self.
|
556
|
+
return self.parts[4]
|
545
557
|
|
546
558
|
def to_list(self) -> list[list[int]]:
|
547
559
|
"""Returns the cron schedule as a 2-dimensional list of integers."""
|
548
|
-
return [part.values for part in self.
|
560
|
+
return [part.values for part in self.parts]
|
549
561
|
|
550
562
|
def schedule(
|
551
563
|
self, date: Optional[datetime] = None, _tz: Optional[str] = None
|
@@ -554,6 +566,11 @@ class CronJob:
|
|
554
566
|
return CronRunner(self, date, tz_str=_tz)
|
555
567
|
|
556
568
|
|
569
|
+
class CronJobAWS(CronJob):
|
570
|
+
cron_length = 6
|
571
|
+
cron_units = CRON_UNITS_AWS
|
572
|
+
|
573
|
+
|
557
574
|
class CronRunner:
|
558
575
|
"""Create an instance of Date Runner object for datetime generate with
|
559
576
|
cron schedule object value.
|
@@ -661,7 +678,8 @@ class CronRunner:
|
|
661
678
|
return False
|
662
679
|
|
663
680
|
|
664
|
-
__all__
|
681
|
+
__all__ = (
|
665
682
|
"CronJob",
|
666
683
|
"CronRunner",
|
684
|
+
"WEEKDAYS",
|
667
685
|
)
|
ddeutil/workflow/loader.py
CHANGED
@@ -37,6 +37,9 @@ class Engine(BaseModel):
|
|
37
37
|
|
38
38
|
@model_validator(mode="before")
|
39
39
|
def __prepare_registry(cls, values: DictData) -> DictData:
|
40
|
+
"""Prepare registry value that passing with string type. It convert the
|
41
|
+
string type to list of string.
|
42
|
+
"""
|
40
43
|
if (_regis := values.get("registry")) and isinstance(_regis, str):
|
41
44
|
values["registry"] = [_regis]
|
42
45
|
return values
|
@@ -83,7 +86,9 @@ class SimLoad:
|
|
83
86
|
|
84
87
|
@cached_property
|
85
88
|
def type(self) -> BaseModelType:
|
86
|
-
"""Return object type which implement
|
89
|
+
"""Return object of string type which implement on any registry. The
|
90
|
+
object type
|
91
|
+
"""
|
87
92
|
if not (_typ := self.data.get("type")):
|
88
93
|
raise ValueError(
|
89
94
|
f"the 'type' value: {_typ} does not exists in config data."
|
@@ -100,6 +105,9 @@ class SimLoad:
|
|
100
105
|
return import_string(f"{_typ}")
|
101
106
|
|
102
107
|
def load(self) -> AnyModel:
|
108
|
+
"""Parsing config data to the object type for initialize with model
|
109
|
+
validate method.
|
110
|
+
"""
|
103
111
|
return self.type.model_validate(self.data)
|
104
112
|
|
105
113
|
|