tracdap-runtime 0.8.0rc1__py3-none-any.whl → 0.9.0b1__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.
- tracdap/rt/_impl/core/data.py +578 -33
- tracdap/rt/_impl/core/repos.py +7 -0
- tracdap/rt/_impl/core/storage.py +10 -3
- tracdap/rt/_impl/core/util.py +54 -11
- tracdap/rt/_impl/exec/dev_mode.py +122 -100
- tracdap/rt/_impl/exec/engine.py +178 -109
- tracdap/rt/_impl/exec/functions.py +218 -257
- tracdap/rt/_impl/exec/graph.py +140 -125
- tracdap/rt/_impl/exec/graph_builder.py +411 -449
- tracdap/rt/_impl/grpc/codec.py +4 -2
- tracdap/rt/_impl/grpc/server.py +7 -7
- tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.py +25 -18
- tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.pyi +27 -9
- tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.py +1 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/config_pb2.py +40 -0
- tracdap/rt/_impl/grpc/tracdap/metadata/config_pb2.pyi +62 -0
- tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.py +1 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.py +1 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.py +1 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.py +1 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.py +67 -63
- tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.pyi +11 -2
- tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.py +1 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.py +3 -3
- tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.pyi +4 -0
- tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.py +8 -6
- tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.pyi +8 -2
- tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.py +18 -5
- tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.pyi +42 -2
- tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.py +1 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/storage_pb2.py +11 -9
- tracdap/rt/_impl/grpc/tracdap/metadata/storage_pb2.pyi +11 -2
- tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.py +1 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.py +1 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.py +1 -1
- tracdap/rt/_impl/runtime.py +8 -0
- tracdap/rt/_plugins/repo_git.py +56 -11
- tracdap/rt/_version.py +1 -1
- tracdap/rt/config/__init__.py +6 -4
- tracdap/rt/config/common.py +5 -0
- tracdap/rt/config/dynamic.py +28 -0
- tracdap/rt/config/job.py +13 -3
- tracdap/rt/config/result.py +8 -4
- tracdap/rt/config/runtime.py +2 -0
- tracdap/rt/metadata/__init__.py +37 -30
- tracdap/rt/metadata/config.py +95 -0
- tracdap/rt/metadata/job.py +2 -0
- tracdap/rt/metadata/object.py +6 -0
- tracdap/rt/metadata/object_id.py +4 -0
- tracdap/rt/metadata/resource.py +41 -1
- tracdap/rt/metadata/storage.py +9 -0
- {tracdap_runtime-0.8.0rc1.dist-info → tracdap_runtime-0.9.0b1.dist-info}/METADATA +5 -2
- {tracdap_runtime-0.8.0rc1.dist-info → tracdap_runtime-0.9.0b1.dist-info}/RECORD +56 -52
- {tracdap_runtime-0.8.0rc1.dist-info → tracdap_runtime-0.9.0b1.dist-info}/WHEEL +1 -1
- {tracdap_runtime-0.8.0rc1.dist-info → tracdap_runtime-0.9.0b1.dist-info/licenses}/LICENSE +0 -0
- {tracdap_runtime-0.8.0rc1.dist-info → tracdap_runtime-0.9.0b1.dist-info}/top_level.txt +0 -0
tracdap/rt/_impl/exec/graph.py
CHANGED
@@ -13,18 +13,18 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
import typing as
|
17
|
-
import dataclasses as
|
16
|
+
import typing as _tp
|
17
|
+
import dataclasses as _dc
|
18
18
|
|
19
19
|
import tracdap.rt._impl.core.data as _data
|
20
|
-
import tracdap.rt.metadata as
|
21
|
-
import tracdap.rt.config as
|
20
|
+
import tracdap.rt.metadata as _meta
|
21
|
+
import tracdap.rt.config as _cfg
|
22
22
|
|
23
23
|
|
24
|
-
_T =
|
24
|
+
_T = _tp.TypeVar('_T')
|
25
25
|
|
26
26
|
|
27
|
-
@
|
27
|
+
@_dc.dataclass(frozen=True)
|
28
28
|
class NodeNamespace:
|
29
29
|
|
30
30
|
__ROOT = None
|
@@ -36,7 +36,7 @@ class NodeNamespace:
|
|
36
36
|
return cls.__ROOT
|
37
37
|
|
38
38
|
name: str
|
39
|
-
parent: "
|
39
|
+
parent: "_tp.Optional[NodeNamespace]" = _dc.field(default_factory=lambda: NodeNamespace.root())
|
40
40
|
|
41
41
|
def __str__(self):
|
42
42
|
if self is self.__ROOT:
|
@@ -56,17 +56,17 @@ class NodeNamespace:
|
|
56
56
|
return [self.name] + self.parent.components()
|
57
57
|
|
58
58
|
|
59
|
-
@
|
60
|
-
class NodeId(
|
59
|
+
@_dc.dataclass(frozen=True)
|
60
|
+
class NodeId(_tp.Generic[_T]):
|
61
61
|
|
62
62
|
@staticmethod
|
63
|
-
def of(name: str, namespace: NodeNamespace, result_type:
|
63
|
+
def of(name: str, namespace: NodeNamespace, result_type: _tp.Type[_T]) -> "NodeId[_T]":
|
64
64
|
return NodeId(name, namespace, result_type)
|
65
65
|
|
66
66
|
name: str
|
67
67
|
namespace: NodeNamespace
|
68
68
|
|
69
|
-
result_type:
|
69
|
+
result_type: _tp.Type[_T] = _dc.field(default=type(None), init=True, compare=False, hash=False)
|
70
70
|
|
71
71
|
def __str__(self):
|
72
72
|
return f"{self.name} / {self.namespace}"
|
@@ -75,14 +75,14 @@ class NodeId(tp.Generic[_T]):
|
|
75
75
|
return f"{self.name} / {repr(self.namespace)}"
|
76
76
|
|
77
77
|
|
78
|
-
@
|
78
|
+
@_dc.dataclass(frozen=True)
|
79
79
|
class DependencyType:
|
80
80
|
|
81
81
|
immediate: bool = True
|
82
82
|
tolerant: bool = False
|
83
83
|
|
84
|
-
HARD: "
|
85
|
-
TOLERANT: "
|
84
|
+
HARD: "_tp.ClassVar[DependencyType]"
|
85
|
+
TOLERANT: "_tp.ClassVar[DependencyType]"
|
86
86
|
|
87
87
|
|
88
88
|
DependencyType.HARD = DependencyType(immediate=True, tolerant=False)
|
@@ -91,31 +91,31 @@ DependencyType.TOLERANT = DependencyType(immediate=True, tolerant=True)
|
|
91
91
|
DependencyType.DELAYED = DependencyType(immediate=False, tolerant=False)
|
92
92
|
|
93
93
|
|
94
|
-
@
|
94
|
+
@_dc.dataclass(frozen=True)
|
95
95
|
class Dependency:
|
96
96
|
|
97
97
|
node_id: NodeId
|
98
98
|
dependency_type: DependencyType
|
99
99
|
|
100
100
|
|
101
|
-
@
|
102
|
-
class Node(
|
101
|
+
@_dc.dataclass(frozen=True)
|
102
|
+
class Node(_tp.Generic[_T]):
|
103
103
|
|
104
104
|
"""A node in the TRAC execution graph"""
|
105
105
|
|
106
106
|
id: NodeId[_T]
|
107
107
|
"""ID of this node"""
|
108
108
|
|
109
|
-
dependencies:
|
109
|
+
dependencies: _tp.Dict[NodeId, DependencyType] = _dc.field(init=False, default_factory=dict)
|
110
110
|
"""Set of node IDs that are dependencies for this node"""
|
111
111
|
|
112
|
-
bundle_result: bool =
|
112
|
+
bundle_result: bool = _dc.field(init=False, default=False)
|
113
113
|
"""Flag indicating whether the result of this node is a bundle"""
|
114
114
|
|
115
|
-
bundle_namespace:
|
115
|
+
bundle_namespace: _tp.Optional[NodeNamespace] = _dc.field(init=False, default=None)
|
116
116
|
"""If the result is a bundle, indicates the namespace that the bundle will be unpacked into"""
|
117
117
|
|
118
|
-
def _node_dependencies(self) ->
|
118
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
119
119
|
return {}
|
120
120
|
|
121
121
|
|
@@ -129,11 +129,11 @@ def _node_type(node_class):
|
|
129
129
|
|
130
130
|
class NodeBuilder(Node):
|
131
131
|
|
132
|
-
explicit_deps:
|
132
|
+
explicit_deps: _dc.InitVar[_tp.List[NodeId]] = None
|
133
133
|
|
134
|
-
bundle:
|
134
|
+
bundle: _dc.InitVar[NodeNamespace] = None
|
135
135
|
|
136
|
-
def __post_init__(self, explicit_deps:
|
136
|
+
def __post_init__(self, explicit_deps: _tp.List[NodeId], bundle: NodeNamespace):
|
137
137
|
dependencies = self._node_dependencies()
|
138
138
|
if explicit_deps:
|
139
139
|
dependencies.update({dep_id: DependencyType.HARD for dep_id in explicit_deps})
|
@@ -148,37 +148,57 @@ def _node_type(node_class):
|
|
148
148
|
|
149
149
|
node_class.__annotations__.update(NodeBuilder.__annotations__)
|
150
150
|
|
151
|
-
return
|
151
|
+
return _dc.dataclass(frozen=True)(node_class)
|
152
152
|
|
153
153
|
|
154
|
-
NodeMap =
|
154
|
+
NodeMap = _tp.Dict[NodeId, Node]
|
155
155
|
|
156
156
|
|
157
|
-
@
|
157
|
+
@_dc.dataclass(frozen=True)
|
158
|
+
class GraphContext:
|
159
|
+
|
160
|
+
job_id: _meta.TagHeader
|
161
|
+
job_namespace: NodeNamespace
|
162
|
+
ctx_namespace: NodeNamespace
|
163
|
+
|
164
|
+
storage_config: _cfg.StorageConfig
|
165
|
+
|
166
|
+
|
167
|
+
@_dc.dataclass(frozen=True)
|
158
168
|
class Graph:
|
159
169
|
|
160
170
|
nodes: NodeMap
|
161
171
|
root_id: NodeId
|
162
172
|
|
163
173
|
|
164
|
-
@
|
174
|
+
@_dc.dataclass(frozen=False)
|
165
175
|
class GraphSection:
|
166
176
|
|
167
177
|
nodes: NodeMap
|
168
|
-
inputs:
|
169
|
-
outputs:
|
170
|
-
must_run:
|
178
|
+
inputs: _tp.Set[NodeId] = _dc.field(default_factory=set)
|
179
|
+
outputs: _tp.Set[NodeId] = _dc.field(default_factory=set)
|
180
|
+
must_run: _tp.List[NodeId] = _dc.field(default_factory=list)
|
181
|
+
|
171
182
|
|
183
|
+
@_dc.dataclass(frozen=False)
|
184
|
+
class GraphUpdate:
|
172
185
|
|
173
|
-
|
174
|
-
|
186
|
+
nodes: NodeMap = _dc.field(default_factory=dict)
|
187
|
+
dependencies: _tp.Dict[NodeId, _tp.List[Dependency]] = _dc.field(default_factory=dict)
|
175
188
|
|
176
189
|
|
177
|
-
@
|
178
|
-
class
|
190
|
+
@_dc.dataclass
|
191
|
+
class GraphOutput:
|
179
192
|
|
180
|
-
|
181
|
-
|
193
|
+
objectId: _meta.TagHeader
|
194
|
+
definition: _meta.ObjectDefinition
|
195
|
+
attrs: _tp.List[_meta.TagUpdate] = _dc.field(default_factory=list)
|
196
|
+
|
197
|
+
|
198
|
+
Bundle = _tp.Dict[str, _T]
|
199
|
+
ObjectBundle = Bundle[_meta.ObjectDefinition]
|
200
|
+
|
201
|
+
JOB_OUTPUT_TYPE = _tp.Union[GraphOutput, _data.DataSpec]
|
182
202
|
|
183
203
|
|
184
204
|
# ----------------------------------------------------------------------------------------------------------------------
|
@@ -186,6 +206,8 @@ class JobOutputs:
|
|
186
206
|
# ----------------------------------------------------------------------------------------------------------------------
|
187
207
|
|
188
208
|
|
209
|
+
# STATIC VALUES
|
210
|
+
|
189
211
|
@_node_type
|
190
212
|
class NoopNode(Node):
|
191
213
|
pass
|
@@ -196,28 +218,53 @@ class StaticValueNode(Node[_T]):
|
|
196
218
|
value: _T
|
197
219
|
|
198
220
|
|
221
|
+
# MAPPING OPERATIONS
|
222
|
+
|
199
223
|
class MappingNode(Node[_T]):
|
200
224
|
pass
|
201
225
|
|
202
226
|
|
227
|
+
@_node_type
|
228
|
+
class IdentityNode(MappingNode[_T]):
|
229
|
+
|
230
|
+
"""Map one graph node directly from another (identity function)"""
|
231
|
+
|
232
|
+
src_id: NodeId[_T]
|
233
|
+
|
234
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
235
|
+
return {self.src_id: DependencyType.HARD}
|
236
|
+
|
237
|
+
|
238
|
+
@_node_type
|
239
|
+
class KeyedItemNode(MappingNode[_T]):
|
240
|
+
|
241
|
+
"""Map a graph node from a keyed item in an existing node (dictionary lookup)"""
|
242
|
+
|
243
|
+
src_id: NodeId[Bundle[_T]]
|
244
|
+
src_item: str
|
245
|
+
|
246
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
247
|
+
return {self.src_id: DependencyType.HARD}
|
248
|
+
|
249
|
+
|
203
250
|
@_node_type
|
204
251
|
class BundleItemNode(MappingNode[_T]):
|
205
252
|
|
206
253
|
bundle_id: NodeId[Bundle[_T]]
|
207
254
|
bundle_item: str
|
208
255
|
|
209
|
-
def _node_dependencies(self) ->
|
256
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
210
257
|
return {self.bundle_id: DependencyType.HARD}
|
211
258
|
|
212
259
|
|
213
260
|
@_node_type
|
214
|
-
class ContextPushNode(Node[Bundle[
|
261
|
+
class ContextPushNode(Node[Bundle[_tp.Any]]):
|
215
262
|
|
216
263
|
"""Push a new execution context onto the stack"""
|
217
264
|
|
218
265
|
namespace: NodeNamespace
|
219
266
|
|
220
|
-
mapping:
|
267
|
+
mapping: _tp.Dict[NodeId, NodeId] = _dc.field(default_factory=dict)
|
221
268
|
"""Mapping of node IDs from the inner to the outer context (i.e. keys are in the context being pushed)"""
|
222
269
|
|
223
270
|
def _node_dependencies(self):
|
@@ -226,11 +273,11 @@ class ContextPushNode(Node[Bundle[tp.Any]]):
|
|
226
273
|
|
227
274
|
|
228
275
|
@_node_type
|
229
|
-
class ContextPopNode(Node[Bundle[
|
276
|
+
class ContextPopNode(Node[Bundle[_tp.Any]]):
|
230
277
|
|
231
278
|
namespace: NodeNamespace
|
232
279
|
|
233
|
-
mapping:
|
280
|
+
mapping: _tp.Dict[NodeId, NodeId] = _dc.field(default_factory=dict)
|
234
281
|
"""Mapping of node IDs from the inner to the outer context (i.e. keys are in the context being popped)"""
|
235
282
|
|
236
283
|
def _node_dependencies(self):
|
@@ -238,50 +285,33 @@ class ContextPopNode(Node[Bundle[tp.Any]]):
|
|
238
285
|
return {nid: DependencyType.HARD for nid in self.mapping.keys()}
|
239
286
|
|
240
287
|
|
241
|
-
|
242
|
-
class IdentityNode(MappingNode[_T]):
|
243
|
-
|
244
|
-
"""Map one graph node directly from another (identity function)"""
|
245
|
-
|
246
|
-
src_id: NodeId[_T]
|
247
|
-
|
248
|
-
def _node_dependencies(self) -> tp.Dict[NodeId, DependencyType]:
|
249
|
-
return {self.src_id: DependencyType.HARD}
|
288
|
+
# DATA HANDLING
|
250
289
|
|
251
290
|
|
252
291
|
@_node_type
|
253
|
-
class
|
254
|
-
|
255
|
-
"""Map a graph node from a keyed item in an existing node (dictionary lookup)"""
|
256
|
-
|
257
|
-
src_id: NodeId[Bundle[_T]]
|
258
|
-
src_item: str
|
259
|
-
|
260
|
-
def _node_dependencies(self) -> tp.Dict[NodeId, DependencyType]:
|
261
|
-
return {self.src_id: DependencyType.HARD}
|
262
|
-
|
263
|
-
|
264
|
-
@_node_type
|
265
|
-
class DynamicDataSpecNode(Node[_data.DataSpec]):
|
292
|
+
class DataSpecNode(Node[_data.DataSpec]):
|
266
293
|
|
267
294
|
data_view_id: NodeId[_data.DataView]
|
268
295
|
|
269
|
-
data_obj_id:
|
270
|
-
storage_obj_id:
|
296
|
+
data_obj_id: _meta.TagHeader
|
297
|
+
storage_obj_id: _meta.TagHeader
|
298
|
+
context_key: str
|
299
|
+
|
300
|
+
storage_config: _cfg.StorageConfig
|
271
301
|
|
272
|
-
prior_data_spec:
|
302
|
+
prior_data_spec: _tp.Optional[_data.DataSpec]
|
273
303
|
|
274
|
-
def _node_dependencies(self) ->
|
304
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
275
305
|
return {self.data_view_id: DependencyType.HARD}
|
276
306
|
|
277
307
|
|
278
308
|
@_node_type
|
279
309
|
class DataViewNode(Node[_data.DataView]):
|
280
310
|
|
281
|
-
schema:
|
311
|
+
schema: _meta.SchemaDefinition
|
282
312
|
root_item: NodeId[_data.DataItem]
|
283
313
|
|
284
|
-
def _node_dependencies(self) ->
|
314
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
285
315
|
return {self.root_item: DependencyType.HARD}
|
286
316
|
|
287
317
|
|
@@ -292,27 +322,10 @@ class DataItemNode(MappingNode[_data.DataItem]):
|
|
292
322
|
|
293
323
|
data_view_id: NodeId[_data.DataView]
|
294
324
|
|
295
|
-
def _node_dependencies(self) ->
|
325
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
296
326
|
return {self.data_view_id: DependencyType.HARD}
|
297
327
|
|
298
328
|
|
299
|
-
@_node_type
|
300
|
-
class DataResultNode(Node[ObjectBundle]):
|
301
|
-
|
302
|
-
# TODO: Remove this node type
|
303
|
-
# Either produce metadata in SaveDataNode, or handle DataSpec outputs in result processing nodes
|
304
|
-
|
305
|
-
output_name: str
|
306
|
-
data_save_id: NodeId[_data.DataSpec]
|
307
|
-
|
308
|
-
data_key: str = None
|
309
|
-
file_key: str = None
|
310
|
-
storage_key: str = None
|
311
|
-
|
312
|
-
def _node_dependencies(self) -> tp.Dict[NodeId, DependencyType]:
|
313
|
-
return {self.data_save_id: DependencyType.HARD}
|
314
|
-
|
315
|
-
|
316
329
|
@_node_type
|
317
330
|
class LoadDataNode(Node[_data.DataItem]):
|
318
331
|
|
@@ -321,10 +334,10 @@ class LoadDataNode(Node[_data.DataItem]):
|
|
321
334
|
The latest incarnation of the item will be loaded from any available copy
|
322
335
|
"""
|
323
336
|
|
324
|
-
spec_id:
|
325
|
-
spec:
|
337
|
+
spec_id: _tp.Optional[NodeId[_data.DataSpec]] = None
|
338
|
+
spec: _tp.Optional[_data.DataSpec] = None
|
326
339
|
|
327
|
-
def _node_dependencies(self) ->
|
340
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
328
341
|
deps = dict()
|
329
342
|
if self.spec_id is not None:
|
330
343
|
deps[self.spec_id] = DependencyType.HARD
|
@@ -340,75 +353,77 @@ class SaveDataNode(Node[_data.DataSpec]):
|
|
340
353
|
|
341
354
|
data_item_id: NodeId[_data.DataItem]
|
342
355
|
|
343
|
-
spec_id:
|
344
|
-
spec:
|
356
|
+
spec_id: _tp.Optional[NodeId[_data.DataSpec]] = None
|
357
|
+
spec: _tp.Optional[_data.DataSpec] = None
|
345
358
|
|
346
|
-
def _node_dependencies(self) ->
|
359
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
347
360
|
deps = {self.data_item_id: DependencyType.HARD}
|
348
361
|
if self.spec_id is not None:
|
349
362
|
deps[self.spec_id] = DependencyType.HARD
|
350
363
|
return deps
|
351
364
|
|
352
365
|
|
366
|
+
# MODEL EXECUTION
|
367
|
+
|
353
368
|
@_node_type
|
354
|
-
class ImportModelNode(Node[
|
369
|
+
class ImportModelNode(Node[GraphOutput]):
|
355
370
|
|
356
|
-
|
357
|
-
|
371
|
+
model_id: _meta.TagHeader
|
372
|
+
|
373
|
+
import_details: _meta.ImportModelJob
|
374
|
+
import_scope: str
|
358
375
|
|
359
376
|
|
360
377
|
@_node_type
|
361
378
|
class RunModelNode(Node[Bundle[_data.DataView]]):
|
362
379
|
|
380
|
+
model_def: _meta.ModelDefinition
|
363
381
|
model_scope: str
|
364
|
-
model_def: meta.ModelDefinition
|
365
|
-
parameter_ids: tp.FrozenSet[NodeId]
|
366
|
-
input_ids: tp.FrozenSet[NodeId]
|
367
|
-
storage_access: tp.Optional[tp.List[str]] = None
|
368
382
|
|
369
|
-
|
370
|
-
|
383
|
+
parameter_ids: _tp.FrozenSet[NodeId]
|
384
|
+
input_ids: _tp.FrozenSet[NodeId]
|
371
385
|
|
386
|
+
storage_access: _tp.Optional[_tp.List[str]] = None
|
372
387
|
|
373
|
-
|
374
|
-
class RunModelResultNode(Node[None]):
|
388
|
+
graph_context: _tp.Optional[GraphContext] = None
|
375
389
|
|
376
|
-
|
390
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
391
|
+
return {dep_id: DependencyType.HARD for dep_id in [*self.parameter_ids, *self.input_ids]}
|
377
392
|
|
378
|
-
def _node_dependencies(self) -> tp.Dict[NodeId, DependencyType]:
|
379
|
-
return {self.model_id: DependencyType.HARD}
|
380
393
|
|
394
|
+
# RESULTS PROCESSING
|
381
395
|
|
382
396
|
@_node_type
|
383
|
-
class
|
397
|
+
class JobResultNode(Node[_cfg.JobResult]):
|
398
|
+
|
399
|
+
job_id: _meta.TagHeader
|
400
|
+
result_id: _meta.TagHeader
|
384
401
|
|
385
|
-
|
402
|
+
named_outputs: _tp.Dict[str, JOB_OUTPUT_TYPE] = _dc.field(default_factory=dict)
|
403
|
+
unnamed_outputs: _tp.List[NodeId[JOB_OUTPUT_TYPE]] = _dc.field(default_factory=list)
|
386
404
|
|
387
|
-
def _node_dependencies(self) ->
|
388
|
-
dep_ids = [*self.
|
405
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
406
|
+
dep_ids = [*self.named_outputs.values(), *self.unnamed_outputs]
|
389
407
|
return {node_id: DependencyType.HARD for node_id in dep_ids}
|
390
408
|
|
391
409
|
|
392
410
|
@_node_type
|
393
|
-
class
|
411
|
+
class DynamicOutputsNode(Node["DynamicOutputsNode"]):
|
394
412
|
|
395
|
-
|
396
|
-
|
413
|
+
named_outputs: _tp.Dict[str, JOB_OUTPUT_TYPE] = _dc.field(default_factory=dict)
|
414
|
+
unnamed_outputs: _tp.List[NodeId[JOB_OUTPUT_TYPE]] = _dc.field(default_factory=list)
|
397
415
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
def _node_dependencies(self) -> tp.Dict[NodeId, DependencyType]:
|
402
|
-
dep_ids = [*self.outputs.bundles, *self.outputs.objects.values()]
|
403
|
-
if self.runtime_outputs is not None:
|
404
|
-
dep_ids.append(self.runtime_outputs)
|
416
|
+
def _node_dependencies(self) -> _tp.Dict[NodeId, DependencyType]:
|
417
|
+
dep_ids = [*self.named_outputs.values(), *self.unnamed_outputs]
|
405
418
|
return {node_id: DependencyType.HARD for node_id in dep_ids}
|
406
419
|
|
407
420
|
|
421
|
+
# MISC NODE TYPES
|
422
|
+
|
408
423
|
@_node_type
|
409
|
-
class ChildJobNode(Node[
|
424
|
+
class ChildJobNode(Node[_cfg.JobResult]):
|
410
425
|
|
411
|
-
job_id:
|
412
|
-
job_def:
|
426
|
+
job_id: _meta.TagHeader
|
427
|
+
job_def: _meta.JobDefinition
|
413
428
|
|
414
429
|
graph: Graph
|