tracdap-runtime 0.10.0.dev3__tar.gz → 0.10.0.dev4__tar.gz
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_runtime-0.10.0.dev3/tracdap_runtime.egg-info → tracdap_runtime-0.10.0.dev4}/PKG-INFO +1 -1
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/setup.cfg +1 -1
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/__init__.py +1 -1
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/resources.py +24 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/validation.py +21 -8
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/context.py +7 -17
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/dev_mode.py +85 -49
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/engine.py +9 -2
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/functions.py +57 -32
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/graph.py +14 -2
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/graph_builder.py +58 -33
- tracdap_runtime-0.10.0.dev4/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.py +73 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.pyi +17 -4
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.py +16 -16
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.pyi +4 -4
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/static_api.py +1 -1
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/api/__init__.py +1 -1
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/flow.py +10 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/model.py +1 -1
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4/tracdap_runtime.egg-info}/PKG-INFO +1 -1
- tracdap_runtime-0.10.0.dev3/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.py +0 -69
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/LICENSE +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/README.md +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/pyproject.toml +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/__init__.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/__init__.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/config_parser.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/data.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/guard_rails.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/logging.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/models.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/plugins.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/repos.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/schemas.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/shim.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/storage.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/struct.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/type_system.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/util.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/__init__.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/actors.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/ext/__init__.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/ext/sql.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/ext/storage.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/__init__.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/codec.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/server.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2_grpc.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/config_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/config_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/storage_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/storage_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.pyi +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/runtime.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/__init__.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/_helpers.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/config_local.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/format_arrow.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/format_csv.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/format_parquet.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/repo_git.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/repo_local.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/repo_pypi.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/storage_aws.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/storage_azure.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/storage_gcp.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/storage_local.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/storage_sql.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_plugins/storage_sql_dialects.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/api/constants.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/api/experimental.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/api/hook.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/api/model_api.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/api/static_api.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/config/__init__.py +5 -5
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/config/common.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/config/dynamic.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/config/job.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/config/platform.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/config/result.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/config/runtime.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/config/tenant.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/exceptions.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/ext/__init__.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/ext/config.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/ext/embed.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/ext/external.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/ext/plugins.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/ext/repos.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/ext/storage.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/ext/util.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/launch/__init__.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/launch/__main__.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/launch/cli.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/launch/launch.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/__init__.py +20 -20
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/common.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/config.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/custom.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/data.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/file.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/job.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/object.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/object_id.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/resource.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/search.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/storage.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/tag.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/tag_update.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/metadata/type.py +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/tracdap_runtime.egg-info/SOURCES.txt +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/tracdap_runtime.egg-info/dependency_links.txt +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/tracdap_runtime.egg-info/requires.txt +0 -0
- {tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/tracdap_runtime.egg-info/top_level.txt +0 -0
{tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/resources.py
RENAMED
|
@@ -86,3 +86,27 @@ class ResourceManager:
|
|
|
86
86
|
raise _ex.ETracInternal(f"External system [{system_name}] is not available")
|
|
87
87
|
|
|
88
88
|
return system
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class ResourceMeta(type):
|
|
92
|
+
|
|
93
|
+
# Use a placeholder type for representing resources in the execution engine
|
|
94
|
+
# This allows resource objects to be defined and type checked during graph processing
|
|
95
|
+
|
|
96
|
+
__RESOURCE_TYPES = [_external.IExternalSystem]
|
|
97
|
+
|
|
98
|
+
def __instancecheck__(self, instance):
|
|
99
|
+
for resource_type in self.__RESOURCE_TYPES:
|
|
100
|
+
if isinstance(instance, resource_type):
|
|
101
|
+
return True
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
def __subclasscheck__(self, subclass):
|
|
105
|
+
for resource_type in self.__RESOURCE_TYPES:
|
|
106
|
+
if issubclass(subclass, resource_type):
|
|
107
|
+
return True
|
|
108
|
+
return False
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class Resource(metaclass=ResourceMeta):
|
|
112
|
+
pass
|
{tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/core/validation.py
RENAMED
|
@@ -68,24 +68,39 @@ def is_primitive_type(basic_type: meta.BasicType) -> bool:
|
|
|
68
68
|
|
|
69
69
|
T_PLUGIN = tp.TypeVar("T_PLUGIN")
|
|
70
70
|
|
|
71
|
+
|
|
71
72
|
def plugin_validation_wrapper(plugin_api: tp.Type[T_PLUGIN], plugin: T_PLUGIN) -> T_PLUGIN:
|
|
72
73
|
|
|
73
74
|
# Create a wrapper that validates return values from plugin API calls
|
|
74
|
-
#
|
|
75
|
+
# Use ABC registration to pass isinstance() checks, only register each wrapper type once
|
|
75
76
|
# Since plugins are not exposed directly to client code, this approach should suffice
|
|
76
77
|
|
|
78
|
+
if not hasattr(plugin_validation_wrapper, "__registrations"):
|
|
79
|
+
plugin_validation_wrapper.__registrations = {}
|
|
80
|
+
|
|
81
|
+
if plugin_api in plugin_validation_wrapper.__registrations:
|
|
82
|
+
wrapper_class = plugin_validation_wrapper.__registrations[plugin_api]
|
|
83
|
+
return wrapper_class(plugin)
|
|
84
|
+
|
|
77
85
|
class PluginValidationWrapper:
|
|
78
86
|
|
|
79
87
|
def __init__(self, delegate: T_PLUGIN):
|
|
80
88
|
self.__delegate = delegate
|
|
89
|
+
self.__cache = dict()
|
|
81
90
|
|
|
82
91
|
def __getattr__(self, name: str) -> tp.Any:
|
|
83
92
|
|
|
93
|
+
# Do not create a new wrapped method object on every call
|
|
94
|
+
cache_method = self.__cache.get(name)
|
|
95
|
+
if cache_method:
|
|
96
|
+
return cache_method
|
|
97
|
+
|
|
84
98
|
# Use abstract method to validate (concrete plugin may have bad annotations)
|
|
85
99
|
abstract_method = getattr(plugin_api, name)
|
|
86
100
|
concrete_method = getattr(self.__delegate, name)
|
|
87
101
|
|
|
88
102
|
if abstract_method is None or not callable(abstract_method):
|
|
103
|
+
self.__cache[name] = concrete_method
|
|
89
104
|
return concrete_method
|
|
90
105
|
|
|
91
106
|
def wrapped_method(*args, **kwargs):
|
|
@@ -100,13 +115,11 @@ def plugin_validation_wrapper(plugin_api: tp.Type[T_PLUGIN], plugin: T_PLUGIN) -
|
|
|
100
115
|
message = f"Invalid plugin: [{util.qualified_type_name(type(plugin))}] {detail}"
|
|
101
116
|
raise ex.EPluginConformance(message) from e
|
|
102
117
|
|
|
118
|
+
self.__cache[name] = wrapped_method
|
|
103
119
|
return wrapped_method
|
|
104
120
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def __subclasscheck__(self, subclass: tp.Any) -> bool:
|
|
109
|
-
return issubclass(subclass, self._interface)
|
|
121
|
+
plugin_validation_wrapper.__registrations[plugin_api] = PluginValidationWrapper
|
|
122
|
+
plugin_api.register(PluginValidationWrapper)
|
|
110
123
|
|
|
111
124
|
return PluginValidationWrapper(plugin)
|
|
112
125
|
|
|
@@ -609,9 +622,9 @@ class StaticValidator:
|
|
|
609
622
|
if resource.resourceType == meta.ResourceType.EXTERNAL_SYSTEM:
|
|
610
623
|
if resource.protocol is None or len(resource.protocol) == 0:
|
|
611
624
|
cls._fail(f"Invalid model resource: [{resource_name}] protocol is missing")
|
|
612
|
-
if resource.system.
|
|
625
|
+
if resource.system.clientType is None or len(resource.system.clientType) == 0:
|
|
613
626
|
cls._fail(f"Invalid model resource: [{resource_name}] client type is missing")
|
|
614
|
-
if not cls.__qualified_identifier_pattern.match(resource.system.
|
|
627
|
+
if not cls.__qualified_identifier_pattern.match(resource.system.clientType):
|
|
615
628
|
cls._fail(f"Invalid model resource: [{resource_name}] client type is not a valid Python type")
|
|
616
629
|
|
|
617
630
|
else:
|
{tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/context.py
RENAMED
|
@@ -122,9 +122,8 @@ class TracContextImpl(_api.TracContext):
|
|
|
122
122
|
|
|
123
123
|
:param model_def: Definition object for the model that will run in this context
|
|
124
124
|
:param model_class: Type for the model that will run in this context
|
|
125
|
-
:param local_ctx: Dictionary of all parameters, inputs and
|
|
126
|
-
Parameters are supplied as python native types.
|
|
127
|
-
Output views will contain schemas but no data.
|
|
125
|
+
:param local_ctx: Dictionary of all parameters, inputs, outputs and resources that will be available to the model.
|
|
126
|
+
Parameters are supplied as python native types. Output views will contain schemas but no data.
|
|
128
127
|
"""
|
|
129
128
|
|
|
130
129
|
def __init__(self,
|
|
@@ -132,7 +131,6 @@ class TracContextImpl(_api.TracContext):
|
|
|
132
131
|
model_class: _api.TracModel.__class__,
|
|
133
132
|
local_ctx: tp.Dict[str, tp.Any],
|
|
134
133
|
dynamic_outputs: tp.List[str] = None,
|
|
135
|
-
resources: tp.Dict[str, tp.Any] = None,
|
|
136
134
|
log_provider: _logging.LogProvider = None,
|
|
137
135
|
checkout_directory: pathlib.Path = None):
|
|
138
136
|
|
|
@@ -147,14 +145,12 @@ class TracContextImpl(_api.TracContext):
|
|
|
147
145
|
self.__model_class = model_class
|
|
148
146
|
self.__local_ctx = local_ctx if local_ctx is not None else {}
|
|
149
147
|
self.__dynamic_outputs = dynamic_outputs if dynamic_outputs is not None else []
|
|
150
|
-
self.__resources = resources if resources is not None else {}
|
|
151
148
|
self.__rct = _util.RuntimeContextTracking()
|
|
152
149
|
|
|
153
150
|
self.__val = TracContextValidator(
|
|
154
151
|
self.__ctx_log,
|
|
155
152
|
self.__model_def,
|
|
156
153
|
self.__local_ctx,
|
|
157
|
-
self.__resources,
|
|
158
154
|
self.__dynamic_outputs,
|
|
159
155
|
checkout_directory)
|
|
160
156
|
|
|
@@ -327,7 +323,7 @@ class TracContextImpl(_api.TracContext):
|
|
|
327
323
|
self.__val.check_item_defined_in_model(system_name, TracContextValidator.SYSTEM)
|
|
328
324
|
self.__val.check_item_available_in_context(system_name, TracContextValidator.SYSTEM)
|
|
329
325
|
|
|
330
|
-
system = self.
|
|
326
|
+
system = self.__local_ctx.get(system_name)
|
|
331
327
|
|
|
332
328
|
self.__val.check_context_object_type(system_name, system, TracExternalSystemWrapper)
|
|
333
329
|
self.__val.check_external_system_client_type(system_name, system, client_type)
|
|
@@ -547,7 +543,7 @@ class TracDataContextImpl(TracContextImpl, _eapi.TracDataContext):
|
|
|
547
543
|
storage_map: tp.Dict[str, tp.Union[_eapi.TracFileStorage, _eapi.TracDataStorage]],
|
|
548
544
|
log_provider: _logging.LogProvider = None, checkout_directory: pathlib.Path = None):
|
|
549
545
|
|
|
550
|
-
super().__init__(model_def, model_class, local_ctx, dynamic_outputs,
|
|
546
|
+
super().__init__(model_def, model_class, local_ctx, dynamic_outputs, log_provider, checkout_directory)
|
|
551
547
|
|
|
552
548
|
self.__model_def = model_def
|
|
553
549
|
self.__local_ctx = local_ctx
|
|
@@ -939,7 +935,6 @@ class TracContextValidator(TracContextErrorReporter):
|
|
|
939
935
|
self, log: logging.Logger,
|
|
940
936
|
model_def: _meta.ModelDefinition,
|
|
941
937
|
local_ctx: tp.Dict[str, tp.Any],
|
|
942
|
-
resources: tp.Dict[str, tp.Any],
|
|
943
938
|
dynamic_outputs: tp.List[str],
|
|
944
939
|
checkout_directory: pathlib.Path):
|
|
945
940
|
|
|
@@ -947,7 +942,6 @@ class TracContextValidator(TracContextErrorReporter):
|
|
|
947
942
|
|
|
948
943
|
self.__model_def = model_def
|
|
949
944
|
self.__local_ctx = local_ctx
|
|
950
|
-
self.__resources = resources
|
|
951
945
|
self.__dynamic_outputs = dynamic_outputs
|
|
952
946
|
|
|
953
947
|
def check_item_valid_identifier(self, item_name: str, item_type: str):
|
|
@@ -985,16 +979,12 @@ class TracContextValidator(TracContextErrorReporter):
|
|
|
985
979
|
|
|
986
980
|
def check_item_available_in_context(self, item_name: str, item_type: str):
|
|
987
981
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
if item_name not in ctx:
|
|
982
|
+
if item_name not in self.__local_ctx:
|
|
991
983
|
self._report_error(f"{item_type} {item_name} is not available in the current context")
|
|
992
984
|
|
|
993
985
|
def check_item_not_available_in_context(self, item_name: str, item_type: str):
|
|
994
986
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
if item_name in ctx:
|
|
987
|
+
if item_name in self.__local_ctx:
|
|
998
988
|
self._report_error(f"{item_type} {item_name} already exists in the current context")
|
|
999
989
|
|
|
1000
990
|
def check_dataset_is_dynamic_output(self, dataset_name: str):
|
|
@@ -1161,7 +1151,7 @@ class TracContextValidator(TracContextErrorReporter):
|
|
|
1161
1151
|
def check_external_system_client_type(self, system_name, system, client_type):
|
|
1162
1152
|
|
|
1163
1153
|
model_system = self.__model_def.resources.get(system_name)
|
|
1164
|
-
model_type_name = model_system.system.
|
|
1154
|
+
model_type_name = model_system.system.clientType if model_system and model_system.system else None
|
|
1165
1155
|
client_type_name = _util.qualified_type_name(client_type)
|
|
1166
1156
|
|
|
1167
1157
|
if client_type_name != model_type_name:
|
{tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/dev_mode.py
RENAMED
|
@@ -551,7 +551,7 @@ class DevModeTranslator:
|
|
|
551
551
|
errors[target_key] = f"Flow target {target_name} is not provided by any node"
|
|
552
552
|
|
|
553
553
|
for node_name, node in flow.nodes.items():
|
|
554
|
-
if node.nodeType
|
|
554
|
+
if node.nodeType in [_meta.FlowNodeType.INPUT_NODE, _meta.FlowNodeType.PARAMETER_NODE, _meta.FlowNodeType.RESOURCE_NODE]:
|
|
555
555
|
add_source(node_name, _meta.FlowSocket(node_name))
|
|
556
556
|
if node.nodeType == _meta.FlowNodeType.MODEL_NODE:
|
|
557
557
|
for model_output in node.outputs:
|
|
@@ -574,6 +574,8 @@ class DevModeTranslator:
|
|
|
574
574
|
add_edge(_meta.FlowSocket(node_name, model_input))
|
|
575
575
|
for model_param in node.parameters:
|
|
576
576
|
add_edge(_meta.FlowSocket(node_name, model_param))
|
|
577
|
+
for model_resource in node.resources:
|
|
578
|
+
add_edge(_meta.FlowSocket(node_name, model_resource))
|
|
577
579
|
|
|
578
580
|
if any(errors):
|
|
579
581
|
|
|
@@ -613,6 +615,11 @@ class DevModeTranslator:
|
|
|
613
615
|
|
|
614
616
|
for node_name, node in flow.nodes.items():
|
|
615
617
|
|
|
618
|
+
if node.nodeType == _meta.FlowNodeType.RESOURCE_NODE and node_name not in flow.resources:
|
|
619
|
+
targets = edges_by_source.get(node_name) or []
|
|
620
|
+
model_resource = cls._infer_resource(node_name, targets, job_def, job_config)
|
|
621
|
+
updated_flow.resources[node_name] = model_resource
|
|
622
|
+
|
|
616
623
|
if node.nodeType == _meta.FlowNodeType.PARAMETER_NODE and node_name not in flow.parameters:
|
|
617
624
|
targets = edges_by_source.get(node_name) or []
|
|
618
625
|
model_parameter = cls._infer_parameter(node_name, targets, job_def, job_config)
|
|
@@ -631,28 +638,56 @@ class DevModeTranslator:
|
|
|
631
638
|
return updated_flow
|
|
632
639
|
|
|
633
640
|
@classmethod
|
|
634
|
-
def
|
|
635
|
-
cls,
|
|
641
|
+
def _infer_resource(
|
|
642
|
+
cls, resource_name: str, targets: tp.List[_meta.FlowSocket],
|
|
636
643
|
job_def: _meta.JobDefinition, job_config: _cfg.JobConfig) \
|
|
637
|
-
-> _meta.
|
|
644
|
+
-> _meta.ModelResource:
|
|
638
645
|
|
|
639
|
-
|
|
646
|
+
model_resources = cls._infer_targets(
|
|
647
|
+
resource_name, targets, lambda model: model.resources,
|
|
648
|
+
job_def, job_config)
|
|
640
649
|
|
|
641
|
-
|
|
650
|
+
model_resource: _meta.ModelResource = model_resources[0]
|
|
642
651
|
|
|
643
|
-
|
|
644
|
-
model_obj = _util.get_job_metadata(model_selector, job_config)
|
|
645
|
-
model_param = model_obj.model.parameters.get(target.socket)
|
|
646
|
-
model_params.append(model_param)
|
|
652
|
+
for i in range(1, len(targets)):
|
|
647
653
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
654
|
+
next_resource: _meta.ModelResource = model_resources[i]
|
|
655
|
+
|
|
656
|
+
if next_resource.resourceType != model_resource.resourceType:
|
|
657
|
+
err = f"Resource is ambiguous for [{resource_name}]: " + \
|
|
658
|
+
f"Resource types are different for [{cls._socket_key(targets[0])}] and [{cls._socket_key(targets[i])}]"
|
|
659
|
+
raise _ex.EJobValidation(err)
|
|
660
|
+
|
|
661
|
+
if model_resource.protocol is None:
|
|
662
|
+
model_resource.protocol = next_resource.protocol
|
|
663
|
+
elif model_resource.protocol != next_resource.protocol:
|
|
664
|
+
err = f"Resource is ambiguous for [{resource_name}]: " + \
|
|
665
|
+
f"Protocols are different for [{cls._socket_key(targets[0])}] and [{cls._socket_key(targets[i])}]"
|
|
666
|
+
raise _ex.EJobValidation(err)
|
|
667
|
+
|
|
668
|
+
if model_resource.subProtocol is None:
|
|
669
|
+
model_resource.subProtocol = next_resource.subProtocol
|
|
670
|
+
elif model_resource.subProtocol != next_resource.subProtocol:
|
|
671
|
+
err = f"Resource is ambiguous for [{resource_name}]: " + \
|
|
672
|
+
f"Sub protocols are different for [{cls._socket_key(targets[0])}] and [{cls._socket_key(targets[i])}]"
|
|
673
|
+
raise _ex.EJobValidation(err)
|
|
674
|
+
|
|
675
|
+
# System details are informational, safe to remove if they are not a match
|
|
676
|
+
if model_resource.system is not None and next_resource.system is not None:
|
|
677
|
+
if model_resource.system != next_resource.system:
|
|
678
|
+
model_resource.system = None
|
|
679
|
+
|
|
680
|
+
return model_resource
|
|
681
|
+
|
|
682
|
+
@classmethod
|
|
683
|
+
def _infer_parameter(
|
|
684
|
+
cls, param_name: str, targets: tp.List[_meta.FlowSocket],
|
|
685
|
+
job_def: _meta.JobDefinition, job_config: _cfg.JobConfig) \
|
|
686
|
+
-> _meta.ModelParameter:
|
|
653
687
|
|
|
654
|
-
|
|
655
|
-
|
|
688
|
+
model_params = cls._infer_targets(
|
|
689
|
+
param_name, targets, lambda model: model.parameters,
|
|
690
|
+
job_def, job_config)
|
|
656
691
|
|
|
657
692
|
model_param = model_params[0]
|
|
658
693
|
|
|
@@ -673,23 +708,9 @@ class DevModeTranslator:
|
|
|
673
708
|
job_def: _meta.JobDefinition, job_config: _cfg.JobConfig) \
|
|
674
709
|
-> _meta.ModelInputSchema:
|
|
675
710
|
|
|
676
|
-
model_inputs =
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
model_selector = job_def.runFlow.models.get(target.node)
|
|
681
|
-
model_obj = _util.get_job_metadata(model_selector, job_config)
|
|
682
|
-
model_input = model_obj.model.inputs.get(target.socket)
|
|
683
|
-
model_inputs.append(model_input)
|
|
684
|
-
|
|
685
|
-
if len(model_inputs) == 0:
|
|
686
|
-
err = f"Flow input [{input_name}] is not connected to any models, schema cannot be inferred" \
|
|
687
|
-
+ f" (either remove the input or connect it to a model)"
|
|
688
|
-
cls._log.error(err)
|
|
689
|
-
raise _ex.EJobValidation(err)
|
|
690
|
-
|
|
691
|
-
if len(model_inputs) == 1:
|
|
692
|
-
return model_inputs[0]
|
|
711
|
+
model_inputs = cls._infer_targets(
|
|
712
|
+
input_name, targets, lambda model: model.inputs,
|
|
713
|
+
job_def, job_config)
|
|
693
714
|
|
|
694
715
|
model_input = model_inputs[0]
|
|
695
716
|
|
|
@@ -708,29 +729,44 @@ class DevModeTranslator:
|
|
|
708
729
|
job_def: _meta.JobDefinition, job_config: _cfg.JobConfig) \
|
|
709
730
|
-> _meta.ModelOutputSchema:
|
|
710
731
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
model_selector = job_def.runFlow.models.get(source.node)
|
|
716
|
-
model_obj = _util.get_job_metadata(model_selector, job_config)
|
|
717
|
-
model_input = model_obj.model.outputs.get(source.socket)
|
|
718
|
-
model_outputs.append(model_input)
|
|
719
|
-
|
|
720
|
-
if len(model_outputs) == 0:
|
|
721
|
-
err = f"Flow output [{output_name}] is not connected to any models, schema cannot be inferred" \
|
|
722
|
-
+ f" (either remove the output or connect it to a model)"
|
|
723
|
-
cls._log.error(err)
|
|
724
|
-
raise _ex.EJobValidation(err)
|
|
732
|
+
# Lookup logic is the same for source and target sockets
|
|
733
|
+
model_outputs = cls._infer_targets(
|
|
734
|
+
output_name, sources, lambda model: model.outputs,
|
|
735
|
+
job_def, job_config)
|
|
725
736
|
|
|
726
737
|
if len(model_outputs) > 1:
|
|
727
|
-
err = f"Flow output [{output_name}] is
|
|
738
|
+
err = f"Flow output [{output_name}] is connected to multiple models" \
|
|
728
739
|
+ f" (only one model can supply one output)"
|
|
729
740
|
cls._log.error(err)
|
|
730
741
|
raise _ex.EJobValidation(err)
|
|
731
742
|
|
|
732
743
|
return model_outputs[0]
|
|
733
744
|
|
|
745
|
+
@classmethod
|
|
746
|
+
def _infer_targets(
|
|
747
|
+
cls, node_name: str, targets, target_func: tp.Callable[[_meta.ModelDefinition], dict],
|
|
748
|
+
job_def: _meta.JobDefinition, job_config: _cfg.JobConfig):
|
|
749
|
+
|
|
750
|
+
# Common logic to look up inference targets
|
|
751
|
+
|
|
752
|
+
target_objects = []
|
|
753
|
+
|
|
754
|
+
for targets in targets:
|
|
755
|
+
|
|
756
|
+
model_selector = job_def.runFlow.models.get(targets.node)
|
|
757
|
+
model_obj = _util.get_job_metadata(model_selector, job_config)
|
|
758
|
+
target_map = target_func(model_obj.model)
|
|
759
|
+
target_obj = target_map.get(targets.socket)
|
|
760
|
+
target_objects.append(target_obj)
|
|
761
|
+
|
|
762
|
+
if len(target_objects) == 0:
|
|
763
|
+
err = f"Flow node [{node_name}] is not connected to any models, type inference is not possible" \
|
|
764
|
+
+ f" (either remove this node or connect it to a model)"
|
|
765
|
+
cls._log.error(err)
|
|
766
|
+
raise _ex.EJobValidation(err)
|
|
767
|
+
|
|
768
|
+
return target_objects
|
|
769
|
+
|
|
734
770
|
@classmethod
|
|
735
771
|
def _socket_key(cls, socket):
|
|
736
772
|
return f"{socket.node}.{socket.socket}" if socket.socket else socket.node
|
{tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/engine.py
RENAMED
|
@@ -1190,6 +1190,7 @@ class NodeLogger:
|
|
|
1190
1190
|
PUSH_POP = 2
|
|
1191
1191
|
SIMPLE_MAPPING = 3
|
|
1192
1192
|
MODEL = 4
|
|
1193
|
+
RESOURCE = 5
|
|
1193
1194
|
|
|
1194
1195
|
def log_node_start(self, node: _EngineNode):
|
|
1195
1196
|
|
|
@@ -1203,6 +1204,9 @@ class NodeLogger:
|
|
|
1203
1204
|
elif logging_type in [self.LoggingType.SIMPLE_MAPPING]:
|
|
1204
1205
|
self._log.info(f"MAP {self._value_type(node)} [{self._mapping_source(node)}] -> [{node_name}] / {namespace}")
|
|
1205
1206
|
|
|
1207
|
+
elif logging_type == self.LoggingType.RESOURCE:
|
|
1208
|
+
self._log.info(f"USE {self._func_type(node)} [{node_name}] / {namespace}")
|
|
1209
|
+
|
|
1206
1210
|
else:
|
|
1207
1211
|
self._log.info(f"START {self._func_type(node)} [{node_name}] / {namespace}")
|
|
1208
1212
|
|
|
@@ -1212,7 +1216,7 @@ class NodeLogger:
|
|
|
1212
1216
|
node_name = node.node.id.name
|
|
1213
1217
|
namespace = node.node.id.namespace
|
|
1214
1218
|
|
|
1215
|
-
if logging_type in [self.LoggingType.STATIC_VALUE, self.LoggingType.SIMPLE_MAPPING]:
|
|
1219
|
+
if logging_type in [self.LoggingType.STATIC_VALUE, self.LoggingType.SIMPLE_MAPPING, self.LoggingType.RESOURCE]:
|
|
1216
1220
|
return
|
|
1217
1221
|
|
|
1218
1222
|
if logging_type == self.LoggingType.PUSH_POP:
|
|
@@ -1237,7 +1241,7 @@ class NodeLogger:
|
|
|
1237
1241
|
node_name = node.node.id.name
|
|
1238
1242
|
namespace = node.node.id.namespace
|
|
1239
1243
|
|
|
1240
|
-
if logging_type in [self.LoggingType.STATIC_VALUE, self.LoggingType.SIMPLE_MAPPING]:
|
|
1244
|
+
if logging_type in [self.LoggingType.STATIC_VALUE, self.LoggingType.SIMPLE_MAPPING, self.LoggingType.RESOURCE]:
|
|
1241
1245
|
return
|
|
1242
1246
|
|
|
1243
1247
|
self._log.info(f"EVICT {self._func_type(node)} [{node_name}] / {namespace}")
|
|
@@ -1276,6 +1280,9 @@ class NodeLogger:
|
|
|
1276
1280
|
if isinstance(node.node, _graph.RunModelNode):
|
|
1277
1281
|
return cls.LoggingType.MODEL
|
|
1278
1282
|
|
|
1283
|
+
if isinstance(node.node, _graph.ResourceNode):
|
|
1284
|
+
return cls.LoggingType.RESOURCE
|
|
1285
|
+
|
|
1279
1286
|
return cls.LoggingType.DEFAULT
|
|
1280
1287
|
|
|
1281
1288
|
@classmethod
|
{tracdap_runtime-0.10.0.dev3 → tracdap_runtime-0.10.0.dev4}/src/tracdap/rt/_impl/exec/functions.py
RENAMED
|
@@ -33,6 +33,7 @@ import tracdap.rt._impl.core.storage as _storage
|
|
|
33
33
|
import tracdap.rt._impl.core.struct as _struct
|
|
34
34
|
import tracdap.rt._impl.core.models as _models
|
|
35
35
|
import tracdap.rt._impl.core.util as _util
|
|
36
|
+
import tracdap.rt.ext.external as _ext_system
|
|
36
37
|
|
|
37
38
|
from tracdap.rt._impl.exec.graph import *
|
|
38
39
|
from tracdap.rt._impl.exec.graph import _T
|
|
@@ -213,6 +214,21 @@ class ContextPopFunc(_ContextPushPopFunc):
|
|
|
213
214
|
super(ContextPopFunc, self).__init__(node, self._POP)
|
|
214
215
|
|
|
215
216
|
|
|
217
|
+
# RESOURCE PROVISION
|
|
218
|
+
# ------------------
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class ResourceFunc(NodeFunction):
|
|
222
|
+
|
|
223
|
+
def __init__(self, node: ResourceNode, resource: _resources.Resource):
|
|
224
|
+
super().__init__()
|
|
225
|
+
self.node = node
|
|
226
|
+
self.resource = resource
|
|
227
|
+
|
|
228
|
+
def _execute(self, ctx: NodeContext) -> _resources.Resource:
|
|
229
|
+
return self.resource
|
|
230
|
+
|
|
231
|
+
|
|
216
232
|
# DATA HANDLING
|
|
217
233
|
# -------------
|
|
218
234
|
|
|
@@ -599,6 +615,8 @@ class RunModelFunc(NodeFunction[Bundle[_data.DataView]]):
|
|
|
599
615
|
if node_id.namespace == self.node.id.namespace:
|
|
600
616
|
if node_id.name in model_def.parameters or node_id.name in model_def.inputs:
|
|
601
617
|
local_ctx[node_id.name] = node_result
|
|
618
|
+
elif node_id.name in model_def.resources:
|
|
619
|
+
local_ctx[node_id.name] = self._wrap_resource(node_id.name, node_result)
|
|
602
620
|
|
|
603
621
|
# Run the model against the mapped local context
|
|
604
622
|
|
|
@@ -610,7 +628,7 @@ class RunModelFunc(NodeFunction[Bundle[_data.DataView]]):
|
|
|
610
628
|
else:
|
|
611
629
|
trac_ctx = _ctx.TracContextImpl(
|
|
612
630
|
self.node.model_def, self.model_class,
|
|
613
|
-
local_ctx, dynamic_outputs,
|
|
631
|
+
local_ctx, dynamic_outputs,
|
|
614
632
|
self.log_provider, self.checkout_directory)
|
|
615
633
|
|
|
616
634
|
try:
|
|
@@ -648,6 +666,13 @@ class RunModelFunc(NodeFunction[Bundle[_data.DataView]]):
|
|
|
648
666
|
|
|
649
667
|
return results
|
|
650
668
|
|
|
669
|
+
def _wrap_resource(self, resource_name, resource):
|
|
670
|
+
|
|
671
|
+
if isinstance(resource, _ext_system.IExternalSystem):
|
|
672
|
+
return _ctx.TracExternalSystemWrapper(resource)
|
|
673
|
+
|
|
674
|
+
raise _ex.EJobValidation(f"Unsupported resource [{resource_name}] of type [{type(resource).__name__}]")
|
|
675
|
+
|
|
651
676
|
|
|
652
677
|
# RESULTS PROCESSING
|
|
653
678
|
# ------------------
|
|
@@ -828,6 +853,20 @@ class FunctionResolver:
|
|
|
828
853
|
|
|
829
854
|
return resolve_func(self, node)
|
|
830
855
|
|
|
856
|
+
def resolve_resource_node(self, node: ResourceNode):
|
|
857
|
+
|
|
858
|
+
if node.model_resource is not None:
|
|
859
|
+
resource_def = self._resources.get_resource_definition(node.resource_key)
|
|
860
|
+
self._check_model_resource(node.resource_key, node.model_resource, resource_def)
|
|
861
|
+
|
|
862
|
+
if node.resource_type == _meta.ResourceType.EXTERNAL_SYSTEM:
|
|
863
|
+
resource = self._resources.get_external_system(node.resource_key)
|
|
864
|
+
else:
|
|
865
|
+
# Other resource types not currently used as graph nodes
|
|
866
|
+
raise _ex.EUnexpected()
|
|
867
|
+
|
|
868
|
+
return ResourceFunc(node, resource)
|
|
869
|
+
|
|
831
870
|
def resolve_load_data(self, node: LoadDataNode):
|
|
832
871
|
return LoadDataFunc(node, self._resources.get_storage())
|
|
833
872
|
|
|
@@ -845,10 +884,10 @@ class FunctionResolver:
|
|
|
845
884
|
model_class = model_loader.load_model_class(node.model_scope, node.model_def)
|
|
846
885
|
checkout_directory = model_loader.model_load_checkout_directory(node.model_scope, node.model_def)
|
|
847
886
|
|
|
848
|
-
# Prepare
|
|
849
|
-
|
|
887
|
+
# Prepare external storage resources - Missing resources will raise an error during the resolve phase
|
|
888
|
+
storage_map = self._resolve_model_storage_resources(node, checkout_directory, self._log_provider)
|
|
850
889
|
|
|
851
|
-
return RunModelFunc(node, model_class,
|
|
890
|
+
return RunModelFunc(node, model_class, storage_map, self._log_provider, checkout_directory)
|
|
852
891
|
|
|
853
892
|
__basic_node_mapping: tp.Dict[Node.__class__, NodeFunction.__class__] = {
|
|
854
893
|
|
|
@@ -869,33 +908,21 @@ class FunctionResolver:
|
|
|
869
908
|
|
|
870
909
|
__node_mapping: tp.Dict[Node.__class__, tp.Callable[["FunctionResolver", Node], NodeFunction]] = {
|
|
871
910
|
|
|
911
|
+
ResourceNode: resolve_resource_node,
|
|
872
912
|
LoadDataNode: resolve_load_data,
|
|
873
913
|
SaveDataNode: resolve_save_data,
|
|
874
914
|
RunModelNode: resolve_run_model_node,
|
|
875
915
|
ImportModelNode: resolve_import_model_node
|
|
876
916
|
}
|
|
877
917
|
|
|
878
|
-
def
|
|
918
|
+
def _resolve_model_storage_resources(
|
|
879
919
|
self, node: RunModelNode,
|
|
880
920
|
checkout_directory, log_provider) \
|
|
881
921
|
-> tp.Dict[str, tp.Any]:
|
|
882
922
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
for model_resource_key, model_resource in node.model_def.resources.items():
|
|
886
|
-
|
|
887
|
-
resource_key = node.resource_mapping.get(model_resource_key)
|
|
888
|
-
resource_def = self._resources.get_resource_definition(resource_key) if resource_key else None
|
|
889
|
-
|
|
890
|
-
self._check_model_resource(
|
|
891
|
-
model_resource_key, model_resource,
|
|
892
|
-
resource_key, resource_def)
|
|
893
|
-
|
|
894
|
-
if resource_def.resourceType == _meta.ResourceType.EXTERNAL_SYSTEM:
|
|
895
|
-
system_impl = self._resources.get_external_system(resource_key)
|
|
896
|
-
system = _ctx.TracExternalSystemWrapper(system_impl)
|
|
897
|
-
resources[model_resource_key] = system
|
|
923
|
+
storage_map = {}
|
|
898
924
|
|
|
925
|
+
# TODO: Switch to resource nodes for external storage
|
|
899
926
|
if node.storage_access:
|
|
900
927
|
|
|
901
928
|
storage_manager = self._resources.get_storage()
|
|
@@ -905,7 +932,7 @@ class FunctionResolver:
|
|
|
905
932
|
if storage_manager.has_file_storage(storage_key, external=True):
|
|
906
933
|
storage_impl = storage_manager.get_file_storage(storage_key, external=True)
|
|
907
934
|
storage = _ctx.TracFileStorageImpl(storage_key, storage_impl, write_access, checkout_directory, log_provider)
|
|
908
|
-
|
|
935
|
+
storage_map[storage_key] = storage
|
|
909
936
|
elif storage_manager.has_data_storage(storage_key, external=True):
|
|
910
937
|
storage_impl = storage_manager.get_data_storage(storage_key, external=True)
|
|
911
938
|
# This is a work-around until the storage extension API can be updated / unified
|
|
@@ -913,31 +940,29 @@ class FunctionResolver:
|
|
|
913
940
|
raise _ex.EStorageConfig(f"External storage for [{storage_key}] is using the legacy storage framework]")
|
|
914
941
|
converter = _data.DataConverter.noop()
|
|
915
942
|
storage = _ctx.TracDataStorageImpl(storage_key, storage_impl, converter, write_access, checkout_directory, log_provider)
|
|
916
|
-
|
|
943
|
+
storage_map[storage_key] = storage
|
|
917
944
|
else:
|
|
918
945
|
raise _ex.EStorageConfig(f"External storage is not available: [{storage_key}]")
|
|
919
946
|
|
|
920
|
-
return
|
|
947
|
+
return storage_map
|
|
921
948
|
|
|
922
949
|
@classmethod
|
|
923
950
|
def _check_model_resource(
|
|
924
|
-
cls,
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
if resource_key is None:
|
|
928
|
-
raise _ex.EJobValidation(f"Resource [{model_resource_key}] is not available (missing resource mapping)")
|
|
951
|
+
cls, resource_key: str,
|
|
952
|
+
model_resource: _meta.ModelResource,
|
|
953
|
+
resource_def: _meta.ResourceDefinition):
|
|
929
954
|
|
|
930
955
|
if resource_def is None:
|
|
931
|
-
raise _ex.EJobValidation(f"Resource [{
|
|
956
|
+
raise _ex.EJobValidation(f"Resource [{resource_key}] is not available)")
|
|
932
957
|
|
|
933
958
|
if model_resource.resourceType != resource_def.resourceType:
|
|
934
959
|
detail = f"(expected {model_resource.resourceType}, got {resource_def.resourceType})"
|
|
935
|
-
raise _ex.EJobValidation(f"Resource [{
|
|
960
|
+
raise _ex.EJobValidation(f"Resource [{resource_key}] is not compatible with the model {detail}")
|
|
936
961
|
|
|
937
962
|
if model_resource.protocol and model_resource.protocol != resource_def.protocol:
|
|
938
963
|
detail = f"(expected protocol {model_resource.protocol}, got protocol {resource_def.protocol})"
|
|
939
|
-
raise _ex.EJobValidation(f"Resource [{
|
|
964
|
+
raise _ex.EJobValidation(f"Resource [{resource_key}] is not compatible with the model {detail}")
|
|
940
965
|
|
|
941
966
|
if model_resource.subProtocol and model_resource.subProtocol != resource_def.subProtocol:
|
|
942
967
|
detail = f"(expected sub-protocol {model_resource.protocol}, got sub-protocol {resource_def.protocol})"
|
|
943
|
-
raise _ex.EJobValidation(f"Resource [{
|
|
968
|
+
raise _ex.EJobValidation(f"Resource [{resource_key}] is not compatible with the model {detail}")
|