ddeutil-workflow 0.0.47__py3-none-any.whl → 0.0.49__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/__init__.py +4 -2
- ddeutil/workflow/api/api.py +2 -1
- ddeutil/workflow/api/repeat.py +2 -1
- ddeutil/workflow/api/routes/job.py +1 -1
- ddeutil/workflow/api/routes/logs.py +6 -5
- ddeutil/workflow/api/routes/schedules.py +2 -1
- ddeutil/workflow/api/routes/workflows.py +2 -2
- ddeutil/workflow/conf.py +61 -66
- ddeutil/workflow/job.py +13 -5
- ddeutil/workflow/logs.py +282 -105
- ddeutil/workflow/result.py +19 -8
- ddeutil/workflow/reusables.py +4 -5
- ddeutil/workflow/scheduler.py +70 -50
- ddeutil/workflow/stages.py +288 -83
- ddeutil/workflow/utils.py +3 -3
- ddeutil/workflow/workflow.py +135 -103
- {ddeutil_workflow-0.0.47.dist-info → ddeutil_workflow-0.0.49.dist-info}/METADATA +24 -26
- ddeutil_workflow-0.0.49.dist-info/RECORD +31 -0
- ddeutil_workflow-0.0.47.dist-info/RECORD +0 -31
- {ddeutil_workflow-0.0.47.dist-info → ddeutil_workflow-0.0.49.dist-info}/WHEEL +0 -0
- {ddeutil_workflow-0.0.47.dist-info → ddeutil_workflow-0.0.49.dist-info}/licenses/LICENSE +0 -0
- {ddeutil_workflow-0.0.47.dist-info → ddeutil_workflow-0.0.49.dist-info}/top_level.txt +0 -0
ddeutil/workflow/workflow.py
CHANGED
@@ -3,8 +3,10 @@
|
|
3
3
|
# Licensed under the MIT License. See LICENSE in the project root for
|
4
4
|
# license information.
|
5
5
|
# ------------------------------------------------------------------------------
|
6
|
-
# [x] Use dynamic config
|
7
|
-
"""A Workflow module that is the core
|
6
|
+
# [x] Use dynamic config
|
7
|
+
"""A Workflow module that is the core module of this package. It keeps Release
|
8
|
+
and Workflow Pydantic models.
|
9
|
+
"""
|
8
10
|
from __future__ import annotations
|
9
11
|
|
10
12
|
import copy
|
@@ -32,7 +34,7 @@ from typing_extensions import Self
|
|
32
34
|
|
33
35
|
from .__cron import CronJob, CronRunner
|
34
36
|
from .__types import DictData, TupleStr
|
35
|
-
from .conf import Loader, SimLoad, dynamic
|
37
|
+
from .conf import Loader, SimLoad, dynamic
|
36
38
|
from .cron import On
|
37
39
|
from .exceptions import JobException, WorkflowException
|
38
40
|
from .job import Job
|
@@ -47,8 +49,6 @@ from .utils import (
|
|
47
49
|
wait_to_next_minute,
|
48
50
|
)
|
49
51
|
|
50
|
-
logger = get_logger("ddeutil.workflow")
|
51
|
-
|
52
52
|
__all__: TupleStr = (
|
53
53
|
"Release",
|
54
54
|
"ReleaseQueue",
|
@@ -75,10 +75,10 @@ class Release:
|
|
75
75
|
that use with the `workflow.release` method.
|
76
76
|
"""
|
77
77
|
|
78
|
-
date: datetime
|
79
|
-
offset: float
|
80
|
-
end_date: datetime
|
81
|
-
runner: CronRunner
|
78
|
+
date: datetime
|
79
|
+
offset: float
|
80
|
+
end_date: datetime
|
81
|
+
runner: CronRunner
|
82
82
|
type: ReleaseType = field(default=ReleaseType.DEFAULT)
|
83
83
|
|
84
84
|
def __repr__(self) -> str:
|
@@ -94,14 +94,14 @@ class Release:
|
|
94
94
|
|
95
95
|
@classmethod
|
96
96
|
def from_dt(
|
97
|
-
cls, dt: datetime | str, *,
|
97
|
+
cls, dt: datetime | str, *, extras: Optional[DictData] = None
|
98
98
|
) -> Self:
|
99
99
|
"""Construct Release via datetime object only.
|
100
100
|
|
101
101
|
:param dt: (datetime | str) A datetime object or string that want to
|
102
102
|
construct to the Release object.
|
103
|
-
:param
|
104
|
-
config.
|
103
|
+
:param extras: (DictData) An extra parameters that want to pass to
|
104
|
+
override config values.
|
105
105
|
|
106
106
|
:raise TypeError: If the type of the dt argument does not valid with
|
107
107
|
datetime or str object.
|
@@ -120,8 +120,10 @@ class Release:
|
|
120
120
|
date=dt,
|
121
121
|
offset=0,
|
122
122
|
end_date=dt + timedelta(days=1),
|
123
|
-
runner=
|
124
|
-
|
123
|
+
runner=(
|
124
|
+
CronJob("* * * * *").schedule(
|
125
|
+
dt.replace(tzinfo=dynamic("tz", extras=extras))
|
126
|
+
)
|
125
127
|
),
|
126
128
|
)
|
127
129
|
|
@@ -159,16 +161,22 @@ class ReleaseQueue:
|
|
159
161
|
complete: list[Release] = field(default_factory=list)
|
160
162
|
extras: DictData = Field(
|
161
163
|
default_factory=dict,
|
162
|
-
description="An extra override config values.",
|
164
|
+
description="An extra parameters that want to override config values.",
|
163
165
|
)
|
164
166
|
|
165
167
|
@classmethod
|
166
168
|
def from_list(
|
167
|
-
cls,
|
169
|
+
cls,
|
170
|
+
queue: list[datetime] | list[Release] | None = None,
|
171
|
+
extras: Optional[DictData] = None,
|
168
172
|
) -> Self:
|
169
173
|
"""Construct ReleaseQueue object from an input queue value that passing
|
170
174
|
with list of datetime or list of Release.
|
171
175
|
|
176
|
+
:param queue:
|
177
|
+
:param extras: An extra parameter that want to override core config
|
178
|
+
values.
|
179
|
+
|
172
180
|
:raise TypeError: If the type of input queue does not valid.
|
173
181
|
|
174
182
|
:rtype: ReleaseQueue
|
@@ -179,7 +187,11 @@ class ReleaseQueue:
|
|
179
187
|
if isinstance(queue, list):
|
180
188
|
|
181
189
|
if all(isinstance(q, datetime) for q in queue):
|
182
|
-
return cls(
|
190
|
+
return cls(
|
191
|
+
queue=[
|
192
|
+
Release.from_dt(q, extras=(extras or {})) for q in queue
|
193
|
+
]
|
194
|
+
)
|
183
195
|
|
184
196
|
if all(isinstance(q, Release) for q in queue):
|
185
197
|
return cls(queue=queue)
|
@@ -216,7 +228,7 @@ class ReleaseQueue:
|
|
216
228
|
:rtype: bool
|
217
229
|
"""
|
218
230
|
if isinstance(value, datetime):
|
219
|
-
value = Release.from_dt(value)
|
231
|
+
value = Release.from_dt(value, extras=self.extras)
|
220
232
|
|
221
233
|
return (
|
222
234
|
(value in self.queue)
|
@@ -242,7 +254,7 @@ class ReleaseQueue:
|
|
242
254
|
heappush(self.complete, value)
|
243
255
|
|
244
256
|
# NOTE: Remove complete queue on workflow that keep more than the
|
245
|
-
# maximum config.
|
257
|
+
# maximum config value.
|
246
258
|
num_complete_delete: int = len(self.complete) - dynamic(
|
247
259
|
"max_queue_complete_hist", extras=self.extras
|
248
260
|
)
|
@@ -253,6 +265,70 @@ class ReleaseQueue:
|
|
253
265
|
|
254
266
|
return self
|
255
267
|
|
268
|
+
def gen(
|
269
|
+
self,
|
270
|
+
end_date: datetime,
|
271
|
+
audit: type[Audit],
|
272
|
+
runner: CronRunner,
|
273
|
+
name: str,
|
274
|
+
*,
|
275
|
+
offset: float = 0,
|
276
|
+
force_run: bool = False,
|
277
|
+
extras: Optional[DictData] = None,
|
278
|
+
) -> Self:
|
279
|
+
"""Generate Release model to queue.
|
280
|
+
|
281
|
+
Steps:
|
282
|
+
- Create Release object from the current date that not reach the end
|
283
|
+
date.
|
284
|
+
- Check this release do not store on the release queue object.
|
285
|
+
Generate the next date if it exists.
|
286
|
+
- Push this release to the release queue
|
287
|
+
|
288
|
+
:param end_date: (datetime) An end datetime object.
|
289
|
+
:param audit: (type[Audit]) An audit class that want to make audit
|
290
|
+
instance.
|
291
|
+
:param runner: (CronRunner) A CronRunner object.
|
292
|
+
:param name: (str) A target name that want to check at pointer of audit.
|
293
|
+
:param offset: (float) An offset in second unit for time travel.
|
294
|
+
:param force_run: A flag that allow to release workflow if the audit
|
295
|
+
with that release was pointed.
|
296
|
+
:param extras: An extra parameter that want to override core config.
|
297
|
+
|
298
|
+
:rtype: ReleaseQueue
|
299
|
+
|
300
|
+
"""
|
301
|
+
if runner.date > end_date:
|
302
|
+
return self
|
303
|
+
|
304
|
+
workflow_release = Release(
|
305
|
+
date=runner.date,
|
306
|
+
offset=offset,
|
307
|
+
end_date=end_date,
|
308
|
+
runner=runner,
|
309
|
+
type=ReleaseType.POKE,
|
310
|
+
)
|
311
|
+
|
312
|
+
while self.check_queue(workflow_release) or (
|
313
|
+
audit.is_pointed(
|
314
|
+
name=name, release=workflow_release.date, extras=extras
|
315
|
+
)
|
316
|
+
and not force_run
|
317
|
+
):
|
318
|
+
workflow_release = Release(
|
319
|
+
date=runner.next,
|
320
|
+
offset=offset,
|
321
|
+
end_date=end_date,
|
322
|
+
runner=runner,
|
323
|
+
type=ReleaseType.POKE,
|
324
|
+
)
|
325
|
+
|
326
|
+
if runner.date > end_date:
|
327
|
+
return self
|
328
|
+
|
329
|
+
heappush(self.queue, workflow_release)
|
330
|
+
return self
|
331
|
+
|
256
332
|
|
257
333
|
class Workflow(BaseModel):
|
258
334
|
"""Workflow Pydantic model.
|
@@ -265,7 +341,7 @@ class Workflow(BaseModel):
|
|
265
341
|
|
266
342
|
extras: DictData = Field(
|
267
343
|
default_factory=dict,
|
268
|
-
description="An extra override config values.",
|
344
|
+
description="An extra parameters that want to override config values.",
|
269
345
|
)
|
270
346
|
|
271
347
|
name: str = Field(description="A workflow name.")
|
@@ -335,8 +411,8 @@ class Workflow(BaseModel):
|
|
335
411
|
|
336
412
|
:param name: (str) A workflow name that want to pass to Loader object.
|
337
413
|
:param path: (Path) A config path that want to search.
|
338
|
-
:param extras: An extra parameters that want to
|
339
|
-
|
414
|
+
:param extras: (DictData) An extra parameters that want to override core
|
415
|
+
config values.
|
340
416
|
|
341
417
|
:raise ValueError: If the type does not match with current object.
|
342
418
|
|
@@ -367,10 +443,10 @@ class Workflow(BaseModel):
|
|
367
443
|
) -> DictData:
|
368
444
|
"""Bypass the on data to loaded config data.
|
369
445
|
|
370
|
-
:param data: A data to construct to this Workflow model.
|
371
|
-
:param path: A config path.
|
372
|
-
:param extras: An extra parameters that want to
|
373
|
-
|
446
|
+
:param data: (DictData) A data to construct to this Workflow model.
|
447
|
+
:param path: (Path) A config path.
|
448
|
+
:param extras: (DictData) An extra parameters that want to override core
|
449
|
+
config values.
|
374
450
|
|
375
451
|
:rtype: DictData
|
376
452
|
"""
|
@@ -445,9 +521,9 @@ class Workflow(BaseModel):
|
|
445
521
|
# "only one value in the on field."
|
446
522
|
# )
|
447
523
|
|
448
|
-
extras: DictData = info.data.get("extras"
|
524
|
+
extras: Optional[DictData] = info.data.get("extras")
|
449
525
|
if len(set_ons) > (
|
450
|
-
conf := dynamic("
|
526
|
+
conf := dynamic("max_cron_per_workflow", extras=extras)
|
451
527
|
):
|
452
528
|
raise ValueError(
|
453
529
|
f"The number of the on should not more than {conf} crontabs."
|
@@ -485,8 +561,9 @@ class Workflow(BaseModel):
|
|
485
561
|
return self
|
486
562
|
|
487
563
|
def job(self, name: str) -> Job:
|
488
|
-
"""Return the workflow's
|
489
|
-
|
564
|
+
"""Return the workflow's Job model that getting by an input job's name
|
565
|
+
or job's ID. This method will pass an extra parameter from this model
|
566
|
+
to the returned Job model.
|
490
567
|
|
491
568
|
:param name: (str) A job name or ID that want to get from a mapping of
|
492
569
|
job models.
|
@@ -596,13 +673,14 @@ class Workflow(BaseModel):
|
|
596
673
|
|
597
674
|
:rtype: Result
|
598
675
|
"""
|
599
|
-
audit: type[Audit] = audit or get_audit()
|
676
|
+
audit: type[Audit] = audit or get_audit(extras=self.extras)
|
600
677
|
name: str = override_log_name or self.name
|
601
678
|
result: Result = Result.construct_with_rs_or_id(
|
602
679
|
result,
|
603
680
|
run_id=run_id,
|
604
681
|
parent_run_id=parent_run_id,
|
605
682
|
id_logic=name,
|
683
|
+
extras=self.extras,
|
606
684
|
)
|
607
685
|
|
608
686
|
if queue is not None and not isinstance(queue, ReleaseQueue):
|
@@ -612,7 +690,7 @@ class Workflow(BaseModel):
|
|
612
690
|
|
613
691
|
# VALIDATE: Change release value to Release object.
|
614
692
|
if isinstance(release, datetime):
|
615
|
-
release: Release = Release.from_dt(release)
|
693
|
+
release: Release = Release.from_dt(release, extras=self.extras)
|
616
694
|
|
617
695
|
result.trace.debug(
|
618
696
|
f"[RELEASE]: Start release - {name!r} : "
|
@@ -659,6 +737,7 @@ class Workflow(BaseModel):
|
|
659
737
|
parent_run_id=result.parent_run_id,
|
660
738
|
run_id=result.run_id,
|
661
739
|
execution_time=result.alive_time(),
|
740
|
+
extras=self.extras,
|
662
741
|
).save(excluded=None)
|
663
742
|
)
|
664
743
|
|
@@ -701,14 +780,6 @@ class Workflow(BaseModel):
|
|
701
780
|
"""Generate Release from all on values from the on field and store them
|
702
781
|
to the ReleaseQueue object.
|
703
782
|
|
704
|
-
Steps:
|
705
|
-
- For-loop all the on value in the on field.
|
706
|
-
- Create Release object from the current date that not reach the end
|
707
|
-
date.
|
708
|
-
- Check this release do not store on the release queue object.
|
709
|
-
Generate the next date if it exists.
|
710
|
-
- Push this release to the release queue
|
711
|
-
|
712
783
|
:param offset: An offset in second unit for time travel.
|
713
784
|
:param end_date: An end datetime object.
|
714
785
|
:param queue: A workflow queue object.
|
@@ -720,40 +791,19 @@ class Workflow(BaseModel):
|
|
720
791
|
"""
|
721
792
|
for on in self.on:
|
722
793
|
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
workflow_release = Release(
|
733
|
-
date=runner.date,
|
794
|
+
queue.gen(
|
795
|
+
end_date,
|
796
|
+
audit,
|
797
|
+
on.next(
|
798
|
+
get_dt_now(
|
799
|
+
tz=dynamic("tz", extras=self.extras), offset=offset
|
800
|
+
).replace(microsecond=0)
|
801
|
+
),
|
802
|
+
self.name,
|
734
803
|
offset=offset,
|
735
|
-
|
736
|
-
runner=runner,
|
737
|
-
type=ReleaseType.POKE,
|
804
|
+
force_run=force_run,
|
738
805
|
)
|
739
806
|
|
740
|
-
while queue.check_queue(workflow_release) or (
|
741
|
-
audit.is_pointed(name=self.name, release=workflow_release.date)
|
742
|
-
and not force_run
|
743
|
-
):
|
744
|
-
workflow_release = Release(
|
745
|
-
date=runner.next,
|
746
|
-
offset=offset,
|
747
|
-
end_date=end_date,
|
748
|
-
runner=runner,
|
749
|
-
type=ReleaseType.POKE,
|
750
|
-
)
|
751
|
-
|
752
|
-
if runner.date > end_date:
|
753
|
-
continue
|
754
|
-
|
755
|
-
heappush(queue.queue, workflow_release)
|
756
|
-
|
757
807
|
return queue
|
758
808
|
|
759
809
|
def poke(
|
@@ -792,7 +842,7 @@ class Workflow(BaseModel):
|
|
792
842
|
:rtype: Result
|
793
843
|
:return: A list of all results that return from `self.release` method.
|
794
844
|
"""
|
795
|
-
audit: type[Audit] = audit or get_audit()
|
845
|
+
audit: type[Audit] = audit or get_audit(extras=self.extras)
|
796
846
|
result: Result = Result(
|
797
847
|
run_id=(run_id or gen_id(self.name, unique=True))
|
798
848
|
)
|
@@ -1042,6 +1092,7 @@ class Workflow(BaseModel):
|
|
1042
1092
|
run_id=run_id,
|
1043
1093
|
parent_run_id=parent_run_id,
|
1044
1094
|
id_logic=self.name,
|
1095
|
+
extras=self.extras,
|
1045
1096
|
)
|
1046
1097
|
|
1047
1098
|
result.trace.info(f"[WORKFLOW]: Start Execute: {self.name!r} ...")
|
@@ -1303,10 +1354,11 @@ class WorkflowTask:
|
|
1303
1354
|
arguments before passing to the parent release method.
|
1304
1355
|
"""
|
1305
1356
|
|
1306
|
-
alias: str
|
1307
|
-
workflow: Workflow
|
1308
|
-
runner: CronRunner
|
1357
|
+
alias: str
|
1358
|
+
workflow: Workflow
|
1359
|
+
runner: CronRunner
|
1309
1360
|
values: DictData = field(default_factory=dict)
|
1361
|
+
extras: DictData = field(default_factory=dict)
|
1310
1362
|
|
1311
1363
|
def release(
|
1312
1364
|
self,
|
@@ -1333,7 +1385,7 @@ class WorkflowTask:
|
|
1333
1385
|
|
1334
1386
|
:rtype: Result
|
1335
1387
|
"""
|
1336
|
-
audit: type[Audit] = audit or get_audit()
|
1388
|
+
audit: type[Audit] = audit or get_audit(extras=self.extras)
|
1337
1389
|
|
1338
1390
|
if release is None:
|
1339
1391
|
|
@@ -1383,35 +1435,15 @@ class WorkflowTask:
|
|
1383
1435
|
|
1384
1436
|
:rtype: ReleaseQueue
|
1385
1437
|
"""
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
runner=self.runner,
|
1394
|
-
type=ReleaseType.TASK,
|
1438
|
+
return queue.gen(
|
1439
|
+
end_date,
|
1440
|
+
audit,
|
1441
|
+
self.runner,
|
1442
|
+
self.alias,
|
1443
|
+
force_run=force_run,
|
1444
|
+
extras=self.extras,
|
1395
1445
|
)
|
1396
1446
|
|
1397
|
-
while queue.check_queue(workflow_release) or (
|
1398
|
-
audit.is_pointed(name=self.alias, release=workflow_release.date)
|
1399
|
-
and not force_run
|
1400
|
-
):
|
1401
|
-
workflow_release = Release(
|
1402
|
-
date=self.runner.next,
|
1403
|
-
offset=0,
|
1404
|
-
end_date=end_date,
|
1405
|
-
runner=self.runner,
|
1406
|
-
type=ReleaseType.TASK,
|
1407
|
-
)
|
1408
|
-
|
1409
|
-
if self.runner.date > end_date:
|
1410
|
-
return queue
|
1411
|
-
|
1412
|
-
heappush(queue.queue, workflow_release)
|
1413
|
-
return queue
|
1414
|
-
|
1415
1447
|
def __repr__(self) -> str:
|
1416
1448
|
"""Override the `__repr__` method.
|
1417
1449
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ddeutil-workflow
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.49
|
4
4
|
Summary: Lightweight workflow orchestration
|
5
5
|
Author-email: ddeutils <korawich.anu@gmail.com>
|
6
6
|
License: MIT
|
@@ -260,31 +260,29 @@ it will use default value and do not raise any error to you.
|
|
260
260
|
> The config value that you will set on the environment should combine with
|
261
261
|
> prefix, component, and name which is `WORKFLOW_{component}_{name}` (Upper case).
|
262
262
|
|
263
|
-
| Name | Component | Default |
|
264
|
-
|
265
|
-
| **
|
266
|
-
| **
|
267
|
-
| **
|
268
|
-
| **
|
269
|
-
| **
|
270
|
-
| **
|
271
|
-
| **
|
272
|
-
| **
|
273
|
-
| **
|
274
|
-
| **
|
275
|
-
| **
|
276
|
-
| **
|
277
|
-
| **
|
278
|
-
| **
|
279
|
-
| **
|
280
|
-
| **
|
281
|
-
| **
|
282
|
-
| **
|
283
|
-
| **
|
284
|
-
| **
|
285
|
-
| **
|
286
|
-
| **MAX_SCHEDULE_PER_PROCESS** | App | `100` | No | A schedule per process that run parallel. |
|
287
|
-
| **STOP_BOUNDARY_DELTA** | App | `'{"minutes": 5, "seconds": 20}'` | No | A time delta value that use to stop scheduler app in json string format. |
|
263
|
+
| Name | Component | Default | Description |
|
264
|
+
|:-----------------------------|:---------:|:--------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------|
|
265
|
+
| **REGISTRY_CALLER** | Core | `.` | List of importable string for the call stage. |
|
266
|
+
| **REGISTRY_FILTER** | Core | `ddeutil.workflow.templates` | List of importable string for the filter template. |
|
267
|
+
| **CONF_PATH** | Core | `./conf` | The config path that keep all template `.yaml` files. |
|
268
|
+
| **TIMEZONE** | Core | `Asia/Bangkok` | A Timezone string value that will pass to `ZoneInfo` object. |
|
269
|
+
| **STAGE_DEFAULT_ID** | Core | `false` | A flag that enable default stage ID that use for catch an execution output. |
|
270
|
+
| **STAGE_RAISE_ERROR** | Core | `false` | A flag that all stage raise StageException from stage execution. |
|
271
|
+
| **JOB_RAISE_ERROR** | Core | `true` | A flag that all job raise JobException from job strategy execution. |
|
272
|
+
| **MAX_CRON_PER_WORKFLOW** | Core | `5` | |
|
273
|
+
| **MAX_QUEUE_COMPLETE_HIST** | Core | `16` | |
|
274
|
+
| **GENERATE_ID_SIMPLE_MODE** | Core | `true` | A flog that enable generating ID with `md5` algorithm. |
|
275
|
+
| **DEBUG_MODE** | Log | `true` | A flag that enable logging with debug level mode. |
|
276
|
+
| **FORMAT** | Log | `%(asctime)s.%(msecs)03d (%(name)-10s, %(process)-5d,%(thread)-5d) [%(levelname)-7s] %(message)-120s (%(filename)s:%(lineno)s)` | |
|
277
|
+
| **FORMAT_FILE** | Log | `{datetime} ({process:5d}, {thread:5d}) {message:120s} ({filename}:{lineno})` | |
|
278
|
+
| **DATETIME_FORMAT** | Log | `%Y-%m-%d %H:%M:%S` | |
|
279
|
+
| **TRACE_PATH** | Log | `./logs` | The log path of the workflow saving log. |
|
280
|
+
| **TRACE_ENABLE_WRITE** | Log | `false` | |
|
281
|
+
| **AUDIT_PATH** | Log | `./audits` | |
|
282
|
+
| **AUDIT_ENABLE_WRITE** | Log | `true` | A flag that enable logging object saving log to its destination. |
|
283
|
+
| **MAX_PROCESS** | App | `2` | The maximum process worker number that run in scheduler app module. |
|
284
|
+
| **MAX_SCHEDULE_PER_PROCESS** | App | `100` | A schedule per process that run parallel. |
|
285
|
+
| **STOP_BOUNDARY_DELTA** | App | `'{"minutes": 5, "seconds": 20}'` | A time delta value that use to stop scheduler app in json string format. |
|
288
286
|
|
289
287
|
**API Application**:
|
290
288
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
ddeutil/workflow/__about__.py,sha256=8c8KBEXeEOskazR5AlLYEjCpyi54xsoTaaqRY8pXUJY,28
|
2
|
+
ddeutil/workflow/__cron.py,sha256=h8rLeIUAAEB2SdZ4Jhch7LU1Yl3bbJ-iNNJ3tQ0eYVM,28095
|
3
|
+
ddeutil/workflow/__init__.py,sha256=EpqROKwAX76Wea-37hi0R_oVQ2jm2cc9ML9USxRAsak,1971
|
4
|
+
ddeutil/workflow/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
ddeutil/workflow/__types.py,sha256=8jBdbfb3aZSetjz0mvNrpGHwwxJff7mK8_4v41cLqlc,4316
|
6
|
+
ddeutil/workflow/conf.py,sha256=lviP7bFsOCJtD8S1VyJK6aaSL9Nj_vfC2Kkpe1z2Zec,12444
|
7
|
+
ddeutil/workflow/cron.py,sha256=80SijzMdDOBxTWRsiF-Fmuz7Ym7leY0XT2lzRAPGdXc,8781
|
8
|
+
ddeutil/workflow/exceptions.py,sha256=uLNxzav3HRcr4vaZnvbUIF_eTR6UXXZNaxroMWFOUL4,1418
|
9
|
+
ddeutil/workflow/job.py,sha256=y2q_md2nUp1jfgjaQdjDZqrHR541ENrWB__S1-Eoyss,30830
|
10
|
+
ddeutil/workflow/logs.py,sha256=JghQawGd16ysf-5y7ZFtSGFY82uwgb9oMKNYy9eGI-o,26468
|
11
|
+
ddeutil/workflow/params.py,sha256=xCtFEh0-G-G-f8y_SXxyf31bU6Ox5p5Z-WbBFXrjy8M,9960
|
12
|
+
ddeutil/workflow/result.py,sha256=kizTEP6DY9ewDQQR17YgfrtMXRW-wF8vRzG26wzAqUM,5439
|
13
|
+
ddeutil/workflow/reusables.py,sha256=hIpehea6J4OWeXX55kjYzo-c9-_Cc0YRwLRRbcaUkZs,17539
|
14
|
+
ddeutil/workflow/scheduler.py,sha256=F783QaJfPg8tvYyvJvkwl8Sa42vsJzj6BzzROZFvm9I,28153
|
15
|
+
ddeutil/workflow/stages.py,sha256=2vO5pdUgKHeGsS762fdYrBkWfvby_Q3Z71ptHajEp8k,55904
|
16
|
+
ddeutil/workflow/utils.py,sha256=CtFUrP_4m6xaJooc9RbE4ulTBE-OkICg-MPHqzCuJ0I,7392
|
17
|
+
ddeutil/workflow/workflow.py,sha256=mCpsAY0Su-pMJ_xZ-qF6lDEXn-Ih7myUODZ0ZEuyVew,50804
|
18
|
+
ddeutil/workflow/api/__init__.py,sha256=F53NMBWtb9IKaDWkPU5KvybGGfKAcbehgn6TLBwHuuM,21
|
19
|
+
ddeutil/workflow/api/api.py,sha256=CWtPLgOv2Jus9E7nzG5mG2Z32ZEkUK3JWQ2htZyMRpA,5244
|
20
|
+
ddeutil/workflow/api/log.py,sha256=NMTnOnsBrDB5129329xF2myLdrb-z9k1MQrmrP7qXJw,1818
|
21
|
+
ddeutil/workflow/api/repeat.py,sha256=uTtUFVLpiYYahXvCVx8sueRQ03K2Xw1id_gW3IMmX1U,5295
|
22
|
+
ddeutil/workflow/api/routes/__init__.py,sha256=qoGtOMyVgQ5nTUc8J8wH27A8isaxl3IFCX8qoyibeCY,484
|
23
|
+
ddeutil/workflow/api/routes/job.py,sha256=oPwBVP0Mxwxv-bGPlfmxQQ9PcVl0ev9HoPzndpYDCCQ,1954
|
24
|
+
ddeutil/workflow/api/routes/logs.py,sha256=U6vOni3wd-ZTOwd3yVdSOpgyRmNdcgfngU5KlLM3Cww,5383
|
25
|
+
ddeutil/workflow/api/routes/schedules.py,sha256=EgUjyRGhsm6UNaMj5luh6TcY6l571sCHcla-BL1iOfY,4829
|
26
|
+
ddeutil/workflow/api/routes/workflows.py,sha256=JcDOrn1deK8ztFRcMTNATQejG6KMA7JxZLVc4QeBsP4,4527
|
27
|
+
ddeutil_workflow-0.0.49.dist-info/licenses/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
|
28
|
+
ddeutil_workflow-0.0.49.dist-info/METADATA,sha256=U847vy3oZ6ZEvngEe-9W3wA1vkKGr15UQa73v9Dsy7k,18257
|
29
|
+
ddeutil_workflow-0.0.49.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
30
|
+
ddeutil_workflow-0.0.49.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
|
31
|
+
ddeutil_workflow-0.0.49.dist-info/RECORD,,
|
@@ -1,31 +0,0 @@
|
|
1
|
-
ddeutil/workflow/__about__.py,sha256=6qZfpuPCbzNW572qdp7t-HFsC1JN75TQi_50aMab9kk,28
|
2
|
-
ddeutil/workflow/__cron.py,sha256=h8rLeIUAAEB2SdZ4Jhch7LU1Yl3bbJ-iNNJ3tQ0eYVM,28095
|
3
|
-
ddeutil/workflow/__init__.py,sha256=m7ZTCuUOarcTKJuXOyuaXd5WTIO7NTkqCeCrNX3d5i8,1943
|
4
|
-
ddeutil/workflow/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
ddeutil/workflow/__types.py,sha256=8jBdbfb3aZSetjz0mvNrpGHwwxJff7mK8_4v41cLqlc,4316
|
6
|
-
ddeutil/workflow/conf.py,sha256=ZlaaLeZuBzqcnS-gfHQV58dJVMwQaRTjWxWZGCzX42s,12068
|
7
|
-
ddeutil/workflow/cron.py,sha256=80SijzMdDOBxTWRsiF-Fmuz7Ym7leY0XT2lzRAPGdXc,8781
|
8
|
-
ddeutil/workflow/exceptions.py,sha256=uLNxzav3HRcr4vaZnvbUIF_eTR6UXXZNaxroMWFOUL4,1418
|
9
|
-
ddeutil/workflow/job.py,sha256=uDT_lxAmtWDk6OYm6E4_rz_ngMdS5S03YF4D3WZMP8k,30676
|
10
|
-
ddeutil/workflow/logs.py,sha256=Ki1t6HkThwimzAe1OSxPPc7OQ4r-kXAc1kB63x2DsOg,21160
|
11
|
-
ddeutil/workflow/params.py,sha256=xCtFEh0-G-G-f8y_SXxyf31bU6Ox5p5Z-WbBFXrjy8M,9960
|
12
|
-
ddeutil/workflow/result.py,sha256=bysM6A194LPcivzmCrNNZsT8MphzhYAvqhjEYD6zryo,5145
|
13
|
-
ddeutil/workflow/reusables.py,sha256=vUsbh1dw5Cpojv98QTZarwBLHjvTMvR05H7XV76zUKQ,17537
|
14
|
-
ddeutil/workflow/scheduler.py,sha256=_MDsEHbBVOeF-381U8DfIMDyca_nG3XNXmgX4229_EU,27437
|
15
|
-
ddeutil/workflow/stages.py,sha256=oYEGWD-3kodtKSZ6JPAqAT5_za-sZI3GAKMJxeYUD8o,49009
|
16
|
-
ddeutil/workflow/utils.py,sha256=sblje9qOtejCHVt8EVrbC0KY98vKqvxccaR5HIkRiTA,7363
|
17
|
-
ddeutil/workflow/workflow.py,sha256=kEbPr2Wi9n5fDaCi5R26f4SHw7083_TdcIkZw-w7cEA,49716
|
18
|
-
ddeutil/workflow/api/__init__.py,sha256=F53NMBWtb9IKaDWkPU5KvybGGfKAcbehgn6TLBwHuuM,21
|
19
|
-
ddeutil/workflow/api/api.py,sha256=b-bMg0aRsEqt8Qb2hNUtamEt2Fq2CgNotF2oXSAdDu8,5226
|
20
|
-
ddeutil/workflow/api/log.py,sha256=NMTnOnsBrDB5129329xF2myLdrb-z9k1MQrmrP7qXJw,1818
|
21
|
-
ddeutil/workflow/api/repeat.py,sha256=cycd1-91j-4v6uY1SkrZHd9l95e-YgVC4UCSNNFuGJ8,5277
|
22
|
-
ddeutil/workflow/api/routes/__init__.py,sha256=qoGtOMyVgQ5nTUc8J8wH27A8isaxl3IFCX8qoyibeCY,484
|
23
|
-
ddeutil/workflow/api/routes/job.py,sha256=YVta083i8vU8-o4WdKFwDpfdC9vN1dZ6goZSmNlQXHA,1954
|
24
|
-
ddeutil/workflow/api/routes/logs.py,sha256=TeRDrEelbKS2Hu_EovgLh0bOdmSv9mfnrIZsrE7uPD4,5353
|
25
|
-
ddeutil/workflow/api/routes/schedules.py,sha256=rUWBm5RgLS1PNBHSWwWXJ0l-c5mYWfl9os0BA9_OTEw,4810
|
26
|
-
ddeutil/workflow/api/routes/workflows.py,sha256=ctgQGxXfpIV6bHFDM9IQ1_qaQHT6n5-HjJ1-D4GKWpc,4527
|
27
|
-
ddeutil_workflow-0.0.47.dist-info/licenses/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
|
28
|
-
ddeutil_workflow-0.0.47.dist-info/METADATA,sha256=EngsQlJUAaJf_8irHXLk04p6F71UjQnBifd84g1GhNw,19116
|
29
|
-
ddeutil_workflow-0.0.47.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
30
|
-
ddeutil_workflow-0.0.47.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
|
31
|
-
ddeutil_workflow-0.0.47.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|