dv-flow-mgr 0.0.1.13979842530a1__py3-none-any.whl → 0.0.1.14097297609a1__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.
- dv_flow/mgr/__init__.py +2 -2
- dv_flow/mgr/__main__.py +26 -1
- dv_flow/mgr/cmds/cmd_graph.py +82 -0
- dv_flow/mgr/cmds/cmd_run.py +2 -2
- dv_flow/mgr/cmds/cmd_show.py +107 -0
- dv_flow/mgr/fileset.py +1 -0
- dv_flow/mgr/fragment_def.py +1 -1
- dv_flow/mgr/package.py +3 -3
- dv_flow/mgr/package_def.py +121 -33
- dv_flow/mgr/param_def.py +8 -3
- dv_flow/mgr/std/message.py +1 -1
- dv_flow/mgr/task_data.py +24 -20
- dv_flow/mgr/task_def.py +0 -1
- dv_flow/mgr/task_graph_builder.py +121 -12
- dv_flow/mgr/task_graph_dot_writer.py +78 -0
- dv_flow/mgr/task_node.py +3 -326
- dv_flow/mgr/task_node_compound.py +13 -1
- dv_flow/mgr/task_node_ctor.py +118 -0
- dv_flow/mgr/task_node_ctor_compound.py +117 -0
- dv_flow/mgr/task_node_ctor_compound_proxy.py +65 -0
- dv_flow/mgr/task_node_ctor_def_base.py +47 -0
- dv_flow/mgr/task_node_ctor_proxy.py +56 -0
- dv_flow/mgr/task_node_ctor_task.py +64 -0
- dv_flow/mgr/task_node_ctor_wrapper.py +96 -0
- dv_flow/mgr/task_node_leaf.py +170 -0
- dv_flow/mgr/task_runner.py +11 -6
- dv_flow/mgr/util/__init__.py +3 -0
- dv_flow/mgr/util/__main__.py +36 -0
- dv_flow/mgr/util/cmds/__init__.py +0 -0
- dv_flow/mgr/util/cmds/cmd_schema.py +63 -0
- dv_flow/mgr/{util.py → util/util.py} +1 -1
- {dv_flow_mgr-0.0.1.13979842530a1.dist-info → dv_flow_mgr-0.0.1.14097297609a1.dist-info}/METADATA +1 -1
- dv_flow_mgr-0.0.1.14097297609a1.dist-info/RECORD +57 -0
- {dv_flow_mgr-0.0.1.13979842530a1.dist-info → dv_flow_mgr-0.0.1.14097297609a1.dist-info}/WHEEL +1 -1
- dv_flow/mgr/task.py +0 -181
- dv_flow/mgr/task_ctor.py +0 -64
- dv_flow_mgr-0.0.1.13979842530a1.dist-info/RECORD +0 -44
- {dv_flow_mgr-0.0.1.13979842530a1.dist-info → dv_flow_mgr-0.0.1.14097297609a1.dist-info}/entry_points.txt +0 -0
- {dv_flow_mgr-0.0.1.13979842530a1.dist-info → dv_flow_mgr-0.0.1.14097297609a1.dist-info}/licenses/LICENSE +0 -0
- {dv_flow_mgr-0.0.1.13979842530a1.dist-info → dv_flow_mgr-0.0.1.14097297609a1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,170 @@
|
|
1
|
+
import enum
|
2
|
+
import os
|
3
|
+
import sys
|
4
|
+
import dataclasses as dc
|
5
|
+
import pydantic.dataclasses as pdc
|
6
|
+
import logging
|
7
|
+
import toposort
|
8
|
+
from typing import Any, Callable, ClassVar, Dict, List, Tuple
|
9
|
+
from .task_data import TaskDataInput, TaskDataOutput, TaskDataResult
|
10
|
+
from .task_node import TaskNode
|
11
|
+
from .task_params_ctor import TaskParamsCtor
|
12
|
+
from .param_ref_eval import ParamRefEval
|
13
|
+
from .param import Param
|
14
|
+
|
15
|
+
@dc.dataclass
|
16
|
+
class TaskNodeLeaf(TaskNode):
|
17
|
+
task : Callable[['TaskRunner','TaskDataInput'],'TaskDataResult'] = dc.field(default=None)
|
18
|
+
|
19
|
+
async def do_run(self,
|
20
|
+
runner,
|
21
|
+
rundir,
|
22
|
+
memento : Any = None) -> 'TaskDataResult':
|
23
|
+
self._log.debug("--> do_run: %s" % self.name)
|
24
|
+
changed = False
|
25
|
+
for dep,_ in self.needs:
|
26
|
+
changed |= dep.changed
|
27
|
+
|
28
|
+
self.rundir = rundir
|
29
|
+
|
30
|
+
# TODO: Form dep-map from inputs
|
31
|
+
|
32
|
+
dep_m = {}
|
33
|
+
for need,block in self.needs:
|
34
|
+
self._log.debug("dep %s dep_m: %s" % (need.name, str(dep_m)))
|
35
|
+
if not block:
|
36
|
+
for subdep in need.output.dep_m.keys():
|
37
|
+
if subdep not in dep_m.keys():
|
38
|
+
dep_m[subdep] = []
|
39
|
+
for dep in need.output.dep_m[subdep]:
|
40
|
+
if dep not in dep_m[subdep]:
|
41
|
+
dep_m[subdep].append(dep)
|
42
|
+
self._log.debug("input dep_m: %s %s" % (self.name, str(dep_m)))
|
43
|
+
|
44
|
+
sorted = toposort.toposort(dep_m)
|
45
|
+
|
46
|
+
in_params_m = {}
|
47
|
+
added_srcs = set()
|
48
|
+
for need,block in self.needs:
|
49
|
+
self._log.debug("Process need=%s block=%s" % (need.name, block))
|
50
|
+
if not block:
|
51
|
+
for p in need.output.output:
|
52
|
+
|
53
|
+
# Avoid adding parameters from a single task more than once
|
54
|
+
key = (p.src, p.seq)
|
55
|
+
if key not in added_srcs:
|
56
|
+
added_srcs.add(key)
|
57
|
+
if p.src not in in_params_m.keys():
|
58
|
+
in_params_m[p.src] = []
|
59
|
+
in_params_m[p.src].append(p)
|
60
|
+
|
61
|
+
# in_params holds parameter sets ordered by dependency
|
62
|
+
in_params = []
|
63
|
+
for sorted_s in sorted:
|
64
|
+
self._log.debug("sorted_s: %s" % str(sorted_s))
|
65
|
+
for dep in sorted_s:
|
66
|
+
if dep in in_params_m.keys():
|
67
|
+
self._log.debug("(%s) Extend with: %s" % (dep, str(in_params_m[dep])))
|
68
|
+
in_params.extend(in_params_m[dep])
|
69
|
+
|
70
|
+
self._log.debug("in_params[1]: %s" % ",".join(p.src for p in in_params))
|
71
|
+
|
72
|
+
# Create an evaluator for substituting param values
|
73
|
+
eval = ParamRefEval()
|
74
|
+
|
75
|
+
self._log.debug("in_params[2]: %s" % ",".join(p.src for p in in_params))
|
76
|
+
eval.setVar("in", in_params)
|
77
|
+
eval.setVar("rundir", rundir)
|
78
|
+
|
79
|
+
# Set variables from the inputs
|
80
|
+
for need in self.needs:
|
81
|
+
for name,value in {"rundir" : need[0].rundir}.items():
|
82
|
+
eval.setVar("%s.%s" % (need[0].name, name), value)
|
83
|
+
|
84
|
+
# Default inputs is the list of parameter sets that match 'consumes'
|
85
|
+
inputs = []
|
86
|
+
if self.consumes is not None and len(self.consumes):
|
87
|
+
for in_p in in_params:
|
88
|
+
if self._matches(in_p, self.consumes):
|
89
|
+
inputs.append(in_p)
|
90
|
+
|
91
|
+
for name,field in self.params.model_fields.items():
|
92
|
+
value = getattr(self.params, name)
|
93
|
+
if type(value) == str:
|
94
|
+
if value.find("${{") != -1:
|
95
|
+
new_val = eval.eval(value)
|
96
|
+
self._log.debug("Param %s: Evaluate expression \"%s\" => \"%s\"" % (name, value, new_val))
|
97
|
+
setattr(self.params, name, new_val)
|
98
|
+
elif isinstance(value, list):
|
99
|
+
for i,elem in enumerate(value):
|
100
|
+
if elem.find("${{") != -1:
|
101
|
+
new_val = eval.eval(elem)
|
102
|
+
value[i] = new_val
|
103
|
+
|
104
|
+
input = TaskDataInput(
|
105
|
+
name=self.name,
|
106
|
+
changed=changed,
|
107
|
+
srcdir=self.srcdir,
|
108
|
+
rundir=rundir,
|
109
|
+
params=self.params,
|
110
|
+
inputs=inputs,
|
111
|
+
memento=memento)
|
112
|
+
|
113
|
+
self._log.debug("--> Call task method %s" % str(self.task))
|
114
|
+
self.result : TaskDataResult = await self.task(self, input)
|
115
|
+
self._log.debug("<-- Call task method %s" % str(self.task))
|
116
|
+
|
117
|
+
output=self.result.output.copy()
|
118
|
+
for i,out in enumerate(output):
|
119
|
+
out.src = self.name
|
120
|
+
out.seq = i
|
121
|
+
|
122
|
+
self._log.debug("output[1]: %s" % str(output))
|
123
|
+
|
124
|
+
# Pass-through all dependencies
|
125
|
+
# Add an entry for ourselves
|
126
|
+
dep_m[self.name] = list(need.name for need,_ in self.needs)
|
127
|
+
|
128
|
+
if self.passthrough:
|
129
|
+
self._log.debug("passthrough: %s" % self.name)
|
130
|
+
|
131
|
+
if self.consumes is None or len(self.consumes) == 0:
|
132
|
+
self._log.debug("Propagating all input parameters to output")
|
133
|
+
for need,block in self.needs:
|
134
|
+
if not block:
|
135
|
+
output.extend(need.output.output)
|
136
|
+
else:
|
137
|
+
# Filter out parameter sets that were consumed
|
138
|
+
self._log.debug("Propagating non-consumed input parameters to output")
|
139
|
+
self._log.debug("consumes: %s" % str(self.consumes))
|
140
|
+
for need,block in self.needs:
|
141
|
+
if not block:
|
142
|
+
for out in need.output.output:
|
143
|
+
if not self._matches(out, self.consumes):
|
144
|
+
self._log.debug("Propagating type %s from %s" % (
|
145
|
+
getattr(out, "type", "<unknown>"),
|
146
|
+
getattr(out, "src", "<unknown>")))
|
147
|
+
output.append(out)
|
148
|
+
else:
|
149
|
+
self._log.debug("non-passthrough: %s (only local outputs propagated)" % self.name)
|
150
|
+
# empty dependency map
|
151
|
+
# dep_m = {
|
152
|
+
# self.name : []
|
153
|
+
# }
|
154
|
+
|
155
|
+
self._log.debug("output dep_m: %s %s" % (self.name, str(dep_m)))
|
156
|
+
self._log.debug("output[2]: %s" % str(output))
|
157
|
+
|
158
|
+
# Store the result
|
159
|
+
self.output = TaskDataOutput(
|
160
|
+
changed=self.result.changed,
|
161
|
+
dep_m=dep_m,
|
162
|
+
output=output)
|
163
|
+
|
164
|
+
# TODO:
|
165
|
+
self._log.debug("<-- do_run: %s" % self.name)
|
166
|
+
|
167
|
+
return self.result
|
168
|
+
|
169
|
+
def __hash__(self):
|
170
|
+
return id(self)
|
dv_flow/mgr/task_runner.py
CHANGED
@@ -27,7 +27,7 @@ import dataclasses as dc
|
|
27
27
|
import logging
|
28
28
|
from datetime import datetime
|
29
29
|
from toposort import toposort
|
30
|
-
from typing import Any, Callable, ClassVar, List, Tuple, Union
|
30
|
+
from typing import Any, Callable, ClassVar, Dict, List, Set, Tuple, Union
|
31
31
|
from .task_data import TaskDataInput, TaskDataOutput, TaskDataResult
|
32
32
|
from .task_node import TaskNode, RundirE
|
33
33
|
|
@@ -92,11 +92,7 @@ class TaskSetRunner(TaskRunner):
|
|
92
92
|
|
93
93
|
|
94
94
|
# First, build a depedency map
|
95
|
-
|
96
|
-
dep_m = {}
|
97
|
-
self._anon_tid = 1
|
98
|
-
for t in tasks:
|
99
|
-
self._buildDepMap(dep_m, t)
|
95
|
+
dep_m = self.buildDepMap(task)
|
100
96
|
|
101
97
|
if self._log.isEnabledFor(logging.DEBUG):
|
102
98
|
self._log.debug("Deps:")
|
@@ -191,6 +187,15 @@ class TaskSetRunner(TaskRunner):
|
|
191
187
|
return list(t.output for t in task)
|
192
188
|
else:
|
193
189
|
return task.output
|
190
|
+
|
191
|
+
def buildDepMap(self, task : Union[TaskNode, List[TaskNode]]) -> Dict[TaskNode, Set[TaskNode]]:
|
192
|
+
tasks = task if isinstance(task, list) else [task]
|
193
|
+
dep_m = {}
|
194
|
+
self._anon_tid = 1
|
195
|
+
for t in tasks:
|
196
|
+
self._buildDepMap(dep_m, t)
|
197
|
+
|
198
|
+
return dep_m
|
194
199
|
|
195
200
|
def _buildDepMap(self, dep_m, task : TaskNode):
|
196
201
|
if task.name is None:
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import argparse
|
2
|
+
import logging
|
3
|
+
from .cmds.cmd_schema import CmdSchema
|
4
|
+
|
5
|
+
def get_parser():
|
6
|
+
parser = argparse.ArgumentParser(description="dv-flow-mgr.util")
|
7
|
+
parser.add_argument("--log-level",
|
8
|
+
help="Configures debug level [INFO, DEBUG]",
|
9
|
+
choices=("NONE", "INFO", "DEBUG"))
|
10
|
+
|
11
|
+
subparsers = parser.add_subparsers(required=True)
|
12
|
+
|
13
|
+
schema = subparsers.add_parser('schema', help='Write schema')
|
14
|
+
schema.add_argument("-o", "--output",
|
15
|
+
help="Destination file",
|
16
|
+
default="-")
|
17
|
+
schema.set_defaults(f=CmdSchema())
|
18
|
+
|
19
|
+
return parser
|
20
|
+
|
21
|
+
|
22
|
+
def main():
|
23
|
+
parser = get_parser()
|
24
|
+
args = parser.parse_args()
|
25
|
+
|
26
|
+
if args.log_level is not None and args.log_level != "NONE":
|
27
|
+
opt_m = {
|
28
|
+
"INFO": logging.INFO,
|
29
|
+
"DEBUG": logging.DEBUG
|
30
|
+
}
|
31
|
+
logging.basicConfig(level=opt_m[args.log_level])
|
32
|
+
|
33
|
+
args.f(args)
|
34
|
+
|
35
|
+
if __name__ == "__main__":
|
36
|
+
main()
|
File without changes
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
import json
|
3
|
+
import sys
|
4
|
+
from pydantic import BaseModel
|
5
|
+
import pydantic.dataclasses as pdc
|
6
|
+
from typing import Union
|
7
|
+
from ...fragment_def import FragmentDef
|
8
|
+
from ...package_def import PackageDef
|
9
|
+
|
10
|
+
class DvFlowSchema(BaseModel):
|
11
|
+
root : Union[PackageDef,FragmentDef] = pdc.Field(default=None)
|
12
|
+
|
13
|
+
class CmdSchema(object):
|
14
|
+
|
15
|
+
def __call__(self, args):
|
16
|
+
if args.output == "-":
|
17
|
+
fp = sys.stdout
|
18
|
+
else:
|
19
|
+
fp = open(args.output, "w")
|
20
|
+
|
21
|
+
root_s = DvFlowSchema.model_json_schema(
|
22
|
+
ref_template="#/defs/{model}"
|
23
|
+
)
|
24
|
+
pkg_s = PackageDef.model_json_schema(
|
25
|
+
ref_template="#/defs/{model}"
|
26
|
+
)
|
27
|
+
frag_s = FragmentDef.model_json_schema(
|
28
|
+
ref_template="#/defs/{model}"
|
29
|
+
)
|
30
|
+
|
31
|
+
defs = {}
|
32
|
+
print("root_s keys: %s" % " ".join(root_s.keys()))
|
33
|
+
print("root_s defs: %s" % " ".join(root_s["$defs"].keys()))
|
34
|
+
defs.update(root_s["$defs"])
|
35
|
+
# defs.update(pkg_s["$defs"])
|
36
|
+
# defs.update(frag_s["$defs"])
|
37
|
+
|
38
|
+
for td in defs.keys():
|
39
|
+
defs[td]["$$target"] = "#/defs/%s" % td
|
40
|
+
|
41
|
+
root = {
|
42
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
43
|
+
"$id": "https://dv-flow.github.io/flow.dv.schema.json",
|
44
|
+
"title": "DV Flow-specification schema",
|
45
|
+
"description": "Flow-specification schema",
|
46
|
+
"type": "object",
|
47
|
+
"properties": {
|
48
|
+
"package": {
|
49
|
+
"$ref": "#/defs/PackageDef",
|
50
|
+
"title": "Package Definition",
|
51
|
+
"description": "Package Definition"
|
52
|
+
},
|
53
|
+
"fragment": {
|
54
|
+
"$ref": "#/defs/FragmentDef"
|
55
|
+
}
|
56
|
+
},
|
57
|
+
"defs": defs,
|
58
|
+
}
|
59
|
+
|
60
|
+
fp.write(json.dumps(root, indent=2))
|
61
|
+
|
62
|
+
if fp != sys.stdout:
|
63
|
+
fp.close()
|
@@ -21,7 +21,7 @@
|
|
21
21
|
#****************************************************************************
|
22
22
|
import os
|
23
23
|
import yaml
|
24
|
-
from
|
24
|
+
from ..package_def import PackageDef
|
25
25
|
|
26
26
|
def loadProjPkgDef(path):
|
27
27
|
"""Locates the project's flow spec and returns the PackageDef"""
|
@@ -0,0 +1,57 @@
|
|
1
|
+
dv_flow/mgr/__init__.py,sha256=EL7krYGBmN53z3HKvdrIiyHTD4TRx94LegCgx8whUAo,1130
|
2
|
+
dv_flow/mgr/__main__.py,sha256=ExLZCOjDZtxqPk_SSF5SZKkbYUjMmVca4sT2OeePv10,3437
|
3
|
+
dv_flow/mgr/eval_jq.py,sha256=bRsHtaN51qIOiZK1VJV52W0-vj5VH0nQ7XIFebZi5kI,1129
|
4
|
+
dv_flow/mgr/expr_eval.py,sha256=N_8hRIgzJK9JVqhRt8F9rc4S7AAdKHMMltafqk6KhJs,3113
|
5
|
+
dv_flow/mgr/expr_parser.py,sha256=P6u2FdSXeZbdamC3zpEnYKLcK2RULQJfSoev2Ol75fE,6543
|
6
|
+
dv_flow/mgr/fileset.py,sha256=4izm4-qldWLiZxWDUa5Em0iFizzS-S-O0YU6zvtbUUs,1264
|
7
|
+
dv_flow/mgr/fragment_def.py,sha256=AHx3ITbiNbGCzlDk5FM8Iimm0GJnWXDDRAoRC1b41jM,1647
|
8
|
+
dv_flow/mgr/out,sha256=d8GGBi3J43fhdLBlnsUbzBfRe0TD0QTP3nOTz54l2bI,200
|
9
|
+
dv_flow/mgr/package.py,sha256=9FhOu1hKYKzlD88zehwrI6KAcs1E7TbXDnq4v54dqDQ,1701
|
10
|
+
dv_flow/mgr/package_def.py,sha256=L6KzBLSgArDgKPdjRAkkkq1c771BwV0NU-fMZRMMwws,20581
|
11
|
+
dv_flow/mgr/package_import_spec.py,sha256=aZMpnS9a5NFY76_pYXEuO3-Mkc_xFzy73fdrUe_54Dc,1760
|
12
|
+
dv_flow/mgr/param.py,sha256=kkxMRGf6mPjSZJsjgLKH2vJL62Sn0ZESvjBLkEYOp20,1386
|
13
|
+
dv_flow/mgr/param_def.py,sha256=mkAw3DanIxcVWRYeh9lUAfUMkpqDFly_Ku_iobr4ix8,1745
|
14
|
+
dv_flow/mgr/param_ref_eval.py,sha256=5yH37oIX6f2qmk7GfRgNT5qZx0jm3CJFgB9lLDZZ1yQ,1981
|
15
|
+
dv_flow/mgr/parsetab.py,sha256=I-p3nC60t9jiNtPhKyl_sE92SiP96zJLnNdydcLy33g,3780
|
16
|
+
dv_flow/mgr/pkg_rgy.py,sha256=d1nIjRm3ymMNJT-yiMDxCS6bFisTPvLMqh5VrfsHVKM,5404
|
17
|
+
dv_flow/mgr/task_data.py,sha256=lN7Iq8YTitEMGG4rZqYQi6Ri2HuPgBQ5oGQbW-63T8c,12436
|
18
|
+
dv_flow/mgr/task_def.py,sha256=TlDXDfmPKBewDIT0IIwNEaaT-trbeEtTnoPSKM6te7k,3474
|
19
|
+
dv_flow/mgr/task_graph_builder.py,sha256=3jDlC6UinOHNZO1scO4g6bdDdLZKJEjtexxV9RXy0_4,14371
|
20
|
+
dv_flow/mgr/task_graph_dot_writer.py,sha256=GxqiYwQJbFgUQdnPCS9vpIYmYFbSXwnXCSbGmjbxC3M,2418
|
21
|
+
dv_flow/mgr/task_listener_log.py,sha256=hrJEjSRXXoovDTcD1Cmhi3Spzw7uEJ-WP6tv6JUaa6s,4060
|
22
|
+
dv_flow/mgr/task_node.py,sha256=mMQlvYLxBBlWpZD-D97th2Hzy4T9E5i4H3V_i9bFxcM,3431
|
23
|
+
dv_flow/mgr/task_node_compound.py,sha256=y8_jzsfT9Vnm-tCWc_-hFHFoSat95zBXFibySu38YRA,1696
|
24
|
+
dv_flow/mgr/task_node_ctor.py,sha256=COFGvm5PR2B92H3uW1yhDIUCmppo9U4IfOcv_Jrsreo,3952
|
25
|
+
dv_flow/mgr/task_node_ctor_compound.py,sha256=inJeqOtlkVa7QRCzktqvVkkZ0vZALHFadIGlRZyDTD8,4006
|
26
|
+
dv_flow/mgr/task_node_ctor_compound_proxy.py,sha256=fkH_b35xE0dABbRn9Boa80WWx_tR4L9v1mhX6faefpg,1999
|
27
|
+
dv_flow/mgr/task_node_ctor_def_base.py,sha256=C2EeKgjeHB9xdC7nkLMBOcektwDoLhdP-4wQLY8OZ4g,1562
|
28
|
+
dv_flow/mgr/task_node_ctor_proxy.py,sha256=e1pfLBnJHAgQvkyNcB8sKw5DJdAPRphQz1-DT9Oheho,2017
|
29
|
+
dv_flow/mgr/task_node_ctor_task.py,sha256=9HT39F3KcEpnOBd0SbUqE6FaeSY5fFp_tN1bzGNfFKk,2237
|
30
|
+
dv_flow/mgr/task_node_ctor_wrapper.py,sha256=fRwO2RRJbt7IB1Ziwobmg0-nU5vFYsXoNV4IXfsS7mw,3435
|
31
|
+
dv_flow/mgr/task_node_leaf.py,sha256=52qv1hwp5FLG9PuPvYVPLlTdzi1TcG4OTqMZC54iIwc,6481
|
32
|
+
dv_flow/mgr/task_output.py,sha256=ZwyvwnYj_gHOEFAEOH3m24Xfc4Cn77hb1j7LkX8_3C4,1086
|
33
|
+
dv_flow/mgr/task_params_ctor.py,sha256=BPkbnoCtzhCxc1g8CJ6VimCcm5UAu92PXeDMhQ4lYsQ,1957
|
34
|
+
dv_flow/mgr/task_runner.py,sha256=6Tq-ADmCjWzDmUktHs0yHsmJovUXAxcbZdOuJovdR2M,9117
|
35
|
+
dv_flow/mgr/type.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
|
+
dv_flow/mgr/type_def.py,sha256=NDeyplKrPnWwEv4yHkhXEMK9d9j39b5MOeLB-1Mchqo,1095
|
37
|
+
dv_flow/mgr/cmds/cmd_graph.py,sha256=Ykw__EdwamDBZZKxQZVbtMtFl7koq5dJMShTBXSM2pk,2672
|
38
|
+
dv_flow/mgr/cmds/cmd_run.py,sha256=VL0LU0zYnClQ8Id30sxMN_fHJzQFJsOuj7qDG7GTT60,3198
|
39
|
+
dv_flow/mgr/cmds/cmd_show.py,sha256=CZlgwB3Hcu-6HS-diqnWjCcPPpO-kjIIXU3DgWXvsf4,3773
|
40
|
+
dv_flow/mgr/share/flow.json,sha256=lNmZex9NXkYbyb2aZseQfUOkV9CMyfH0iLODEI7EPBw,5096
|
41
|
+
dv_flow/mgr/std/create_file.py,sha256=wmn5N_mObx_wr2LPdKOVbNmdM71hhs3UXOv6Ap9l3Ts,2726
|
42
|
+
dv_flow/mgr/std/exec.py,sha256=UChqa_tAjvdB1NjqTsvlPgFomP8hMsX2rAOPyUonNpk,3896
|
43
|
+
dv_flow/mgr/std/fileset.py,sha256=5IxS6T-x0wzA6fdEQcfHZ9kNP8IpH9hfJ3UMhL4A6Iw,3911
|
44
|
+
dv_flow/mgr/std/flow.dv,sha256=rl0VZt_H-TyIJq0iERai07aDDZHI86mNozs4gUxidDA,3759
|
45
|
+
dv_flow/mgr/std/message.py,sha256=0JHLErg8whqMLAasG1fumZ2O7R7WNWeNQ9ibJaLDpVY,1029
|
46
|
+
dv_flow/mgr/std/task_null.py,sha256=dw6LXBXVwth6gLPeduDvlz5znAhcVpDH8r1DticD-0w,1041
|
47
|
+
dv_flow/mgr/util/__init__.py,sha256=6uuA6z5cKS2hcjJw6YyEM2M79g6OpXb6tZF_Gku-AGU,22
|
48
|
+
dv_flow/mgr/util/__main__.py,sha256=F0LXpCDpYTPalSo0dc1h_qZkip5v1AZYYh-vcYbh5s0,983
|
49
|
+
dv_flow/mgr/util/util.py,sha256=yg9oTPRiO87mkCSOQpOtlG9vyKPQzY3qp4OJkEMbWyY,1443
|
50
|
+
dv_flow/mgr/util/cmds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
51
|
+
dv_flow/mgr/util/cmds/cmd_schema.py,sha256=lrEI-Jwb8j4I4yYOn9hq7_7NYbK8leVxLesrHyEWm-E,1879
|
52
|
+
dv_flow_mgr-0.0.1.14097297609a1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
53
|
+
dv_flow_mgr-0.0.1.14097297609a1.dist-info/METADATA,sha256=IlTwE8Jw4l2MnwXv0JkjznsQabW7cYXyVi0qTop1uUU,13336
|
54
|
+
dv_flow_mgr-0.0.1.14097297609a1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
55
|
+
dv_flow_mgr-0.0.1.14097297609a1.dist-info/entry_points.txt,sha256=1roy8wAFM48LabOvr6jiOw0MUs-qE8X3Vf8YykPazxk,50
|
56
|
+
dv_flow_mgr-0.0.1.14097297609a1.dist-info/top_level.txt,sha256=amfVTkggzYPtWwLqNmRukfz1Buu0pGS2SrYBBLhXm04,8
|
57
|
+
dv_flow_mgr-0.0.1.14097297609a1.dist-info/RECORD,,
|
dv_flow/mgr/task.py
DELETED
@@ -1,181 +0,0 @@
|
|
1
|
-
#****************************************************************************
|
2
|
-
#* task.py
|
3
|
-
#*
|
4
|
-
#* Copyright 2023-2025 Matthew Ballance and Contributors
|
5
|
-
#*
|
6
|
-
#* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
7
|
-
#* not use this file except in compliance with the License.
|
8
|
-
#* You may obtain a copy of the License at:
|
9
|
-
#*
|
10
|
-
#* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#*
|
12
|
-
#* Unless required by applicable law or agreed to in writing, software
|
13
|
-
#* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
#* See the License for the specific language governing permissions and
|
16
|
-
#* limitations under the License.
|
17
|
-
#*
|
18
|
-
#* Created on:
|
19
|
-
#* Author:
|
20
|
-
#*
|
21
|
-
#****************************************************************************
|
22
|
-
import os
|
23
|
-
import json
|
24
|
-
import dataclasses as dc
|
25
|
-
import logging
|
26
|
-
from pydantic import BaseModel
|
27
|
-
from typing import Any, Callable, ClassVar, Dict, List, Tuple
|
28
|
-
from .task_data import TaskData, TaskDataInput, TaskDataOutput, TaskDataResult
|
29
|
-
from .task_ctor import TaskParamsCtor
|
30
|
-
from .task_params_ctor import TaskParamsCtor
|
31
|
-
from .task_runner import TaskRunner
|
32
|
-
|
33
|
-
# @dc.dataclass
|
34
|
-
# class TaskSpec(object):
|
35
|
-
# name : str
|
36
|
-
|
37
|
-
# class TaskParams(BaseModel):
|
38
|
-
# pass
|
39
|
-
|
40
|
-
|
41
|
-
# @dc.dataclass
|
42
|
-
# class TaskCtorParam(TaskCtor):
|
43
|
-
# params : Dict[str,Any] = dc.field(default_factory=dict)
|
44
|
-
|
45
|
-
# _log : ClassVar = logging.getLogger("TaskCtorParam")
|
46
|
-
|
47
|
-
# def mkTask(self, name : str, depends, rundir, srcdir=None, params=None):
|
48
|
-
# self._log.debug("--> %s::mkTask" % self.name)
|
49
|
-
# if params is None:
|
50
|
-
# params = self.mkParams()
|
51
|
-
# if srcdir is None:
|
52
|
-
# srcdir = self.srcdir
|
53
|
-
|
54
|
-
# ret = self.uses.mkTask(name, depends, rundir, srcdir, params)
|
55
|
-
|
56
|
-
# self.applyParams(ret.params)
|
57
|
-
# self._log.debug("<-- %s::mkTask" % self.name)
|
58
|
-
|
59
|
-
# return ret
|
60
|
-
|
61
|
-
# def applyParams(self, params):
|
62
|
-
# self._log.debug("--> %s::applyParams: %s %s" % (self.name, str(type(self.params)), str(type(params))))
|
63
|
-
# if self.params is not None:
|
64
|
-
# for k,v in self.params.items():
|
65
|
-
# self._log.debug(" change %s %s=>%s" % (
|
66
|
-
# k,
|
67
|
-
# str(getattr(params, k)),
|
68
|
-
# str(v)))
|
69
|
-
# setattr(params, k, v)
|
70
|
-
# else:
|
71
|
-
# self._log.debug(" no params")
|
72
|
-
# self._log.debug("<-- %s::applyParams: %s" % (self.name, str(self.params)))
|
73
|
-
|
74
|
-
# @dc.dataclass
|
75
|
-
# class TaskCtorParamCls(TaskCtor):
|
76
|
-
# params_ctor : Callable = None
|
77
|
-
|
78
|
-
# _log : ClassVar = logging.getLogger("TaskCtorParamType")
|
79
|
-
|
80
|
-
# def mkParams(self):
|
81
|
-
# self._log.debug("--> %s::mkParams" % str(self.name))
|
82
|
-
# params = self.params_ctor()
|
83
|
-
# self._log.debug("<-- %s::mkParams: %s" % (str(self.name), str(type(params))))
|
84
|
-
# return params
|
85
|
-
|
86
|
-
# @dc.dataclass
|
87
|
-
# class TaskCtorCls(TaskCtor):
|
88
|
-
# task_ctor : Callable = None
|
89
|
-
|
90
|
-
# _log : ClassVar = logging.getLogger("TaskCtorCls")
|
91
|
-
|
92
|
-
# def mkTask(self, name : str, depends, rundir, srcdir=None, params=None):
|
93
|
-
# self._log.debug("--> %s::mkTask (%s) srcdir=%s" % (self.name, str(self.task_ctor), srcdir))
|
94
|
-
|
95
|
-
# if srcdir is None:
|
96
|
-
# srcdir = self.srcdir
|
97
|
-
|
98
|
-
# if params is None:
|
99
|
-
# params = self.mkParams()
|
100
|
-
|
101
|
-
# ret = self.task_ctor(
|
102
|
-
# name=name,
|
103
|
-
# depends=depends,
|
104
|
-
# rundir=rundir,
|
105
|
-
# srcdir=srcdir,
|
106
|
-
# params=params)
|
107
|
-
|
108
|
-
# # Update parameters on the way back
|
109
|
-
# self.applyParams(ret.params)
|
110
|
-
|
111
|
-
# self._log.debug("<-- %s::mkTask" % self.name)
|
112
|
-
# return ret
|
113
|
-
|
114
|
-
# @dc.dataclass
|
115
|
-
# class TaskCtorProxy(TaskCtor):
|
116
|
-
# task_ctor : TaskCtor = None
|
117
|
-
# param_ctor : Callable = None
|
118
|
-
|
119
|
-
# _log : ClassVar = logging.getLogger("TaskCtorProxy")
|
120
|
-
|
121
|
-
# def mkTask(self, *args, **kwargs):
|
122
|
-
# self._log.debug("--> %s::mkTask" % self.name)
|
123
|
-
# ret = self.task_ctor.mkTask(*args, **kwargs)
|
124
|
-
# self._log.debug("<-- %s::mkTask" % self.name)
|
125
|
-
# return ret
|
126
|
-
|
127
|
-
# def mkParams(self, params=None):
|
128
|
-
# self._log.debug("--> %s::mkParams: %s" % (self.name, str(self.params)))
|
129
|
-
|
130
|
-
# if params is None and self.param_ctor is not None:
|
131
|
-
# params = self.param_ctor()
|
132
|
-
|
133
|
-
# params = self.task_ctor.mkParams(params)
|
134
|
-
|
135
|
-
# if self.params is not None:
|
136
|
-
# for k,v in self.params.items():
|
137
|
-
# self._log.debug(" change %s %s=>%s" % (
|
138
|
-
# k,
|
139
|
-
# str(getattr(params, k)),
|
140
|
-
# str(v)))
|
141
|
-
# setattr(params, k, v)
|
142
|
-
# self._log.debug("<-- %s::mkParams: %s" % (self.name, str(self.params)))
|
143
|
-
# return params
|
144
|
-
|
145
|
-
|
146
|
-
@dc.dataclass
|
147
|
-
class Task(object):
|
148
|
-
"""Executable view of a task"""
|
149
|
-
# Ctor fields -- must specify on construction
|
150
|
-
name : str
|
151
|
-
srcdir : str
|
152
|
-
params : TaskParamsCtor
|
153
|
-
|
154
|
-
# Runtime fields -- these get populated during execution
|
155
|
-
changed : bool = False
|
156
|
-
needs : List['Task'] = dc.field(default_factory=list)
|
157
|
-
dependents : List['Task'] = dc.field(default_factory=list)
|
158
|
-
rundir : str = dc.field(default=None)
|
159
|
-
output : TaskDataOutput = dc.field(default=None)
|
160
|
-
|
161
|
-
_log : ClassVar = logging.getLogger("Task")
|
162
|
-
|
163
|
-
async def run(self,
|
164
|
-
runner : 'TaskRunner',
|
165
|
-
input : TaskDataInput) -> TaskDataResult:
|
166
|
-
raise NotImplementedError("TaskImpl.run() not implemented")
|
167
|
-
|
168
|
-
@staticmethod
|
169
|
-
def ctor(paramT):
|
170
|
-
def wrapper(T):
|
171
|
-
def mk_task(name, srcdir, params):
|
172
|
-
return T(name, srcdir, params)
|
173
|
-
def mk_params(**params):
|
174
|
-
ctor = TaskParamsCtor(paramT)
|
175
|
-
ctor.values.append(paramT(**params))
|
176
|
-
return ctor
|
177
|
-
T.mkTask = mk_task
|
178
|
-
T.mkParams = mk_params
|
179
|
-
return T
|
180
|
-
return wrapper
|
181
|
-
|
dv_flow/mgr/task_ctor.py
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
#****************************************************************************
|
2
|
-
#* task_ctor.py
|
3
|
-
#*
|
4
|
-
#* Copyright 2023-2025 Matthew Ballance and Contributors
|
5
|
-
#*
|
6
|
-
#* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
7
|
-
#* not use this file except in compliance with the License.
|
8
|
-
#* You may obtain a copy of the License at:
|
9
|
-
#*
|
10
|
-
#* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#*
|
12
|
-
#* Unless required by applicable law or agreed to in writing, software
|
13
|
-
#* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
#* See the License for the specific language governing permissions and
|
16
|
-
#* limitations under the License.
|
17
|
-
#*
|
18
|
-
#* Created on:
|
19
|
-
#* Author:
|
20
|
-
#*
|
21
|
-
#****************************************************************************
|
22
|
-
import os
|
23
|
-
import json
|
24
|
-
import dataclasses as dc
|
25
|
-
import logging
|
26
|
-
from pydantic import BaseModel
|
27
|
-
from typing import Any, Callable, ClassVar, Dict, List, Tuple
|
28
|
-
from .task_data import TaskDataOutput, TaskDataResult
|
29
|
-
|
30
|
-
# TaskParamsCtor accepts an evaluation context and returns a task parameter object
|
31
|
-
TaskParamsCtor = Callable[[object], Any]
|
32
|
-
|
33
|
-
@dc.dataclass
|
34
|
-
class TaskCtor(object):
|
35
|
-
name : str
|
36
|
-
uses : 'TaskCtor' = None
|
37
|
-
srcdir : str = None
|
38
|
-
|
39
|
-
_log : ClassVar = logging.getLogger("TaskCtor")
|
40
|
-
|
41
|
-
def mkTask(self, name : str, srcdir=None) -> 'TaskNode':
|
42
|
-
"""Creates a task object"""
|
43
|
-
if srcdir is None:
|
44
|
-
srcdir = self.srcdir
|
45
|
-
|
46
|
-
if self.uses is not None:
|
47
|
-
return self.uses.mkTask(name, srcdir)
|
48
|
-
else:
|
49
|
-
raise NotImplementedError("TaskCtor.mkTask() not implemented for %s" % str(type(self)))
|
50
|
-
|
51
|
-
def mkParams(self, params=None) -> TaskParamsCtor:
|
52
|
-
"""Creates a list of task-parameter objects used produce the params object"""
|
53
|
-
self._log.debug("--> %s::mkParams" % self.name)
|
54
|
-
if self.uses is not None:
|
55
|
-
params = self.uses.mkParams()
|
56
|
-
else:
|
57
|
-
params = TaskParams()
|
58
|
-
self._log.debug("<-- %s::mkParams: %s" % (self.name, str(params)))
|
59
|
-
|
60
|
-
return params
|
61
|
-
|
62
|
-
def applyParams(self, params):
|
63
|
-
if self.uses is not None:
|
64
|
-
self.uses.applyParams(params)
|