tracdap-runtime 0.8.0b3__tar.gz → 0.8.0b4__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.8.0b3/tracdap_runtime.egg-info → tracdap_runtime-0.8.0b4}/PKG-INFO +14 -12
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/README.md +4 -3
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/setup.cfg +10 -10
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/config_parser.py +55 -37
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/data.py +63 -32
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/storage.py +4 -1
- tracdap_runtime-0.8.0b4/src/tracdap/rt/_impl/core/struct.py +547 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/type_system.py +73 -33
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/validation.py +56 -15
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/exec/context.py +64 -10
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/exec/dev_mode.py +25 -14
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/exec/functions.py +79 -29
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.py +2 -2
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2_grpc.py +1 -1
- tracdap_runtime-0.8.0b4/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.py +63 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.pyi +48 -2
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/static_api.py +9 -1
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/storage_sql.py +12 -5
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_version.py +1 -1
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/api/experimental.py +32 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/api/hook.py +11 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/config/__init__.py +7 -10
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/config/common.py +0 -34
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/config/platform.py +6 -26
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/__init__.py +11 -9
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/data.py +40 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4/tracdap_runtime.egg-info}/PKG-INFO +14 -12
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/tracdap_runtime.egg-info/SOURCES.txt +1 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/tracdap_runtime.egg-info/requires.txt +9 -7
- tracdap_runtime-0.8.0b3/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.py +0 -51
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/LICENSE +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/pyproject.toml +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/guard_rails.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/logging.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/models.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/repos.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/schemas.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/shim.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/util.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/exec/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/exec/actors.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/exec/engine.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/exec/graph.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/exec/graph_builder.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/ext/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/ext/sql.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/ext/storage.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/codec.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/server.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/stoarge_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/stoarge_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.pyi +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/runtime.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/_helpers.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/config_local.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/format_arrow.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/format_csv.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/format_parquet.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/repo_git.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/repo_local.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/repo_pypi.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/storage_aws.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/storage_azure.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/storage_gcp.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/storage_local.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_plugins/storage_sql_dialects.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/api/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/api/file_types.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/api/model_api.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/api/static_api.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/config/job.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/config/result.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/config/runtime.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/exceptions.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/ext/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/ext/config.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/ext/embed.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/ext/plugins.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/ext/repos.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/ext/storage.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/launch/__init__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/launch/__main__.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/launch/cli.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/launch/launch.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/common.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/custom.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/file.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/flow.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/job.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/model.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/object.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/object_id.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/resource.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/search.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/stoarge.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/tag.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/tag_update.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/metadata/type.py +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/tracdap_runtime.egg-info/dependency_links.txt +0 -0
- {tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/tracdap_runtime.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: tracdap-runtime
|
3
|
-
Version: 0.8.
|
3
|
+
Version: 0.8.0b4
|
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
|
@@ -13,19 +13,20 @@ Platform: any
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
14
14
|
Classifier: License :: OSI Approved :: Apache Software License
|
15
15
|
Classifier: Operating System :: OS Independent
|
16
|
-
Requires-Python: <3.
|
16
|
+
Requires-Python: <3.14,>=3.9
|
17
17
|
Description-Content-Type: text/markdown
|
18
18
|
License-File: LICENSE
|
19
|
-
Requires-Dist: protobuf==5.
|
20
|
-
Requires-Dist: pyarrow==
|
19
|
+
Requires-Dist: protobuf==5.29.3
|
20
|
+
Requires-Dist: pyarrow==18.1.0
|
21
21
|
Requires-Dist: pyyaml==6.0.2
|
22
|
-
Requires-Dist: dulwich==0.22.
|
22
|
+
Requires-Dist: dulwich==0.22.7
|
23
23
|
Requires-Dist: requests==2.32.3
|
24
|
-
Requires-Dist: pandas<2.3.0,>=1.2.0
|
25
|
-
Requires-Dist: numpy<2.0.0
|
26
24
|
Provides-Extra: grpc
|
27
|
-
Requires-Dist: grpcio==1.
|
28
|
-
Requires-Dist: grpcio-status==1.
|
25
|
+
Requires-Dist: grpcio==1.70.0; extra == "grpc"
|
26
|
+
Requires-Dist: grpcio-status==1.70.0; extra == "grpc"
|
27
|
+
Provides-Extra: pandas
|
28
|
+
Requires-Dist: pandas<2.3.0,>=1.2.0; extra == "pandas"
|
29
|
+
Requires-Dist: numpy<2.3.0,>=1.20; extra == "pandas"
|
29
30
|
Provides-Extra: polars
|
30
31
|
Requires-Dist: polars<2.0.0,>=1.0.0; extra == "polars"
|
31
32
|
Provides-Extra: pyspark
|
@@ -64,12 +65,13 @@ Documentation for the TRAC platform is available on our website at
|
|
64
65
|
|
65
66
|
The TRAC runtime for Python has these requirements:
|
66
67
|
|
67
|
-
* Python: 3.
|
68
|
+
* Python: 3.9 up to 3.13
|
68
69
|
* Pandas: 1.2 up to 2.2
|
69
70
|
* PySpark 3.0 up to 3.5 (optional)
|
70
71
|
|
71
|
-
3rd party libraries may impose additional constraints on supported versions of
|
72
|
-
|
72
|
+
3rd party libraries may impose additional constraints on supported versions of key libraries.
|
73
|
+
For example, Pandas 1.5 is not available for Python 3.12 or 3.13, while NumPy 2.0 is only
|
74
|
+
compatible with Pandas 2.1 and later.
|
73
75
|
|
74
76
|
## Installing the runtime
|
75
77
|
|
@@ -16,12 +16,13 @@ Documentation for the TRAC platform is available on our website at
|
|
16
16
|
|
17
17
|
The TRAC runtime for Python has these requirements:
|
18
18
|
|
19
|
-
* Python: 3.
|
19
|
+
* Python: 3.9 up to 3.13
|
20
20
|
* Pandas: 1.2 up to 2.2
|
21
21
|
* PySpark 3.0 up to 3.5 (optional)
|
22
22
|
|
23
|
-
3rd party libraries may impose additional constraints on supported versions of
|
24
|
-
|
23
|
+
3rd party libraries may impose additional constraints on supported versions of key libraries.
|
24
|
+
For example, Pandas 1.5 is not available for Python 3.12 or 3.13, while NumPy 2.0 is only
|
25
|
+
compatible with Pandas 2.1 and later.
|
25
26
|
|
26
27
|
## Installing the runtime
|
27
28
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[metadata]
|
2
2
|
name = tracdap-runtime
|
3
|
-
version = 0.8.
|
3
|
+
version = 0.8.0b4
|
4
4
|
description = Runtime package for building models on the TRAC Data & Analytics Platform
|
5
5
|
long_description = file: README.md
|
6
6
|
long_description_content_type = text/markdown
|
@@ -38,21 +38,21 @@ packages =
|
|
38
38
|
package_dir =
|
39
39
|
tracdap = src/tracdap
|
40
40
|
tracdap.rt = src/tracdap/rt
|
41
|
-
python_requires = >= 3.
|
41
|
+
python_requires = >= 3.9, < 3.14
|
42
42
|
install_requires =
|
43
|
-
protobuf == 5.
|
44
|
-
pyarrow ==
|
43
|
+
protobuf == 5.29.3
|
44
|
+
pyarrow == 18.1.0
|
45
45
|
pyyaml == 6.0.2
|
46
|
-
dulwich == 0.22.
|
46
|
+
dulwich == 0.22.7
|
47
47
|
requests == 2.32.3
|
48
|
-
|
49
|
-
pandas >= 1.2.0, < 2.3.0
|
50
|
-
numpy < 2.0.0
|
51
48
|
|
52
49
|
[options.extras_require]
|
53
50
|
grpc =
|
54
|
-
grpcio == 1.
|
55
|
-
grpcio-status == 1.
|
51
|
+
grpcio == 1.70.0
|
52
|
+
grpcio-status == 1.70.0
|
53
|
+
pandas =
|
54
|
+
pandas >= 1.2.0, < 2.3.0
|
55
|
+
numpy >= 1.20, < 2.3.0
|
56
56
|
polars =
|
57
57
|
polars >= 1.0.0, < 2.0.0
|
58
58
|
pyspark =
|
{tracdap_runtime-0.8.0b3 → tracdap_runtime-0.8.0b4}/src/tracdap/rt/_impl/core/config_parser.py
RENAMED
@@ -12,14 +12,6 @@
|
|
12
12
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
|
-
#
|
16
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
17
|
-
#
|
18
|
-
# Unless required by applicable law or agreed to in writing, software
|
19
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
20
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
21
|
-
# See the License for the specific language governing permissions and
|
22
|
-
# limitations under the License.
|
23
15
|
|
24
16
|
import dataclasses as _dc
|
25
17
|
import decimal
|
@@ -30,6 +22,7 @@ import json
|
|
30
22
|
import os
|
31
23
|
import pathlib
|
32
24
|
import re
|
25
|
+
import types as ts
|
33
26
|
import typing as tp
|
34
27
|
import urllib.parse as _urlp
|
35
28
|
import uuid
|
@@ -44,6 +37,11 @@ import tracdap.rt._impl.core.util as _util
|
|
44
37
|
import yaml
|
45
38
|
import yaml.parser
|
46
39
|
|
40
|
+
try:
|
41
|
+
import pydantic as _pyd # noqa
|
42
|
+
except ModuleNotFoundError:
|
43
|
+
_pyd = None
|
44
|
+
|
47
45
|
_T = tp.TypeVar('_T')
|
48
46
|
|
49
47
|
|
@@ -286,9 +284,17 @@ class ConfigManager:
|
|
286
284
|
|
287
285
|
class ConfigParser(tp.Generic[_T]):
|
288
286
|
|
289
|
-
#
|
290
|
-
#
|
291
|
-
|
287
|
+
# Support both new and old styles for generic, union and optional types
|
288
|
+
# Old-style annotations are still valid, even when the new style is fully supported
|
289
|
+
__generic_types: list[type] = [
|
290
|
+
ts.GenericAlias,
|
291
|
+
type(tp.List[int]),
|
292
|
+
type(tp.Optional[int])
|
293
|
+
]
|
294
|
+
|
295
|
+
# UnionType was added to the types module in Python 3.10, we support 3.9 (Jan 2025)
|
296
|
+
if hasattr(ts, "UnionType"):
|
297
|
+
__generic_types.append(ts.UnionType)
|
292
298
|
|
293
299
|
__primitive_types: tp.Dict[type, callable] = {
|
294
300
|
bool: bool,
|
@@ -328,6 +334,23 @@ class ConfigParser(tp.Generic[_T]):
|
|
328
334
|
|
329
335
|
def _parse_value(self, location: str, raw_value: tp.Any, annotation: type):
|
330
336
|
|
337
|
+
if self._is_dev_mode_location(location):
|
338
|
+
|
339
|
+
if type(raw_value) in ConfigParser.__primitive_types:
|
340
|
+
return self._parse_primitive(location, raw_value, type(raw_value))
|
341
|
+
|
342
|
+
if isinstance(raw_value, list):
|
343
|
+
if len(raw_value) == 0:
|
344
|
+
return []
|
345
|
+
items = iter((self._child_location(location, i), x) for i, x in enumerate(raw_value))
|
346
|
+
return list(self._parse_value(loc, x, tp.Any) for loc, x in items)
|
347
|
+
|
348
|
+
if isinstance(raw_value, dict):
|
349
|
+
if len(raw_value) == 0:
|
350
|
+
return {}
|
351
|
+
items = iter((self._child_location(location, k), k, v) for k, v in raw_value.items())
|
352
|
+
return dict((k, self._parse_value(loc, v, tp.Any)) for loc, k, v in items)
|
353
|
+
|
331
354
|
if raw_value is None:
|
332
355
|
return None
|
333
356
|
|
@@ -346,24 +369,17 @@ class ConfigParser(tp.Generic[_T]):
|
|
346
369
|
return self._parse_enum(location, raw_value, annotation)
|
347
370
|
|
348
371
|
if _dc.is_dataclass(annotation):
|
372
|
+
return self._parse_simple_class(location, raw_value, annotation)
|
349
373
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
if self._is_dev_mode_location(location):
|
354
|
-
if type(raw_value) in ConfigParser.__primitive_types:
|
355
|
-
return self._parse_primitive(location, raw_value, type(raw_value))
|
356
|
-
if isinstance(raw_value, list):
|
357
|
-
if len(raw_value) == 0:
|
358
|
-
return []
|
359
|
-
list_type = type(raw_value[0])
|
360
|
-
return list(map(lambda x: self._parse_primitive(location, x, list_type), raw_value))
|
374
|
+
# Basic support for Pydantic, if it is installed
|
375
|
+
if _pyd and isinstance(annotation, type) and issubclass(annotation, _pyd.BaseModel):
|
376
|
+
return self._parse_simple_class(location, raw_value, annotation)
|
361
377
|
|
362
|
-
|
363
|
-
|
364
|
-
if isinstance(annotation, self.__generic_metaclass):
|
378
|
+
if any(map(lambda _t: isinstance(annotation, _t), self.__generic_types)):
|
365
379
|
return self._parse_generic_class(location, raw_value, annotation) # noqa
|
366
380
|
|
381
|
+
return self._error(location, f"Cannot parse value of type {annotation.__name__}")
|
382
|
+
|
367
383
|
def _is_dev_mode_location(self, location):
|
368
384
|
|
369
385
|
return any(map(lambda pattern: re.match(pattern, location), self._dev_mode_locations))
|
@@ -423,14 +439,14 @@ class ConfigParser(tp.Generic[_T]):
|
|
423
439
|
def _parse_simple_class(self, location: str, raw_dict: tp.Any, metaclass: type) -> object:
|
424
440
|
|
425
441
|
if raw_dict is not None and not isinstance(raw_dict, dict):
|
426
|
-
|
442
|
+
return self._error(location, f"Expected type {metaclass.__name__}, got '{str(raw_dict)}'")
|
427
443
|
|
428
444
|
obj = metaclass.__new__(metaclass, object()) # noqa
|
429
445
|
|
430
446
|
init_signature = inspect.signature(metaclass.__init__)
|
431
447
|
init_types = tp.get_type_hints(metaclass.__init__)
|
432
448
|
init_params = iter(init_signature.parameters.items())
|
433
|
-
init_values: tp.
|
449
|
+
init_values: tp.Dict[str, tp.Any] = dict()
|
434
450
|
|
435
451
|
# Do not process 'self'
|
436
452
|
next(init_params)
|
@@ -444,20 +460,20 @@ class ConfigParser(tp.Generic[_T]):
|
|
444
460
|
message = f"Class {metaclass.__name__} does not support config decoding: " + \
|
445
461
|
f"Missing type information for init parameter '{param_name}'"
|
446
462
|
self._error(location, message)
|
447
|
-
init_values
|
463
|
+
init_values[param_name] = None
|
448
464
|
|
449
465
|
elif param_name in raw_dict and raw_dict[param_name] is not None:
|
450
466
|
param_value = self._parse_value(param_location, raw_dict[param_name], param_type)
|
451
|
-
init_values
|
467
|
+
init_values[param_name] = param_value
|
452
468
|
|
453
469
|
elif param.default != inspect._empty: # noqa
|
454
|
-
init_values
|
470
|
+
init_values[param_name] = param.default
|
455
471
|
|
456
472
|
else:
|
457
473
|
self._error(location, f"Missing required value '{param_name}'")
|
458
|
-
init_values
|
474
|
+
init_values[param_name] = None
|
459
475
|
|
460
|
-
binding = init_signature.bind(obj,
|
476
|
+
binding = init_signature.bind(obj, **init_values)
|
461
477
|
metaclass.__init__(*binding.args, **binding.kwargs)
|
462
478
|
|
463
479
|
# Now go back over the members and look for any that weren't declared in __init__
|
@@ -478,7 +494,7 @@ class ConfigParser(tp.Generic[_T]):
|
|
478
494
|
self._error(location, message)
|
479
495
|
|
480
496
|
# Generic members must be declared in __init__ since that is the only way to get the full annotation
|
481
|
-
if isinstance(type(default_value), self.
|
497
|
+
if any(map(lambda _t: isinstance(type(default_value), _t), self.__generic_types)):
|
482
498
|
message = f"Class {metaclass.__name__} does not support config decoding: " + \
|
483
499
|
f"Members with no default value must be declared in __init__: '{member_name}'"
|
484
500
|
self._error(location, message)
|
@@ -504,7 +520,7 @@ class ConfigParser(tp.Generic[_T]):
|
|
504
520
|
|
505
521
|
return obj
|
506
522
|
|
507
|
-
def _parse_generic_class(self, location: str, raw_value: tp.Any,
|
523
|
+
def _parse_generic_class(self, location: str, raw_value: tp.Any, metaclass: type):
|
508
524
|
|
509
525
|
origin = _util.get_origin(metaclass)
|
510
526
|
args = _util.get_args(metaclass)
|
@@ -517,7 +533,7 @@ class ConfigParser(tp.Generic[_T]):
|
|
517
533
|
return self._error(location, f"Expected a list, got {type(raw_value)}")
|
518
534
|
|
519
535
|
return [
|
520
|
-
self._parse_value(self._child_location(location,
|
536
|
+
self._parse_value(self._child_location(location, idx), item, list_type)
|
521
537
|
for (idx, item) in enumerate(raw_value)]
|
522
538
|
|
523
539
|
if origin == tp.Dict or origin == dict:
|
@@ -548,12 +564,14 @@ class ConfigParser(tp.Generic[_T]):
|
|
548
564
|
return None
|
549
565
|
|
550
566
|
@staticmethod
|
551
|
-
def _child_location(parent_location: str, item: str):
|
567
|
+
def _child_location(parent_location: str, item: tp.Union[str, int]):
|
552
568
|
|
553
569
|
if parent_location is None or parent_location == "":
|
554
570
|
return item
|
571
|
+
elif isinstance(item, int):
|
572
|
+
return f"{parent_location}[{item}]"
|
555
573
|
else:
|
556
|
-
return parent_location
|
574
|
+
return f"{parent_location}.{item}"
|
557
575
|
|
558
576
|
|
559
577
|
class ConfigQuoter:
|
@@ -44,6 +44,7 @@ import tracdap.rt._impl.core.logging as _log
|
|
44
44
|
class DataSpec:
|
45
45
|
|
46
46
|
object_type: _meta.ObjectType
|
47
|
+
schema_type: _meta.SchemaType
|
47
48
|
data_item: str
|
48
49
|
|
49
50
|
data_def: _meta.DataDefinition
|
@@ -58,8 +59,15 @@ class DataSpec:
|
|
58
59
|
storage_def: _meta.StorageDefinition,
|
59
60
|
schema_def: tp.Optional[_meta.SchemaDefinition] = None) -> "DataSpec":
|
60
61
|
|
62
|
+
if schema_def:
|
63
|
+
schema_type = schema_def.schemaType
|
64
|
+
elif data_def.schema:
|
65
|
+
schema_type = data_def.schema.schemaType
|
66
|
+
else:
|
67
|
+
schema_type = _meta.SchemaType.SCHEMA_TYPE_NOT_SET
|
68
|
+
|
61
69
|
return DataSpec(
|
62
|
-
_meta.ObjectType.DATA, data_item,
|
70
|
+
_meta.ObjectType.DATA, schema_type, data_item,
|
63
71
|
data_def,
|
64
72
|
storage_def=storage_def,
|
65
73
|
schema_def=schema_def,
|
@@ -72,15 +80,15 @@ class DataSpec:
|
|
72
80
|
storage_def: _meta.StorageDefinition) -> "DataSpec":
|
73
81
|
|
74
82
|
return DataSpec(
|
75
|
-
_meta.ObjectType.FILE, data_item,
|
83
|
+
_meta.ObjectType.FILE, _meta.SchemaType.SCHEMA_TYPE_NOT_SET, data_item,
|
76
84
|
file_def=file_def,
|
77
85
|
storage_def=storage_def,
|
78
86
|
data_def=None,
|
79
87
|
schema_def=None)
|
80
88
|
|
81
89
|
@staticmethod
|
82
|
-
def create_empty_spec(object_type: _meta.ObjectType):
|
83
|
-
return DataSpec(object_type, None, None, None, None, None)
|
90
|
+
def create_empty_spec(object_type: _meta.ObjectType, schema_type: _meta.SchemaType):
|
91
|
+
return DataSpec(object_type, schema_type, None, None, None, None, None)
|
84
92
|
|
85
93
|
def is_empty(self):
|
86
94
|
return self.data_item is None or len(self.data_item) == 0
|
@@ -100,32 +108,54 @@ class DataPartKey:
|
|
100
108
|
class DataItem:
|
101
109
|
|
102
110
|
object_type: _meta.ObjectType
|
111
|
+
schema_type: _meta.SchemaType
|
112
|
+
|
113
|
+
content: tp.Any = None
|
114
|
+
content_type: tp.Type = None
|
115
|
+
content_func: tp.Callable[[], tp.Any] = None
|
116
|
+
|
117
|
+
trac_schema: _meta.SchemaDefinition = None
|
118
|
+
native_schema: tp.Any = None
|
103
119
|
|
120
|
+
# TODO: Remove legacy API and use content / native_schema instead
|
104
121
|
schema: pa.Schema = None
|
105
122
|
table: tp.Optional[pa.Table] = None
|
106
|
-
batches: tp.Optional[tp.List[pa.RecordBatch]] = None
|
107
123
|
|
108
|
-
|
109
|
-
|
124
|
+
def is_empty(self) -> bool:
|
125
|
+
return self.content is None
|
110
126
|
|
111
|
-
|
127
|
+
@staticmethod
|
128
|
+
def create_empty(
|
129
|
+
object_type: _meta.ObjectType = _meta.ObjectType.DATA,
|
130
|
+
schema_type: _meta.SchemaType = _meta.SchemaType.TABLE) -> "DataItem":
|
112
131
|
|
113
|
-
|
114
|
-
|
115
|
-
return self.raw_bytes is None or len(self.raw_bytes) == 0
|
132
|
+
if object_type == _meta.ObjectType.DATA and schema_type == _meta.SchemaType.TABLE:
|
133
|
+
return DataItem(_meta.ObjectType.DATA, _meta.SchemaType.TABLE, schema=pa.schema([]))
|
116
134
|
else:
|
117
|
-
return
|
135
|
+
return DataItem(object_type, schema_type)
|
118
136
|
|
119
137
|
@staticmethod
|
120
|
-
def
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
138
|
+
def for_table(table: pa.Table, schema: pa.Schema, trac_schema: _meta.SchemaDefinition) -> "DataItem":
|
139
|
+
|
140
|
+
return DataItem(
|
141
|
+
_meta.ObjectType.DATA, _meta.SchemaType.TABLE,
|
142
|
+
content=table, content_type=pa.Table,
|
143
|
+
trac_schema=trac_schema, native_schema=schema,
|
144
|
+
table=table, schema=schema)
|
145
|
+
|
146
|
+
@staticmethod
|
147
|
+
def for_struct(content: tp.Any):
|
148
|
+
|
149
|
+
return DataItem(
|
150
|
+
_meta.ObjectType.DATA, _meta.SchemaType.STRUCT,
|
151
|
+
content=content, content_type=type(content))
|
125
152
|
|
126
153
|
@staticmethod
|
127
|
-
def for_file_content(
|
128
|
-
|
154
|
+
def for_file_content(content: bytes):
|
155
|
+
|
156
|
+
return DataItem(
|
157
|
+
_meta.ObjectType.FILE, _meta.SchemaType.SCHEMA_TYPE_NOT_SET,
|
158
|
+
content=content, content_type=bytes)
|
129
159
|
|
130
160
|
|
131
161
|
@dc.dataclass(frozen=True)
|
@@ -148,8 +178,11 @@ class DataView:
|
|
148
178
|
|
149
179
|
@staticmethod
|
150
180
|
def for_trac_schema(trac_schema: _meta.SchemaDefinition):
|
151
|
-
|
152
|
-
|
181
|
+
if trac_schema.schemaType == _meta.SchemaType.TABLE:
|
182
|
+
arrow_schema = DataMapping.trac_to_arrow_schema(trac_schema)
|
183
|
+
return DataView(_meta.ObjectType.DATA, trac_schema, arrow_schema, dict())
|
184
|
+
else:
|
185
|
+
return DataView(_meta.ObjectType.DATA, trac_schema, parts = dict())
|
153
186
|
|
154
187
|
@staticmethod
|
155
188
|
def for_file_item(file_item: DataItem):
|
@@ -381,29 +414,27 @@ class DataMapping:
|
|
381
414
|
if not deltas:
|
382
415
|
raise _ex.ETracInternal(f"Data view for part [{part.opaque_key}] does not contain any items")
|
383
416
|
|
417
|
+
# For a single delta, use the existing Arrow content
|
384
418
|
if len(deltas) == 1:
|
385
419
|
return cls.item_to_arrow(deltas[0])
|
386
420
|
|
387
|
-
|
421
|
+
# For multiple deltas, construct a new table by assembling the record batches
|
422
|
+
# Atm no consideration is given to overwriting records based on business key
|
423
|
+
batches = iter(
|
388
424
|
batch
|
389
425
|
for delta in deltas
|
390
|
-
for batch in (
|
391
|
-
delta.batches
|
392
|
-
if delta.batches
|
393
|
-
else delta.table.to_batches())}
|
426
|
+
for batch in cls.item_to_arrow(delta).to_batches())
|
394
427
|
|
395
428
|
return pa.Table.from_batches(batches) # noqa
|
396
429
|
|
397
430
|
@classmethod
|
398
431
|
def item_to_arrow(cls, item: DataItem) -> pa.Table:
|
399
432
|
|
400
|
-
if item.
|
401
|
-
|
402
|
-
|
403
|
-
if item.batches is not None:
|
404
|
-
return pa.Table.from_batches(item.batches, item.schema) # noqa
|
433
|
+
if item.content_type != pa.Table:
|
434
|
+
detail = f"expected Arrow table, got [{item.content_type}]"
|
435
|
+
raise _ex.ETracInternal(f"Data item does not contain tabular data ({detail})")
|
405
436
|
|
406
|
-
|
437
|
+
return item.content
|
407
438
|
|
408
439
|
@classmethod
|
409
440
|
def arrow_to_pandas(
|
@@ -496,7 +496,10 @@ class CommonFileStorage(IFileStorage):
|
|
496
496
|
|
497
497
|
# For successful write streams, log the total size written
|
498
498
|
if is_write and not error:
|
499
|
-
|
499
|
+
if not stream.closed:
|
500
|
+
file_size = _util.format_file_size(stream.tell())
|
501
|
+
else:
|
502
|
+
file_size = self._fs.get_file_info(storage_path).size
|
500
503
|
self._log.info(f"File size [{self._key}]: {file_size} [{storage_path}]")
|
501
504
|
|
502
505
|
# Close the stream - this may take time for write streams that are not flushed
|