tracdap-runtime 0.6.4__py3-none-any.whl → 0.6.6__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.
Files changed (41) hide show
  1. tracdap/rt/_exec/context.py +556 -36
  2. tracdap/rt/_exec/dev_mode.py +320 -198
  3. tracdap/rt/_exec/engine.py +331 -62
  4. tracdap/rt/_exec/functions.py +151 -22
  5. tracdap/rt/_exec/graph.py +47 -13
  6. tracdap/rt/_exec/graph_builder.py +383 -175
  7. tracdap/rt/_exec/runtime.py +7 -5
  8. tracdap/rt/_impl/config_parser.py +11 -4
  9. tracdap/rt/_impl/data.py +329 -152
  10. tracdap/rt/_impl/ext/__init__.py +13 -0
  11. tracdap/rt/_impl/ext/sql.py +116 -0
  12. tracdap/rt/_impl/ext/storage.py +57 -0
  13. tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.py +82 -30
  14. tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.pyi +155 -2
  15. tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.py +12 -10
  16. tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.pyi +14 -2
  17. tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.py +29 -0
  18. tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.pyi +16 -0
  19. tracdap/rt/_impl/models.py +8 -0
  20. tracdap/rt/_impl/static_api.py +29 -0
  21. tracdap/rt/_impl/storage.py +39 -27
  22. tracdap/rt/_impl/util.py +10 -0
  23. tracdap/rt/_impl/validation.py +140 -18
  24. tracdap/rt/_plugins/repo_git.py +1 -1
  25. tracdap/rt/_plugins/storage_sql.py +417 -0
  26. tracdap/rt/_plugins/storage_sql_dialects.py +117 -0
  27. tracdap/rt/_version.py +1 -1
  28. tracdap/rt/api/experimental.py +267 -0
  29. tracdap/rt/api/hook.py +14 -0
  30. tracdap/rt/api/model_api.py +48 -6
  31. tracdap/rt/config/__init__.py +2 -2
  32. tracdap/rt/config/common.py +6 -0
  33. tracdap/rt/metadata/__init__.py +29 -20
  34. tracdap/rt/metadata/job.py +99 -0
  35. tracdap/rt/metadata/model.py +18 -0
  36. tracdap/rt/metadata/resource.py +24 -0
  37. {tracdap_runtime-0.6.4.dist-info → tracdap_runtime-0.6.6.dist-info}/METADATA +5 -1
  38. {tracdap_runtime-0.6.4.dist-info → tracdap_runtime-0.6.6.dist-info}/RECORD +41 -32
  39. {tracdap_runtime-0.6.4.dist-info → tracdap_runtime-0.6.6.dist-info}/WHEEL +1 -1
  40. {tracdap_runtime-0.6.4.dist-info → tracdap_runtime-0.6.6.dist-info}/LICENSE +0 -0
  41. {tracdap_runtime-0.6.4.dist-info → tracdap_runtime-0.6.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,267 @@
1
+ # Copyright 2024 Accenture Global Solutions Limited
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import abc as _abc
16
+ import dataclasses as _dc
17
+ import datetime as _dt
18
+ import enum as _enum
19
+ import typing as _tp
20
+
21
+ from tracdap.rt.api import *
22
+ from .hook import _StaticApiHook
23
+
24
+
25
+ _PROTOCOL = _tp.TypeVar('_PROTOCOL')
26
+
27
+ @_dc.dataclass(frozen=True)
28
+ class _Protocol(_tp.Generic[_PROTOCOL]):
29
+
30
+ protocol_name: str
31
+ api_type: _tp.Type[_PROTOCOL]
32
+
33
+ def __str__(self):
34
+ return self.protocol_name
35
+
36
+
37
+ def __pandas_api_type() -> "_tp.Type[pandas.DataFrame]":
38
+ try:
39
+ import pandas
40
+ return pandas.DataFrame
41
+ except ModuleNotFoundError:
42
+ return None # noqa
43
+
44
+ def __polars_api_type() -> "_tp.Type[polars.DataFrame]":
45
+ try:
46
+ import polars
47
+ return polars.DataFrame
48
+ except ModuleNotFoundError:
49
+ return None # noqa
50
+
51
+ DATA_API = _tp.TypeVar('DATA_API', __pandas_api_type(), __polars_api_type())
52
+
53
+ class DataFramework(_Protocol[DATA_API]):
54
+
55
+ def __init__(self, protocol_name: str, api_type: _tp.Type[DATA_API]):
56
+ super().__init__(protocol_name, api_type)
57
+
58
+ @classmethod
59
+ def pandas(cls) -> "DataFramework[pandas.DataFrame]":
60
+ return DataFramework("pandas", DATA_API.__constraints__[0])
61
+
62
+ @classmethod
63
+ def polars(cls) -> "DataFramework[polars.DataFrame]":
64
+ return DataFramework("polars", DATA_API.__constraints__[1])
65
+
66
+ PANDAS = DataFramework.pandas()
67
+ """Data framework constant for the Pandas data library"""
68
+
69
+ POLARS = DataFramework.polars()
70
+ """Data framework constant for the Polars data library"""
71
+
72
+
73
+ class TracContext(TracContext):
74
+
75
+ @_abc.abstractmethod
76
+ def get_table(self, dataset_name: str, framework: DataFramework[DATA_API]) -> DATA_API:
77
+
78
+ pass
79
+
80
+ @_abc.abstractmethod
81
+ def put_table(self, dataset_name: str, dataset: DATA_API):
82
+
83
+ pass
84
+
85
+
86
+ def init_static():
87
+ """Ensure TRAC's static model API is available to use (for static definitions at module or class scope)"""
88
+ import tracdap.rt._impl.static_api as _static_impl # noqa
89
+ _static_impl.StaticApiImpl.register_impl()
90
+
91
+
92
+ def infer_schema(dataset: DATA_API) -> SchemaDefinition:
93
+ """Infer the full TRAC schema of an existing dataset"""
94
+ sa = _StaticApiHook.get_instance()
95
+ return sa.infer_schema(dataset)
96
+
97
+
98
+ def array_type(item_type: BasicType) -> TypeDescriptor:
99
+ """Build a type descriptor for an ARRAY type"""
100
+ sa = _StaticApiHook.get_instance()
101
+ return sa.array_type(item_type)
102
+
103
+
104
+ def map_type(entry_type: BasicType) -> TypeDescriptor:
105
+ """Build a type descriptor for a MAP type"""
106
+ sa = _StaticApiHook.get_instance()
107
+ return sa.map_type(entry_type)
108
+
109
+
110
+ class FileType(_enum.Enum):
111
+
112
+ FILE = 1
113
+ DIRECTORY = 2
114
+
115
+
116
+ @_dc.dataclass
117
+ class FileStat:
118
+
119
+ """
120
+ Dataclass to represent some basic file stat info independent of the storage technology used
121
+ I.e. do not depend on Python stat_result class that refers to locally-mounted filesystems
122
+ Timestamps are held in UTC
123
+ """
124
+
125
+ file_name: str
126
+ file_type: FileType
127
+ storage_path: str
128
+ size: int
129
+
130
+ mtime: _tp.Optional[_dt.datetime] = None
131
+ atime: _tp.Optional[_dt.datetime] = None
132
+
133
+
134
+ class TracFileStorage:
135
+
136
+ @_abc.abstractmethod
137
+ def get_storage_key(self) -> str:
138
+ pass
139
+
140
+ @_abc.abstractmethod
141
+ def exists(self, storage_path: str) -> bool:
142
+ """The exists method can be used for both files and directories"""
143
+ pass
144
+
145
+ @_abc.abstractmethod
146
+ def size(self, storage_path: str) -> int:
147
+ """The rm method only works on regular files, it cannot be used for directories"""
148
+ pass
149
+
150
+ @_abc.abstractmethod
151
+ def stat(self, storage_path: str) -> FileStat:
152
+ """The stat method can be used for both files and directories, so long as they exist"""
153
+ pass
154
+
155
+ @_abc.abstractmethod
156
+ def ls(self, storage_path: str, recursive: bool = False) -> _tp.List[FileStat]:
157
+ """The ls method only works on directories, it cannot be used for regular files"""
158
+ pass
159
+
160
+ @_abc.abstractmethod
161
+ def mkdir(self, storage_path: str, recursive: bool = False):
162
+ """The mkdir method will succeed silently if the directory already exists"""
163
+ pass
164
+
165
+ @_abc.abstractmethod
166
+ def rm(self, storage_path: str):
167
+ """The rm method only works on regular files, it cannot be used for directories and is not recursive"""
168
+ pass
169
+
170
+ @_abc.abstractmethod
171
+ def rmdir(self, storage_path: str):
172
+ """The rmdir method only works on directories and is always recursive"""
173
+ pass
174
+
175
+ @_abc.abstractmethod
176
+ def read_byte_stream(self, storage_path: str) -> _tp.ContextManager[_tp.BinaryIO]:
177
+ """The read_byte_stream method only works for existing files"""
178
+ pass
179
+
180
+ @_abc.abstractmethod
181
+ def write_byte_stream(self, storage_path: str) -> _tp.ContextManager[_tp.BinaryIO]:
182
+ """The write_byte_stream method will always overwrite an existing file if it exists"""
183
+ pass
184
+
185
+ def read_bytes(self, storage_path: str) -> bytes:
186
+ """The read_bytes method only works for existing files"""
187
+ with self.read_byte_stream(storage_path) as stream:
188
+ return stream.read()
189
+
190
+ def write_bytes(self, storage_path: str, data: bytes):
191
+ """The write_bytes method will always overwrite an existing file if it exists"""
192
+ with self.write_byte_stream(storage_path) as stream:
193
+ stream.write(data)
194
+
195
+
196
+ class TracDataStorage(_tp.Generic[DATA_API]):
197
+
198
+ @_abc.abstractmethod
199
+ def has_table(self, table_name: str) -> bool:
200
+ pass
201
+
202
+ @_abc.abstractmethod
203
+ def list_tables(self) -> _tp.List[str]:
204
+ pass
205
+
206
+ @_abc.abstractmethod
207
+ def create_table(self, table_name: str, schema: SchemaDefinition):
208
+ pass
209
+
210
+ @_abc.abstractmethod
211
+ def read_table(self, table_name: str) -> DATA_API:
212
+ pass
213
+
214
+ @_abc.abstractmethod
215
+ def write_table(self, table_name: str, dataset: DATA_API):
216
+ pass
217
+
218
+ @_abc.abstractmethod
219
+ def native_read_query(self, query: str, **parameters) -> DATA_API:
220
+ pass
221
+
222
+
223
+ class TracDataContext(TracContext):
224
+
225
+ @_abc.abstractmethod
226
+ def get_file_storage(self, storage_key: str) -> TracFileStorage:
227
+ pass
228
+
229
+ @_abc.abstractmethod
230
+ def get_data_storage(self, storage_key: str, framework: DataFramework[DATA_API], **framework_args) -> TracDataStorage[DATA_API]:
231
+ pass
232
+
233
+ @_abc.abstractmethod
234
+ def add_data_import(self, dataset_key: str):
235
+ pass
236
+
237
+ @_abc.abstractmethod
238
+ def set_source_metadata(self, dataset_key: str, storage_key: str, source_info: _tp.Union[FileStat, str]):
239
+ pass
240
+
241
+ @_abc.abstractmethod
242
+ def set_attribute(self, dataset_key: str, attribute_name: str, value: _tp.Any):
243
+ pass
244
+
245
+ @_abc.abstractmethod
246
+ def set_schema(self, dataset_key: str, schema: SchemaDefinition):
247
+ pass
248
+
249
+
250
+ class TracDataImport(TracModel):
251
+
252
+ def define_inputs(self) -> _tp.Dict[str, ModelInputSchema]:
253
+ return dict()
254
+
255
+ @_abc.abstractmethod
256
+ def run_model(self, ctx: TracDataContext):
257
+ pass
258
+
259
+
260
+ class TracDataExport(TracModel):
261
+
262
+ def define_outputs(self) -> _tp.Dict[str, ModelOutputSchema]:
263
+ return dict()
264
+
265
+ @_abc.abstractmethod
266
+ def run_model(self, ctx: TracDataContext):
267
+ pass
tracdap/rt/api/hook.py CHANGED
@@ -61,6 +61,16 @@ class _StaticApiHook:
61
61
 
62
62
  return cls.__static_api_hook
63
63
 
64
+ @_abc.abstractmethod
65
+ def array_type(self, item_type: _meta.BasicType) -> _meta.TypeDescriptor:
66
+
67
+ pass
68
+
69
+ @_abc.abstractmethod
70
+ def map_type(self, entry_type: _meta.BasicType) -> _meta.TypeDescriptor:
71
+
72
+ pass
73
+
64
74
  @_abc.abstractmethod
65
75
  def define_attributes(
66
76
  self, *attrs: _tp.Union[_meta.TagUpdate, _tp.List[_meta.TagUpdate]]) \
@@ -118,6 +128,10 @@ class _StaticApiHook:
118
128
 
119
129
  pass
120
130
 
131
+ @_abc.abstractmethod
132
+ def infer_schema(self, dataset: _tp.Any) -> _meta.SchemaDefinition:
133
+ pass
134
+
121
135
  @_abc.abstractmethod
122
136
  def define_input_table(
123
137
  self, *fields: _tp.Union[_meta.FieldSchema, _tp.List[_meta.FieldSchema]],
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from __future__ import annotations
16
-
17
15
  import abc as _abc
18
16
  import typing as _tp
19
17
  import logging as _logging
@@ -22,8 +20,18 @@ import logging as _logging
22
20
  # This significantly improves type hinting, inline documentation and auto-complete in JetBrains IDEs
23
21
  from tracdap.rt.metadata import * # DOCGEN_REMOVE
24
22
 
23
+
25
24
  if _tp.TYPE_CHECKING:
26
- import pandas
25
+
26
+ try:
27
+ import pandas
28
+ except ModuleNotFoundError:
29
+ pass
30
+
31
+ try:
32
+ import polars
33
+ except ModuleNotFoundError:
34
+ pass
27
35
 
28
36
 
29
37
  class TracContext:
@@ -134,7 +142,8 @@ class TracContext:
134
142
  pass
135
143
 
136
144
  @_abc.abstractmethod
137
- def get_pandas_table(self, dataset_name: str, use_temporal_objects: _tp.Optional[bool] = None) -> pandas.DataFrame:
145
+ def get_pandas_table(self, dataset_name: str, use_temporal_objects: _tp.Optional[bool] = None) \
146
+ -> "pandas.DataFrame":
138
147
 
139
148
  """
140
149
  Get the data for a model input or output as a Pandas dataframe
@@ -165,6 +174,22 @@ class TracContext:
165
174
  """
166
175
  pass
167
176
 
177
+ @_abc.abstractmethod
178
+ def get_polars_table(self, dataset_name: str) -> "polars.DataFrame":
179
+
180
+ """
181
+ Get the data for a model input or output as a Polars dataframe
182
+
183
+ This method has equivalent semantics to :py:meth:`get_pandas_table`, but returns
184
+ a Polars dataframe.
185
+
186
+ :param dataset_name: The name of the model input or output to get data for
187
+ :return: A polars dataframe containing the data for the named dataset
188
+ :raises: :py:class:`ERuntimeValidation <tracdap.rt.exceptions.ERuntimeValidation>`
189
+ """
190
+
191
+ pass
192
+
168
193
  @_abc.abstractmethod
169
194
  def put_schema(self, dataset_name: str, schema: SchemaDefinition):
170
195
 
@@ -196,7 +221,7 @@ class TracContext:
196
221
  pass
197
222
 
198
223
  @_abc.abstractmethod
199
- def put_pandas_table(self, dataset_name: str, dataset: pandas.DataFrame):
224
+ def put_pandas_table(self, dataset_name: str, dataset: "pandas.DataFrame"):
200
225
 
201
226
  """
202
227
  Save the data for a model output as a Pandas dataframe
@@ -217,7 +242,24 @@ class TracContext:
217
242
  :param dataset_name: The name of the model output to save data for
218
243
  :param dataset: A pandas dataframe containing the data for the named dataset
219
244
  :raises: :py:class:`ERuntimeValidation <tracdap.rt.exceptions.ERuntimeValidation>`,
220
- :py:class:`EDataValidation <tracdap.rt.exceptions.EDataValidation>`
245
+ :py:class:`EDataConformance <tracdap.rt.exceptions.EDataConformance>`
246
+ """
247
+
248
+ pass
249
+
250
+ @_abc.abstractmethod
251
+ def put_polars_table(self, dataset_name: str, dataset: "polars.DataFrame"):
252
+
253
+ """
254
+ Save the data for a model output as a Polars dataframe
255
+
256
+ This method has equivalent semantics to :py:meth:`put_pandas_table`, but accepts
257
+ a Polars dataframe.
258
+
259
+ :param dataset_name: The name of the model output to save data for
260
+ :param dataset: A polars dataframe containing the data for the named dataset
261
+ :raises: :py:class:`ERuntimeValidation <tracdap.rt.exceptions.ERuntimeValidation>`,
262
+ :py:class:`EDataConformance <tracdap.rt.exceptions.EDataConformance>`
221
263
  """
222
264
 
223
265
  pass
@@ -10,6 +10,8 @@ from .common import ServiceConfig
10
10
  from .runtime import RuntimeConfig
11
11
  from .runtime import SparkSettings
12
12
 
13
+ from .job import JobConfig
14
+
13
15
  from .platform import RoutingProtocol
14
16
  from .platform import DeploymentLayout
15
17
  from .platform import PlatformConfig
@@ -24,7 +26,5 @@ from .platform import RoutingMatch
24
26
  from .platform import RoutingTarget
25
27
  from .platform import DeploymentConfig
26
28
 
27
- from .job import JobConfig
28
-
29
29
  from .result import TagUpdateList
30
30
  from .result import JobResult
@@ -17,6 +17,8 @@ class PluginConfig:
17
17
 
18
18
  protocol: str = ""
19
19
 
20
+ publicProperties: _tp.Dict[str, str] = _dc.field(default_factory=dict)
21
+
20
22
  properties: _tp.Dict[str, str] = _dc.field(default_factory=dict)
21
23
 
22
24
  secrets: _tp.Dict[str, str] = _dc.field(default_factory=dict)
@@ -63,6 +65,10 @@ class StorageConfig:
63
65
 
64
66
  buckets: _tp.Dict[str, PluginConfig] = _dc.field(default_factory=dict)
65
67
 
68
+ """TODO: Rename "buckets" as "internal" for 0.7"""
69
+
70
+ external: _tp.Dict[str, PluginConfig] = _dc.field(default_factory=dict)
71
+
66
72
  defaultBucket: str = ""
67
73
 
68
74
  defaultFormat: str = ""
@@ -21,30 +21,12 @@ from .data import SchemaDefinition
21
21
  from .data import PartKey
22
22
  from .data import DataDefinition
23
23
 
24
- from .stoarge import CopyStatus
25
- from .stoarge import IncarnationStatus
26
- from .stoarge import StorageCopy
27
- from .stoarge import StorageIncarnation
28
- from .stoarge import StorageItem
29
- from .stoarge import StorageDefinition
30
-
24
+ from .model import ModelType
31
25
  from .model import ModelParameter
32
26
  from .model import ModelInputSchema
33
27
  from .model import ModelOutputSchema
34
28
  from .model import ModelDefinition
35
29
 
36
- from .tag_update import TagOperation
37
- from .tag_update import TagUpdate
38
-
39
- from .job import JobType
40
- from .job import JobStatusCode
41
- from .job import JobDefinition
42
- from .job import RunModelJob
43
- from .job import RunFlowJob
44
- from .job import ImportModelJob
45
-
46
- from .file import FileDefinition
47
-
48
30
  from .search import SearchOperator
49
31
  from .search import LogicalOperator
50
32
  from .search import SearchTerm
@@ -52,18 +34,45 @@ from .search import LogicalExpression
52
34
  from .search import SearchExpression
53
35
  from .search import SearchParameters
54
36
 
37
+ from .tag_update import TagOperation
38
+ from .tag_update import TagUpdate
39
+
55
40
  from .flow import FlowNodeType
56
41
  from .flow import FlowNode
57
42
  from .flow import FlowSocket
58
43
  from .flow import FlowEdge
59
44
  from .flow import FlowDefinition
60
45
 
46
+ from .job import JobType
47
+ from .job import JobStatusCode
48
+ from .job import JobGroupType
49
+ from .job import JobDefinition
50
+ from .job import RunModelJob
51
+ from .job import RunFlowJob
52
+ from .job import ImportModelJob
53
+ from .job import ImportDataJob
54
+ from .job import ExportDataJob
55
+ from .job import JobGroup
56
+ from .job import SequentialJobGroup
57
+ from .job import ParallelJobGroup
58
+
59
+ from .file import FileDefinition
60
+
61
61
  from .custom import CustomDefinition
62
62
 
63
+ from .stoarge import CopyStatus
64
+ from .stoarge import IncarnationStatus
65
+ from .stoarge import StorageCopy
66
+ from .stoarge import StorageIncarnation
67
+ from .stoarge import StorageItem
68
+ from .stoarge import StorageDefinition
69
+
63
70
  from .object import ObjectDefinition
64
71
 
65
- from .tag import Tag
72
+ from .resource import ResourceType
66
73
 
67
74
  from .common import MetadataFormat
68
75
  from .common import MetadataVersion
69
76
  from .common import TenantInfo
77
+
78
+ from .tag import Tag
@@ -32,6 +32,14 @@ class JobType(_enum.Enum):
32
32
 
33
33
  """Import data into the platform"""
34
34
 
35
+ EXPORT_DATA = 5
36
+
37
+ """Export data to external locations"""
38
+
39
+ JOB_GROUP = 6
40
+
41
+ """A job built from a collection of other jobs"""
42
+
35
43
 
36
44
  class JobStatusCode(_enum.Enum):
37
45
 
@@ -80,6 +88,17 @@ class JobStatusCode(_enum.Enum):
80
88
  """The job was cancelled by a user of the platform"""
81
89
 
82
90
 
91
+ class JobGroupType(_enum.Enum):
92
+
93
+ """Specify the group type for a JOB_GROUP job"""
94
+
95
+ JOB_GROUP_TYPE_NOT_SET = 0
96
+
97
+ SEQUENTIAL_JOB_GROUP = 1
98
+
99
+ PARALLEL_JOB_GROUP = 2
100
+
101
+
83
102
  @_dc.dataclass
84
103
  class JobDefinition:
85
104
 
@@ -93,6 +112,12 @@ class JobDefinition:
93
112
 
94
113
  importModel: _tp.Optional[ImportModelJob] = None
95
114
 
115
+ importData: _tp.Optional[ImportDataJob] = None
116
+
117
+ exportData: _tp.Optional[ExportDataJob] = None
118
+
119
+ jobGroup: _tp.Optional[JobGroup] = None
120
+
96
121
 
97
122
  @_dc.dataclass
98
123
  class RunModelJob:
@@ -152,3 +177,77 @@ class ImportModelJob:
152
177
  path: str = ""
153
178
 
154
179
  modelAttrs: _tp.List[TagUpdate] = _dc.field(default_factory=list)
180
+
181
+
182
+ @_dc.dataclass
183
+ class ImportDataJob:
184
+
185
+ """Specification for an IMPORT_DATA job"""
186
+
187
+ model: TagSelector = _dc.field(default_factory=lambda: TagSelector())
188
+
189
+ parameters: _tp.Dict[str, Value] = _dc.field(default_factory=dict)
190
+
191
+ inputs: _tp.Dict[str, TagSelector] = _dc.field(default_factory=dict)
192
+
193
+ outputs: _tp.Dict[str, TagSelector] = _dc.field(default_factory=dict)
194
+
195
+ priorOutputs: _tp.Dict[str, TagSelector] = _dc.field(default_factory=dict)
196
+
197
+ storageAccess: _tp.List[str] = _dc.field(default_factory=list)
198
+
199
+ imports: _tp.Dict[str, TagSelector] = _dc.field(default_factory=dict)
200
+
201
+ outputAttrs: _tp.List[TagUpdate] = _dc.field(default_factory=list)
202
+
203
+ importAttrs: _tp.List[TagUpdate] = _dc.field(default_factory=list)
204
+
205
+
206
+ @_dc.dataclass
207
+ class ExportDataJob:
208
+
209
+ """Specification for an EXPORT_DATA job"""
210
+
211
+ model: TagSelector = _dc.field(default_factory=lambda: TagSelector())
212
+
213
+ parameters: _tp.Dict[str, Value] = _dc.field(default_factory=dict)
214
+
215
+ inputs: _tp.Dict[str, TagSelector] = _dc.field(default_factory=dict)
216
+
217
+ outputs: _tp.Dict[str, TagSelector] = _dc.field(default_factory=dict)
218
+
219
+ priorOutputs: _tp.Dict[str, TagSelector] = _dc.field(default_factory=dict)
220
+
221
+ storageAccess: _tp.List[str] = _dc.field(default_factory=list)
222
+
223
+ exports: _tp.Dict[str, TagSelector] = _dc.field(default_factory=dict)
224
+
225
+ outputAttrs: _tp.List[TagUpdate] = _dc.field(default_factory=list)
226
+
227
+
228
+ @_dc.dataclass
229
+ class JobGroup:
230
+
231
+ """Specification for a JOB_GROUP job, which runs a collection of other jobs"""
232
+
233
+ jobGroupType: JobGroupType = JobGroupType.JOB_GROUP_TYPE_NOT_SET
234
+
235
+ sequential: _tp.Optional[SequentialJobGroup] = None
236
+
237
+ parallel: _tp.Optional[ParallelJobGroup] = None
238
+
239
+
240
+ @_dc.dataclass
241
+ class SequentialJobGroup:
242
+
243
+ """A job group where each job runs in sequence"""
244
+
245
+ jobs: _tp.List[JobDefinition] = _dc.field(default_factory=list)
246
+
247
+
248
+ @_dc.dataclass
249
+ class ParallelJobGroup:
250
+
251
+ """A job group where all jobs runs in parallel"""
252
+
253
+ jobs: _tp.List[JobDefinition] = _dc.field(default_factory=list)
@@ -9,6 +9,22 @@ from .type import * # noqa
9
9
  from .data import * # noqa
10
10
 
11
11
 
12
+ class ModelType(_enum.Enum):
13
+
14
+ """Identify specialized model types for specific tasks"""
15
+
16
+ STANDARD_MODEL = 0
17
+
18
+ """A regular model with parameters, inputs and outputs (this is the default)"""
19
+
20
+ DATA_IMPORT_MODEL = 1
21
+
22
+ """A model with read access to external storage for importing data"""
23
+
24
+ DATA_EXPORT_MODEL = 2
25
+
26
+ """A model with write access to external storage for exporting data"""
27
+
12
28
 
13
29
  @_dc.dataclass
14
30
  class ModelParameter:
@@ -105,3 +121,5 @@ class ModelDefinition:
105
121
  staticAttributes: _tp.Dict[str, Value] = _dc.field(default_factory=dict)
106
122
 
107
123
  """Static attributes defined in model code"""
124
+
125
+ modelType: ModelType = ModelType.STANDARD_MODEL
@@ -0,0 +1,24 @@
1
+ # Code generated by TRAC
2
+
3
+ from __future__ import annotations
4
+ import typing as _tp # noqa
5
+ import dataclasses as _dc # noqa
6
+ import enum as _enum # noqa
7
+
8
+ from .object_id import * # noqa
9
+ from .object import * # noqa
10
+
11
+
12
+ class ResourceType(_enum.Enum):
13
+
14
+ """Enumeration of infrastructure resources that can be added to a tenant"""
15
+
16
+ RESOURCE_TYPE_NOT_SET = 0
17
+
18
+ MODEL_REPOSITORY = 1
19
+
20
+ """Model repository, which can be a source or binary repository"""
21
+
22
+ INTERNAL_STORAGE = 2
23
+
24
+ """Storage location for data held internally by the TRAC platform"""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tracdap-runtime
3
- Version: 0.6.4
3
+ Version: 0.6.6
4
4
  Summary: Runtime package for building models on the TRAC Data & Analytics Platform
5
5
  Home-page: https://tracdap.finos.org/
6
6
  Author: Martin Traverse
@@ -39,8 +39,12 @@ Requires-Dist: gcsfs==2024.3.1; extra == "gcp"
39
39
  Provides-Extra: grpc
40
40
  Requires-Dist: grpcio==1.66.1; extra == "grpc"
41
41
  Requires-Dist: grpcio-status==1.66.1; extra == "grpc"
42
+ Provides-Extra: polars
43
+ Requires-Dist: polars<2.0.0,>=1.0.0; extra == "polars"
42
44
  Provides-Extra: spark
43
45
  Requires-Dist: pyspark<3.6.0,>=3.0.0; extra == "spark"
46
+ Provides-Extra: sql
47
+ Requires-Dist: sqlalchemy<2.1.0,>=2.0.0; extra == "sql"
44
48
 
45
49
  # TRAC Model Runtime for Python
46
50