tracdap-runtime 0.7.0rc1__py3-none-any.whl → 0.8.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/_exec/context.py +140 -64
- tracdap/rt/_exec/dev_mode.py +144 -69
- tracdap/rt/_exec/engine.py +9 -7
- tracdap/rt/_exec/functions.py +95 -33
- tracdap/rt/_exec/graph.py +22 -15
- tracdap/rt/_exec/graph_builder.py +221 -98
- tracdap/rt/_exec/runtime.py +19 -6
- tracdap/rt/_impl/data.py +86 -13
- tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.py +3 -1
- tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.pyi +8 -0
- tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.py +27 -25
- tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.pyi +14 -4
- tracdap/rt/_impl/models.py +9 -7
- tracdap/rt/_impl/static_api.py +53 -33
- tracdap/rt/_impl/util.py +1 -1
- tracdap/rt/_impl/validation.py +54 -28
- tracdap/rt/_version.py +1 -1
- tracdap/rt/api/__init__.py +6 -3
- tracdap/rt/api/file_types.py +29 -0
- tracdap/rt/api/hook.py +15 -7
- tracdap/rt/api/model_api.py +16 -0
- tracdap/rt/api/static_api.py +211 -125
- tracdap/rt/config/__init__.py +6 -6
- tracdap/rt/config/common.py +11 -1
- tracdap/rt/config/platform.py +4 -6
- tracdap/rt/launch/launch.py +9 -11
- tracdap/rt/metadata/__init__.py +10 -9
- tracdap/rt/metadata/file.py +8 -0
- tracdap/rt/metadata/model.py +12 -2
- {tracdap_runtime-0.7.0rc1.dist-info → tracdap_runtime-0.8.0b1.dist-info}/METADATA +15 -15
- {tracdap_runtime-0.7.0rc1.dist-info → tracdap_runtime-0.8.0b1.dist-info}/RECORD +34 -33
- {tracdap_runtime-0.7.0rc1.dist-info → tracdap_runtime-0.8.0b1.dist-info}/WHEEL +1 -1
- {tracdap_runtime-0.7.0rc1.dist-info → tracdap_runtime-0.8.0b1.dist-info}/LICENSE +0 -0
- {tracdap_runtime-0.7.0rc1.dist-info → tracdap_runtime-0.8.0b1.dist-info}/top_level.txt +0 -0
tracdap/rt/_impl/data.py
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
16
|
import abc
|
17
|
+
import copy
|
17
18
|
import dataclasses as dc
|
18
19
|
import typing as tp
|
19
20
|
import datetime as dt
|
@@ -42,11 +43,48 @@ import tracdap.rt._impl.util as _util
|
|
42
43
|
@dc.dataclass(frozen=True)
|
43
44
|
class DataSpec:
|
44
45
|
|
46
|
+
object_type: _meta.ObjectType
|
45
47
|
data_item: str
|
48
|
+
|
46
49
|
data_def: _meta.DataDefinition
|
50
|
+
file_def: _meta.FileDefinition
|
47
51
|
storage_def: _meta.StorageDefinition
|
48
52
|
schema_def: tp.Optional[_meta.SchemaDefinition]
|
49
53
|
|
54
|
+
@staticmethod
|
55
|
+
def create_data_spec(
|
56
|
+
data_item: str,
|
57
|
+
data_def: _meta.DataDefinition,
|
58
|
+
storage_def: _meta.StorageDefinition,
|
59
|
+
schema_def: tp.Optional[_meta.SchemaDefinition] = None) -> "DataSpec":
|
60
|
+
|
61
|
+
return DataSpec(
|
62
|
+
_meta.ObjectType.DATA, data_item,
|
63
|
+
data_def,
|
64
|
+
storage_def=storage_def,
|
65
|
+
schema_def=schema_def,
|
66
|
+
file_def=None)
|
67
|
+
|
68
|
+
@staticmethod
|
69
|
+
def create_file_spec(
|
70
|
+
data_item: str,
|
71
|
+
file_def: _meta.FileDefinition,
|
72
|
+
storage_def: _meta.StorageDefinition) -> "DataSpec":
|
73
|
+
|
74
|
+
return DataSpec(
|
75
|
+
_meta.ObjectType.FILE, data_item,
|
76
|
+
file_def=file_def,
|
77
|
+
storage_def=storage_def,
|
78
|
+
data_def=None,
|
79
|
+
schema_def=None)
|
80
|
+
|
81
|
+
@staticmethod
|
82
|
+
def create_empty_spec(object_type: _meta.ObjectType):
|
83
|
+
return DataSpec(object_type, None, None, None, None, None)
|
84
|
+
|
85
|
+
def is_empty(self):
|
86
|
+
return self.data_item is None or len(self.data_item) == 0
|
87
|
+
|
50
88
|
|
51
89
|
@dc.dataclass(frozen=True)
|
52
90
|
class DataPartKey:
|
@@ -61,44 +99,79 @@ class DataPartKey:
|
|
61
99
|
@dc.dataclass(frozen=True)
|
62
100
|
class DataItem:
|
63
101
|
|
64
|
-
|
102
|
+
object_type: _meta.ObjectType
|
103
|
+
|
104
|
+
schema: pa.Schema = None
|
65
105
|
table: tp.Optional[pa.Table] = None
|
66
106
|
batches: tp.Optional[tp.List[pa.RecordBatch]] = None
|
67
107
|
|
68
108
|
pandas: "tp.Optional[pandas.DataFrame]" = None
|
69
109
|
pyspark: tp.Any = None
|
70
110
|
|
111
|
+
raw_bytes: bytes = None
|
112
|
+
|
71
113
|
def is_empty(self) -> bool:
|
72
|
-
|
114
|
+
if self.object_type == _meta.ObjectType.FILE:
|
115
|
+
return self.raw_bytes is None or len(self.raw_bytes) == 0
|
116
|
+
else:
|
117
|
+
return self.table is None and (self.batches is None or len(self.batches) == 0)
|
73
118
|
|
74
119
|
@staticmethod
|
75
|
-
def create_empty() -> "DataItem":
|
76
|
-
|
120
|
+
def create_empty(object_type: _meta.ObjectType = _meta.ObjectType.DATA) -> "DataItem":
|
121
|
+
if object_type == _meta.ObjectType.DATA:
|
122
|
+
return DataItem(_meta.ObjectType.DATA, pa.schema([]))
|
123
|
+
else:
|
124
|
+
return DataItem(object_type)
|
125
|
+
|
126
|
+
@staticmethod
|
127
|
+
def for_file_content(raw_bytes: bytes):
|
128
|
+
return DataItem(_meta.ObjectType.FILE, raw_bytes=raw_bytes)
|
77
129
|
|
78
130
|
|
79
131
|
@dc.dataclass(frozen=True)
|
80
132
|
class DataView:
|
81
133
|
|
82
|
-
|
83
|
-
arrow_schema: pa.Schema
|
134
|
+
object_type: _meta.ObjectType
|
84
135
|
|
85
|
-
|
136
|
+
trac_schema: _meta.SchemaDefinition = None
|
137
|
+
arrow_schema: pa.Schema = None
|
138
|
+
|
139
|
+
parts: tp.Dict[DataPartKey, tp.List[DataItem]] = None
|
140
|
+
file_item: tp.Optional[DataItem] = None
|
86
141
|
|
87
142
|
@staticmethod
|
88
|
-
def create_empty() -> "DataView":
|
89
|
-
|
143
|
+
def create_empty(object_type: _meta.ObjectType = _meta.ObjectType.DATA) -> "DataView":
|
144
|
+
if object_type == _meta.ObjectType.DATA:
|
145
|
+
return DataView(object_type, _meta.SchemaDefinition(), pa.schema([]), dict())
|
146
|
+
else:
|
147
|
+
return DataView(object_type)
|
90
148
|
|
91
149
|
@staticmethod
|
92
150
|
def for_trac_schema(trac_schema: _meta.SchemaDefinition):
|
93
151
|
arrow_schema = DataMapping.trac_to_arrow_schema(trac_schema)
|
94
|
-
return DataView(trac_schema, arrow_schema, dict())
|
152
|
+
return DataView(_meta.ObjectType.DATA, trac_schema, arrow_schema, dict())
|
153
|
+
|
154
|
+
@staticmethod
|
155
|
+
def for_file_item(file_item: DataItem):
|
156
|
+
return DataView(file_item.object_type, file_item=file_item)
|
95
157
|
|
96
158
|
def with_trac_schema(self, trac_schema: _meta.SchemaDefinition):
|
97
159
|
arrow_schema = DataMapping.trac_to_arrow_schema(trac_schema)
|
98
|
-
return DataView(trac_schema, arrow_schema, self.parts)
|
160
|
+
return DataView(_meta.ObjectType.DATA, trac_schema, arrow_schema, self.parts)
|
161
|
+
|
162
|
+
def with_part(self, part_key: DataPartKey, part: DataItem):
|
163
|
+
new_parts = copy.copy(self.parts)
|
164
|
+
new_parts[part_key] = [part]
|
165
|
+
return DataView(self.object_type, self.trac_schema, self.arrow_schema, new_parts)
|
166
|
+
|
167
|
+
def with_file_item(self, file_item: DataItem):
|
168
|
+
return DataView(self.object_type, file_item=file_item)
|
99
169
|
|
100
170
|
def is_empty(self) -> bool:
|
101
|
-
|
171
|
+
if self.object_type == _meta.ObjectType.FILE:
|
172
|
+
return self.file_item is None
|
173
|
+
else:
|
174
|
+
return self.parts is None or not any(self.parts.values())
|
102
175
|
|
103
176
|
|
104
177
|
class _DataInternal:
|
@@ -293,7 +366,7 @@ class DataMapping:
|
|
293
366
|
deltas = [*prior_deltas, item]
|
294
367
|
parts = {**view.parts, part: deltas}
|
295
368
|
|
296
|
-
return DataView(view.trac_schema, view.arrow_schema, parts)
|
369
|
+
return DataView(view.object_type, view.trac_schema, view.arrow_schema, parts=parts)
|
297
370
|
|
298
371
|
@classmethod
|
299
372
|
def view_to_arrow(cls, view: DataView, part: DataPartKey) -> pa.Table:
|
@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
|
|
15
15
|
from tracdap.rt._impl.grpc.tracdap.metadata import object_id_pb2 as tracdap_dot_rt_dot___impl_dot_grpc_dot_tracdap_dot_metadata_dot_object__id__pb2
|
16
16
|
|
17
17
|
|
18
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n1tracdap/rt/_impl/grpc/tracdap/metadata/file.proto\x12\x10tracdap.metadata\x1a\x36tracdap/rt/_impl/grpc/tracdap/metadata/object_id.proto\"\x95\x01\n\x0e\x46ileDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\textension\x18\x02 \x01(\t\x12\x10\n\x08mimeType\x18\x03 \x01(\t\x12\x0c\n\x04size\x18\x04 \x01(\x04\x12\x30\n\tstorageId\x18\x05 \x01(\x0b\x32\x1d.tracdap.metadata.TagSelector\x12\x10\n\x08\x64\x61taItem\x18\x06 \x01(\tB\x1e\n\x1aorg.finos.tracdap.metadataP\x01\x62\x06proto3')
|
18
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n1tracdap/rt/_impl/grpc/tracdap/metadata/file.proto\x12\x10tracdap.metadata\x1a\x36tracdap/rt/_impl/grpc/tracdap/metadata/object_id.proto\"\x95\x01\n\x0e\x46ileDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\textension\x18\x02 \x01(\t\x12\x10\n\x08mimeType\x18\x03 \x01(\t\x12\x0c\n\x04size\x18\x04 \x01(\x04\x12\x30\n\tstorageId\x18\x05 \x01(\x0b\x32\x1d.tracdap.metadata.TagSelector\x12\x10\n\x08\x64\x61taItem\x18\x06 \x01(\t\"/\n\x08\x46ileType\x12\x11\n\textension\x18\x01 \x01(\t\x12\x10\n\x08mimeType\x18\x02 \x01(\tB\x1e\n\x1aorg.finos.tracdap.metadataP\x01\x62\x06proto3')
|
19
19
|
|
20
20
|
_globals = globals()
|
21
21
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
@@ -25,4 +25,6 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
25
25
|
_globals['DESCRIPTOR']._serialized_options = b'\n\032org.finos.tracdap.metadataP\001'
|
26
26
|
_globals['_FILEDEFINITION']._serialized_start=128
|
27
27
|
_globals['_FILEDEFINITION']._serialized_end=277
|
28
|
+
_globals['_FILETYPE']._serialized_start=279
|
29
|
+
_globals['_FILETYPE']._serialized_end=326
|
28
30
|
# @@protoc_insertion_point(module_scope)
|
@@ -20,3 +20,11 @@ class FileDefinition(_message.Message):
|
|
20
20
|
storageId: _object_id_pb2.TagSelector
|
21
21
|
dataItem: str
|
22
22
|
def __init__(self, name: _Optional[str] = ..., extension: _Optional[str] = ..., mimeType: _Optional[str] = ..., size: _Optional[int] = ..., storageId: _Optional[_Union[_object_id_pb2.TagSelector, _Mapping]] = ..., dataItem: _Optional[str] = ...) -> None: ...
|
23
|
+
|
24
|
+
class FileType(_message.Message):
|
25
|
+
__slots__ = ("extension", "mimeType")
|
26
|
+
EXTENSION_FIELD_NUMBER: _ClassVar[int]
|
27
|
+
MIMETYPE_FIELD_NUMBER: _ClassVar[int]
|
28
|
+
extension: str
|
29
|
+
mimeType: str
|
30
|
+
def __init__(self, extension: _Optional[str] = ..., mimeType: _Optional[str] = ...) -> None: ...
|
@@ -13,10 +13,12 @@ _sym_db = _symbol_database.Default()
|
|
13
13
|
|
14
14
|
|
15
15
|
from tracdap.rt._impl.grpc.tracdap.metadata import type_pb2 as tracdap_dot_rt_dot___impl_dot_grpc_dot_tracdap_dot_metadata_dot_type__pb2
|
16
|
+
from tracdap.rt._impl.grpc.tracdap.metadata import object_id_pb2 as tracdap_dot_rt_dot___impl_dot_grpc_dot_tracdap_dot_metadata_dot_object__id__pb2
|
16
17
|
from tracdap.rt._impl.grpc.tracdap.metadata import data_pb2 as tracdap_dot_rt_dot___impl_dot_grpc_dot_tracdap_dot_metadata_dot_data__pb2
|
18
|
+
from tracdap.rt._impl.grpc.tracdap.metadata import file_pb2 as tracdap_dot_rt_dot___impl_dot_grpc_dot_tracdap_dot_metadata_dot_file__pb2
|
17
19
|
|
18
20
|
|
19
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n2tracdap/rt/_impl/grpc/tracdap/metadata/model.proto\x12\x10tracdap.metadata\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/type.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/data.proto\"\xab\x02\n\x0eModelParameter\x12\x33\n\tparamType\x18\x01 \x01(\x0b\x32 .tracdap.metadata.TypeDescriptor\x12\r\n\x05label\x18\x02 \x01(\t\x12\x32\n\x0c\x64\x65\x66\x61ultValue\x18\x03 \x01(\x0b\x32\x17.tracdap.metadata.ValueH\x00\x88\x01\x01\x12\x44\n\nparamProps\x18\x04 \x03(\x0b\x32\x30.tracdap.metadata.ModelParameter.ParamPropsEntry\x1aJ\n\x0fParamPropsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.tracdap.metadata.Value:\x02\x38\x01\x42\x0f\n\r_defaultValue\"\
|
21
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n2tracdap/rt/_impl/grpc/tracdap/metadata/model.proto\x12\x10tracdap.metadata\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/type.proto\x1a\x36tracdap/rt/_impl/grpc/tracdap/metadata/object_id.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/data.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/file.proto\"\xab\x02\n\x0eModelParameter\x12\x33\n\tparamType\x18\x01 \x01(\x0b\x32 .tracdap.metadata.TypeDescriptor\x12\r\n\x05label\x18\x02 \x01(\t\x12\x32\n\x0c\x64\x65\x66\x61ultValue\x18\x03 \x01(\x0b\x32\x17.tracdap.metadata.ValueH\x00\x88\x01\x01\x12\x44\n\nparamProps\x18\x04 \x03(\x0b\x32\x30.tracdap.metadata.ModelParameter.ParamPropsEntry\x1aJ\n\x0fParamPropsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.tracdap.metadata.Value:\x02\x38\x01\x42\x0f\n\r_defaultValue\"\x8e\x03\n\x10ModelInputSchema\x12\x30\n\nobjectType\x18\x06 \x01(\x0e\x32\x1c.tracdap.metadata.ObjectType\x12\x34\n\x06schema\x18\x01 \x01(\x0b\x32\".tracdap.metadata.SchemaDefinitionH\x00\x12.\n\x08\x66ileType\x18\x07 \x01(\x0b\x32\x1a.tracdap.metadata.FileTypeH\x00\x12\x12\n\x05label\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x10\n\x08optional\x18\x03 \x01(\x08\x12\x0f\n\x07\x64ynamic\x18\x05 \x01(\x08\x12\x46\n\ninputProps\x18\x04 \x03(\x0b\x32\x32.tracdap.metadata.ModelInputSchema.InputPropsEntry\x1aJ\n\x0fInputPropsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.tracdap.metadata.Value:\x02\x38\x01\x42\r\n\x0brequirementB\x08\n\x06_label\"\x93\x03\n\x11ModelOutputSchema\x12\x30\n\nobjectType\x18\x06 \x01(\x0e\x32\x1c.tracdap.metadata.ObjectType\x12\x34\n\x06schema\x18\x01 \x01(\x0b\x32\".tracdap.metadata.SchemaDefinitionH\x00\x12.\n\x08\x66ileType\x18\x07 \x01(\x0b\x32\x1a.tracdap.metadata.FileTypeH\x00\x12\x12\n\x05label\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x10\n\x08optional\x18\x03 \x01(\x08\x12\x0f\n\x07\x64ynamic\x18\x05 \x01(\x08\x12I\n\x0boutputProps\x18\x04 \x03(\x0b\x32\x34.tracdap.metadata.ModelOutputSchema.OutputPropsEntry\x1aK\n\x10OutputPropsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.tracdap.metadata.Value:\x02\x38\x01\x42\r\n\x0brequirementB\x08\n\x06_label\"\xce\x06\n\x0fModelDefinition\x12\x10\n\x08language\x18\x01 \x01(\t\x12\x12\n\nrepository\x18\x02 \x01(\t\x12\x19\n\x0cpackageGroup\x18\n \x01(\tH\x00\x88\x01\x01\x12\x0f\n\x07package\x18\x0b \x01(\t\x12\x0f\n\x07version\x18\x06 \x01(\t\x12\x12\n\nentryPoint\x18\x05 \x01(\t\x12\x11\n\x04path\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x45\n\nparameters\x18\x07 \x03(\x0b\x32\x31.tracdap.metadata.ModelDefinition.ParametersEntry\x12=\n\x06inputs\x18\x08 \x03(\x0b\x32-.tracdap.metadata.ModelDefinition.InputsEntry\x12?\n\x07outputs\x18\t \x03(\x0b\x32..tracdap.metadata.ModelDefinition.OutputsEntry\x12Q\n\x10staticAttributes\x18\x0c \x03(\x0b\x32\x37.tracdap.metadata.ModelDefinition.StaticAttributesEntry\x12.\n\tmodelType\x18\r \x01(\x0e\x32\x1b.tracdap.metadata.ModelType\x1aS\n\x0fParametersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12/\n\x05value\x18\x02 \x01(\x0b\x32 .tracdap.metadata.ModelParameter:\x02\x38\x01\x1aQ\n\x0bInputsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x31\n\x05value\x18\x02 \x01(\x0b\x32\".tracdap.metadata.ModelInputSchema:\x02\x38\x01\x1aS\n\x0cOutputsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x32\n\x05value\x18\x02 \x01(\x0b\x32#.tracdap.metadata.ModelOutputSchema:\x02\x38\x01\x1aP\n\x15StaticAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.tracdap.metadata.Value:\x02\x38\x01\x42\x0f\n\r_packageGroupB\x07\n\x05_path*M\n\tModelType\x12\x12\n\x0eSTANDARD_MODEL\x10\x00\x12\x15\n\x11\x44\x41TA_IMPORT_MODEL\x10\x01\x12\x15\n\x11\x44\x41TA_EXPORT_MODEL\x10\x02\x42\x1e\n\x1aorg.finos.tracdap.metadataP\x01\x62\x06proto3')
|
20
22
|
|
21
23
|
_globals = globals()
|
22
24
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
@@ -38,28 +40,28 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
38
40
|
_globals['_MODELDEFINITION_OUTPUTSENTRY']._serialized_options = b'8\001'
|
39
41
|
_globals['_MODELDEFINITION_STATICATTRIBUTESENTRY']._options = None
|
40
42
|
_globals['_MODELDEFINITION_STATICATTRIBUTESENTRY']._serialized_options = b'8\001'
|
41
|
-
_globals['_MODELTYPE']._serialized_start=
|
42
|
-
_globals['_MODELTYPE']._serialized_end=
|
43
|
-
_globals['_MODELPARAMETER']._serialized_start=
|
44
|
-
_globals['_MODELPARAMETER']._serialized_end=
|
45
|
-
_globals['_MODELPARAMETER_PARAMPROPSENTRY']._serialized_start=
|
46
|
-
_globals['_MODELPARAMETER_PARAMPROPSENTRY']._serialized_end=
|
47
|
-
_globals['_MODELINPUTSCHEMA']._serialized_start=
|
48
|
-
_globals['_MODELINPUTSCHEMA']._serialized_end=
|
49
|
-
_globals['_MODELINPUTSCHEMA_INPUTPROPSENTRY']._serialized_start=
|
50
|
-
_globals['_MODELINPUTSCHEMA_INPUTPROPSENTRY']._serialized_end=
|
51
|
-
_globals['_MODELOUTPUTSCHEMA']._serialized_start=
|
52
|
-
_globals['_MODELOUTPUTSCHEMA']._serialized_end=
|
53
|
-
_globals['_MODELOUTPUTSCHEMA_OUTPUTPROPSENTRY']._serialized_start=
|
54
|
-
_globals['_MODELOUTPUTSCHEMA_OUTPUTPROPSENTRY']._serialized_end=
|
55
|
-
_globals['_MODELDEFINITION']._serialized_start=
|
56
|
-
_globals['_MODELDEFINITION']._serialized_end=
|
57
|
-
_globals['_MODELDEFINITION_PARAMETERSENTRY']._serialized_start=
|
58
|
-
_globals['_MODELDEFINITION_PARAMETERSENTRY']._serialized_end=
|
59
|
-
_globals['_MODELDEFINITION_INPUTSENTRY']._serialized_start=
|
60
|
-
_globals['_MODELDEFINITION_INPUTSENTRY']._serialized_end=
|
61
|
-
_globals['_MODELDEFINITION_OUTPUTSENTRY']._serialized_start=
|
62
|
-
_globals['_MODELDEFINITION_OUTPUTSENTRY']._serialized_end=
|
63
|
-
_globals['_MODELDEFINITION_STATICATTRIBUTESENTRY']._serialized_start=
|
64
|
-
_globals['_MODELDEFINITION_STATICATTRIBUTESENTRY']._serialized_end=
|
43
|
+
_globals['_MODELTYPE']._serialized_start=2239
|
44
|
+
_globals['_MODELTYPE']._serialized_end=2316
|
45
|
+
_globals['_MODELPARAMETER']._serialized_start=282
|
46
|
+
_globals['_MODELPARAMETER']._serialized_end=581
|
47
|
+
_globals['_MODELPARAMETER_PARAMPROPSENTRY']._serialized_start=490
|
48
|
+
_globals['_MODELPARAMETER_PARAMPROPSENTRY']._serialized_end=564
|
49
|
+
_globals['_MODELINPUTSCHEMA']._serialized_start=584
|
50
|
+
_globals['_MODELINPUTSCHEMA']._serialized_end=982
|
51
|
+
_globals['_MODELINPUTSCHEMA_INPUTPROPSENTRY']._serialized_start=883
|
52
|
+
_globals['_MODELINPUTSCHEMA_INPUTPROPSENTRY']._serialized_end=957
|
53
|
+
_globals['_MODELOUTPUTSCHEMA']._serialized_start=985
|
54
|
+
_globals['_MODELOUTPUTSCHEMA']._serialized_end=1388
|
55
|
+
_globals['_MODELOUTPUTSCHEMA_OUTPUTPROPSENTRY']._serialized_start=1288
|
56
|
+
_globals['_MODELOUTPUTSCHEMA_OUTPUTPROPSENTRY']._serialized_end=1363
|
57
|
+
_globals['_MODELDEFINITION']._serialized_start=1391
|
58
|
+
_globals['_MODELDEFINITION']._serialized_end=2237
|
59
|
+
_globals['_MODELDEFINITION_PARAMETERSENTRY']._serialized_start=1878
|
60
|
+
_globals['_MODELDEFINITION_PARAMETERSENTRY']._serialized_end=1961
|
61
|
+
_globals['_MODELDEFINITION_INPUTSENTRY']._serialized_start=1963
|
62
|
+
_globals['_MODELDEFINITION_INPUTSENTRY']._serialized_end=2044
|
63
|
+
_globals['_MODELDEFINITION_OUTPUTSENTRY']._serialized_start=2046
|
64
|
+
_globals['_MODELDEFINITION_OUTPUTSENTRY']._serialized_end=2129
|
65
|
+
_globals['_MODELDEFINITION_STATICATTRIBUTESENTRY']._serialized_start=2131
|
66
|
+
_globals['_MODELDEFINITION_STATICATTRIBUTESENTRY']._serialized_end=2211
|
65
67
|
# @@protoc_insertion_point(module_scope)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
from tracdap.rt._impl.grpc.tracdap.metadata import type_pb2 as _type_pb2
|
2
|
+
from tracdap.rt._impl.grpc.tracdap.metadata import object_id_pb2 as _object_id_pb2
|
2
3
|
from tracdap.rt._impl.grpc.tracdap.metadata import data_pb2 as _data_pb2
|
4
|
+
from tracdap.rt._impl.grpc.tracdap.metadata import file_pb2 as _file_pb2
|
3
5
|
from google.protobuf.internal import containers as _containers
|
4
6
|
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
5
7
|
from google.protobuf import descriptor as _descriptor
|
@@ -37,7 +39,7 @@ class ModelParameter(_message.Message):
|
|
37
39
|
def __init__(self, paramType: _Optional[_Union[_type_pb2.TypeDescriptor, _Mapping]] = ..., label: _Optional[str] = ..., defaultValue: _Optional[_Union[_type_pb2.Value, _Mapping]] = ..., paramProps: _Optional[_Mapping[str, _type_pb2.Value]] = ...) -> None: ...
|
38
40
|
|
39
41
|
class ModelInputSchema(_message.Message):
|
40
|
-
__slots__ = ("schema", "label", "optional", "dynamic", "inputProps")
|
42
|
+
__slots__ = ("objectType", "schema", "fileType", "label", "optional", "dynamic", "inputProps")
|
41
43
|
class InputPropsEntry(_message.Message):
|
42
44
|
__slots__ = ("key", "value")
|
43
45
|
KEY_FIELD_NUMBER: _ClassVar[int]
|
@@ -45,20 +47,24 @@ class ModelInputSchema(_message.Message):
|
|
45
47
|
key: str
|
46
48
|
value: _type_pb2.Value
|
47
49
|
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[_type_pb2.Value, _Mapping]] = ...) -> None: ...
|
50
|
+
OBJECTTYPE_FIELD_NUMBER: _ClassVar[int]
|
48
51
|
SCHEMA_FIELD_NUMBER: _ClassVar[int]
|
52
|
+
FILETYPE_FIELD_NUMBER: _ClassVar[int]
|
49
53
|
LABEL_FIELD_NUMBER: _ClassVar[int]
|
50
54
|
OPTIONAL_FIELD_NUMBER: _ClassVar[int]
|
51
55
|
DYNAMIC_FIELD_NUMBER: _ClassVar[int]
|
52
56
|
INPUTPROPS_FIELD_NUMBER: _ClassVar[int]
|
57
|
+
objectType: _object_id_pb2.ObjectType
|
53
58
|
schema: _data_pb2.SchemaDefinition
|
59
|
+
fileType: _file_pb2.FileType
|
54
60
|
label: str
|
55
61
|
optional: bool
|
56
62
|
dynamic: bool
|
57
63
|
inputProps: _containers.MessageMap[str, _type_pb2.Value]
|
58
|
-
def __init__(self, schema: _Optional[_Union[_data_pb2.SchemaDefinition, _Mapping]] = ..., label: _Optional[str] = ..., optional: bool = ..., dynamic: bool = ..., inputProps: _Optional[_Mapping[str, _type_pb2.Value]] = ...) -> None: ...
|
64
|
+
def __init__(self, objectType: _Optional[_Union[_object_id_pb2.ObjectType, str]] = ..., schema: _Optional[_Union[_data_pb2.SchemaDefinition, _Mapping]] = ..., fileType: _Optional[_Union[_file_pb2.FileType, _Mapping]] = ..., label: _Optional[str] = ..., optional: bool = ..., dynamic: bool = ..., inputProps: _Optional[_Mapping[str, _type_pb2.Value]] = ...) -> None: ...
|
59
65
|
|
60
66
|
class ModelOutputSchema(_message.Message):
|
61
|
-
__slots__ = ("schema", "label", "optional", "dynamic", "outputProps")
|
67
|
+
__slots__ = ("objectType", "schema", "fileType", "label", "optional", "dynamic", "outputProps")
|
62
68
|
class OutputPropsEntry(_message.Message):
|
63
69
|
__slots__ = ("key", "value")
|
64
70
|
KEY_FIELD_NUMBER: _ClassVar[int]
|
@@ -66,17 +72,21 @@ class ModelOutputSchema(_message.Message):
|
|
66
72
|
key: str
|
67
73
|
value: _type_pb2.Value
|
68
74
|
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[_type_pb2.Value, _Mapping]] = ...) -> None: ...
|
75
|
+
OBJECTTYPE_FIELD_NUMBER: _ClassVar[int]
|
69
76
|
SCHEMA_FIELD_NUMBER: _ClassVar[int]
|
77
|
+
FILETYPE_FIELD_NUMBER: _ClassVar[int]
|
70
78
|
LABEL_FIELD_NUMBER: _ClassVar[int]
|
71
79
|
OPTIONAL_FIELD_NUMBER: _ClassVar[int]
|
72
80
|
DYNAMIC_FIELD_NUMBER: _ClassVar[int]
|
73
81
|
OUTPUTPROPS_FIELD_NUMBER: _ClassVar[int]
|
82
|
+
objectType: _object_id_pb2.ObjectType
|
74
83
|
schema: _data_pb2.SchemaDefinition
|
84
|
+
fileType: _file_pb2.FileType
|
75
85
|
label: str
|
76
86
|
optional: bool
|
77
87
|
dynamic: bool
|
78
88
|
outputProps: _containers.MessageMap[str, _type_pb2.Value]
|
79
|
-
def __init__(self, schema: _Optional[_Union[_data_pb2.SchemaDefinition, _Mapping]] = ..., label: _Optional[str] = ..., optional: bool = ..., dynamic: bool = ..., outputProps: _Optional[_Mapping[str, _type_pb2.Value]] = ...) -> None: ...
|
89
|
+
def __init__(self, objectType: _Optional[_Union[_object_id_pb2.ObjectType, str]] = ..., schema: _Optional[_Union[_data_pb2.SchemaDefinition, _Mapping]] = ..., fileType: _Optional[_Union[_file_pb2.FileType, _Mapping]] = ..., label: _Optional[str] = ..., optional: bool = ..., dynamic: bool = ..., outputProps: _Optional[_Mapping[str, _type_pb2.Value]] = ...) -> None: ...
|
80
90
|
|
81
91
|
class ModelDefinition(_message.Message):
|
82
92
|
__slots__ = ("language", "repository", "packageGroup", "package", "version", "entryPoint", "path", "parameters", "inputs", "outputs", "staticAttributes", "modelType")
|
tracdap/rt/_impl/models.py
CHANGED
@@ -226,13 +226,15 @@ class ModelLoader:
|
|
226
226
|
self.__log.info(f"Parameter [{name}] - {param.paramType.basicType.name}")
|
227
227
|
param.paramProps = self._encoded_props(param.paramProps, "parameter", name)
|
228
228
|
|
229
|
-
for name,
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
229
|
+
for name, input_def in model_def.inputs.items():
|
230
|
+
input_type = input_def.schema.schemaType.name if input_def.objectType == _meta.ObjectType.DATA else input_def.objectType.name
|
231
|
+
self.__log.info(f"Input [{name}] - {input_type}")
|
232
|
+
input_def.inputProps = self._encoded_props(input_def.inputProps, "input", name)
|
233
|
+
|
234
|
+
for name, output_def in model_def.outputs.items():
|
235
|
+
output_type = output_def.schema.schemaType.name if output_def.objectType == _meta.ObjectType.DATA else output_def.objectType.name
|
236
|
+
self.__log.info(f"Output [{name}] - {output_type}")
|
237
|
+
output_def.outputProps = self._encoded_props(output_def.outputProps, "input", name)
|
236
238
|
|
237
239
|
return model_def
|
238
240
|
|
tracdap/rt/_impl/static_api.py
CHANGED
@@ -152,14 +152,18 @@ class StaticApiImpl(_StaticApiHook):
|
|
152
152
|
|
153
153
|
def define_schema(
|
154
154
|
self, *fields: _tp.Union[_meta.FieldSchema, _tp.List[_meta.FieldSchema]],
|
155
|
-
schema_type: _meta.SchemaType = _meta.SchemaType.TABLE) \
|
155
|
+
schema_type: _meta.SchemaType = _meta.SchemaType.TABLE, dynamic: bool = False) \
|
156
156
|
-> _meta.SchemaDefinition:
|
157
157
|
|
158
|
-
_val.validate_signature(self.define_schema, *fields, schema_type=schema_type)
|
158
|
+
_val.validate_signature(self.define_schema, *fields, schema_type=schema_type, dynamic=dynamic)
|
159
159
|
|
160
160
|
if schema_type == _meta.SchemaType.TABLE:
|
161
161
|
|
162
|
-
|
162
|
+
if dynamic and not fields:
|
163
|
+
table_schema = None
|
164
|
+
else:
|
165
|
+
table_schema = self._build_table_schema(*fields)
|
166
|
+
|
163
167
|
return _meta.SchemaDefinition(_meta.SchemaType.TABLE, table=table_schema)
|
164
168
|
|
165
169
|
raise _ex.ERuntimeValidation(f"Invalid schema type [{schema_type.name}]")
|
@@ -182,51 +186,67 @@ class StaticApiImpl(_StaticApiHook):
|
|
182
186
|
|
183
187
|
return converter.infer_schema(dataset)
|
184
188
|
|
185
|
-
def
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
189
|
+
def define_file_type(self, extension: str, mime_type: str) -> _meta.FileType:
|
190
|
+
|
191
|
+
_val.validate_signature(self.define_file_type, extension, mime_type)
|
192
|
+
|
193
|
+
return _meta.FileType(extension=extension, mimeType=mime_type)
|
194
|
+
|
195
|
+
def define_input(
|
196
|
+
self, requirement: _tp.Union[_meta.SchemaDefinition, _meta.FileType], *,
|
197
|
+
label: _tp.Optional[str] = None,
|
198
|
+
optional: bool = False, dynamic: bool = False,
|
199
|
+
input_props: _tp.Optional[_tp.Dict[str, _tp.Any]] = None):
|
190
200
|
|
191
201
|
_val.validate_signature(
|
192
|
-
self.
|
202
|
+
self.define_input, requirement,
|
193
203
|
label=label, optional=optional, dynamic=dynamic,
|
194
204
|
input_props=input_props)
|
195
205
|
|
196
|
-
|
206
|
+
if isinstance(requirement, _meta.SchemaDefinition):
|
197
207
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
208
|
+
return _meta.ModelInputSchema(
|
209
|
+
objectType=_meta.ObjectType.DATA, schema=requirement,
|
210
|
+
label=label, optional=optional, dynamic=dynamic,
|
211
|
+
inputProps=input_props)
|
202
212
|
|
203
|
-
|
204
|
-
schema=schema_def, label=label,
|
205
|
-
optional=optional, dynamic=dynamic,
|
206
|
-
inputProps=input_props)
|
213
|
+
elif isinstance(requirement, _meta.FileType):
|
207
214
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
215
|
+
return _meta.ModelInputSchema(
|
216
|
+
objectType=_meta.ObjectType.FILE, fileType=requirement,
|
217
|
+
label=label, optional=optional, dynamic=dynamic,
|
218
|
+
inputProps=input_props)
|
219
|
+
|
220
|
+
else:
|
221
|
+
raise _ex.EUnexpected()
|
222
|
+
|
223
|
+
def define_output(
|
224
|
+
self, requirement: _tp.Union[_meta.SchemaDefinition, _meta.FileType], *,
|
225
|
+
label: _tp.Optional[str] = None,
|
226
|
+
optional: bool = False, dynamic: bool = False,
|
227
|
+
output_props: _tp.Optional[_tp.Dict[str, _tp.Any]] = None):
|
213
228
|
|
214
229
|
_val.validate_signature(
|
215
|
-
self.
|
230
|
+
self.define_output, requirement,
|
216
231
|
label=label, optional=optional, dynamic=dynamic,
|
217
232
|
output_props=output_props)
|
218
233
|
|
219
|
-
|
234
|
+
if isinstance(requirement, _meta.SchemaDefinition):
|
220
235
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
236
|
+
return _meta.ModelOutputSchema(
|
237
|
+
objectType=_meta.ObjectType.DATA, schema=requirement,
|
238
|
+
label=label, optional=optional, dynamic=dynamic,
|
239
|
+
outputProps=output_props)
|
225
240
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
241
|
+
elif isinstance(requirement, _meta.FileType):
|
242
|
+
|
243
|
+
return _meta.ModelOutputSchema(
|
244
|
+
objectType=_meta.ObjectType.FILE, fileType=requirement,
|
245
|
+
label=label, optional=optional, dynamic=dynamic,
|
246
|
+
outputProps=output_props)
|
247
|
+
|
248
|
+
else:
|
249
|
+
raise _ex.EUnexpected()
|
230
250
|
|
231
251
|
@staticmethod
|
232
252
|
def _build_named_dict(
|
tracdap/rt/_impl/util.py
CHANGED
@@ -235,7 +235,7 @@ def get_job_resource(
|
|
235
235
|
if optional:
|
236
236
|
return None
|
237
237
|
|
238
|
-
err = f"Missing required {selector.objectType} resource [{object_key(selector)}]"
|
238
|
+
err = f"Missing required {selector.objectType.name} resource [{object_key(selector)}]"
|
239
239
|
raise ex.ERuntimeValidation(err)
|
240
240
|
|
241
241
|
|
tracdap/rt/_impl/validation.py
CHANGED
@@ -306,6 +306,9 @@ class StaticValidator:
|
|
306
306
|
__reserved_identifier_pattern = re.compile("\\A(_|trac_)", re.ASCII)
|
307
307
|
__label_length_limit = 4096
|
308
308
|
|
309
|
+
__file_extension_pattern = re.compile('\\A[a-zA-Z0-9]+\\Z')
|
310
|
+
__mime_type_pattern = re.compile('\\A\\w+/[-.\\w]+(?:\\+[-.\\w]+)?\\Z')
|
311
|
+
|
309
312
|
__PRIMITIVE_TYPES = [
|
310
313
|
meta.BasicType.BOOLEAN,
|
311
314
|
meta.BasicType.INTEGER,
|
@@ -418,49 +421,72 @@ class StaticValidator:
|
|
418
421
|
cls._valid_identifiers(param.paramProps.keys(), "entry in param props")
|
419
422
|
|
420
423
|
@classmethod
|
421
|
-
def _check_inputs_or_outputs(cls,
|
424
|
+
def _check_inputs_or_outputs(cls, sockets):
|
422
425
|
|
423
|
-
for
|
426
|
+
for socket_name, socket in sockets.items():
|
424
427
|
|
425
|
-
|
428
|
+
if socket.objectType == meta.ObjectType.DATA:
|
429
|
+
cls._check_socket_schema(socket_name, socket)
|
430
|
+
elif socket.objectType == meta.ObjectType.FILE:
|
431
|
+
cls._check_socket_file_type(socket_name, socket)
|
432
|
+
else:
|
433
|
+
raise ex.EModelValidation(f"Invalid object type [{socket.objectType.name}] for [{socket_name}]")
|
426
434
|
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
435
|
+
label = socket.label
|
436
|
+
cls._check_label(label, socket_name)
|
437
|
+
|
438
|
+
if isinstance(socket, meta.ModelInputSchema):
|
439
|
+
if socket.inputProps is not None:
|
440
|
+
cls._valid_identifiers(socket.inputProps.keys(), "entry in input props")
|
441
|
+
else:
|
442
|
+
if socket.outputProps is not None:
|
443
|
+
cls._valid_identifiers(socket.outputProps.keys(), "entry in output props")
|
433
444
|
|
434
|
-
|
435
|
-
|
436
|
-
property_type = f"field in [{input_name}]"
|
445
|
+
@classmethod
|
446
|
+
def _check_socket_schema(cls, socket_name, socket):
|
437
447
|
|
438
|
-
|
439
|
-
|
448
|
+
if socket.schema is None:
|
449
|
+
cls._fail(f"Missing schema requirement for [{socket_name}]")
|
450
|
+
return
|
440
451
|
|
441
|
-
|
442
|
-
|
452
|
+
if socket.dynamic:
|
453
|
+
if socket.schema and socket.schema.table:
|
454
|
+
error = "Dynamic schemas must have schema.table = None"
|
455
|
+
cls._fail(f"Invalid schema for [{socket_name}]: {error}")
|
456
|
+
else:
|
457
|
+
return
|
443
458
|
|
444
|
-
|
445
|
-
|
459
|
+
fields = socket.schema.table.fields
|
460
|
+
field_names = list(map(lambda f: f.fieldName, fields))
|
461
|
+
property_type = f"field in [{socket_name}]"
|
446
462
|
|
447
|
-
|
448
|
-
cls.
|
463
|
+
if len(fields) == 0:
|
464
|
+
cls._fail(f"Invalid schema for [{socket_name}]: No fields defined")
|
449
465
|
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
466
|
+
cls._valid_identifiers(field_names, property_type)
|
467
|
+
cls._case_insensitive_duplicates(field_names, property_type)
|
468
|
+
|
469
|
+
for field in fields:
|
470
|
+
cls._check_single_field(field, property_type)
|
471
|
+
|
472
|
+
@classmethod
|
473
|
+
def _check_socket_file_type(cls, socket_name, socket):
|
474
|
+
|
475
|
+
if socket.fileType is None:
|
476
|
+
cls._fail(f"Missing file type requirement for [{socket_name}]")
|
477
|
+
return
|
478
|
+
|
479
|
+
if not cls.__file_extension_pattern.match(socket.fileType.extension):
|
480
|
+
cls._fail(f"Invalid extension [{socket.fileType.extension}] for [{socket_name}]")
|
481
|
+
|
482
|
+
if not cls.__mime_type_pattern.match(socket.fileType.mimeType):
|
483
|
+
cls._fail(f"Invalid mime type [{socket.fileType.mimeType}] for [{socket_name}]")
|
456
484
|
|
457
485
|
@classmethod
|
458
486
|
def _check_single_field(cls, field: meta.FieldSchema, property_type):
|
459
487
|
|
460
488
|
# Valid identifier and not trac reserved checked separately
|
461
489
|
|
462
|
-
cls._log.info(field.fieldName)
|
463
|
-
|
464
490
|
if field.fieldOrder < 0:
|
465
491
|
cls._fail(f"Invalid {property_type}: [{field.fieldName}] fieldOrder < 0")
|
466
492
|
|
tracdap/rt/_version.py
CHANGED
tracdap/rt/api/__init__.py
CHANGED
@@ -17,13 +17,16 @@
|
|
17
17
|
TRAC model API for Python
|
18
18
|
"""
|
19
19
|
|
20
|
-
from .model_api import *
|
21
|
-
from .static_api import *
|
22
|
-
|
23
20
|
# Make metadata classes available to client code when importing the API package
|
24
21
|
# Remove this import when generating docs, so metadata classes are only documented once
|
25
22
|
from tracdap.rt.metadata import * # noqa DOCGEN_REMOVE
|
26
23
|
|
24
|
+
# static_api overrides some metadata types for backwards compatibility with pre-0.8 versions
|
25
|
+
# Make sure it is last in the list
|
26
|
+
from .file_types import *
|
27
|
+
from .model_api import *
|
28
|
+
from .static_api import *
|
29
|
+
|
27
30
|
# Map basic types into the root of the API package
|
28
31
|
|
29
32
|
BOOLEAN = BasicType.BOOLEAN
|