tracdap-runtime 0.9.0b1__tar.gz → 0.9.0b2__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.
Files changed (140) hide show
  1. {tracdap_runtime-0.9.0b1/tracdap_runtime.egg-info → tracdap_runtime-0.9.0b2}/PKG-INFO +3 -3
  2. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/setup.cfg +3 -3
  3. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/config_parser.py +29 -3
  4. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/data.py +93 -51
  5. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/repos.py +15 -13
  6. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/storage.py +17 -12
  7. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/struct.py +254 -60
  8. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/util.py +94 -23
  9. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/exec/context.py +35 -8
  10. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/exec/dev_mode.py +60 -40
  11. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/exec/engine.py +44 -50
  12. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/exec/functions.py +12 -8
  13. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/exec/graph.py +3 -3
  14. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/exec/graph_builder.py +22 -5
  15. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/codec.py +4 -11
  16. tracdap_runtime-0.9.0b2/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.py +65 -0
  17. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.pyi +37 -43
  18. tracdap_runtime-0.9.0b2/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.py +134 -0
  19. tracdap_runtime-0.9.0b2/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.py +51 -0
  20. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.pyi +15 -2
  21. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/runtime.py +2 -16
  22. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/static_api.py +5 -6
  23. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/format_csv.py +2 -2
  24. tracdap_runtime-0.9.0b2/src/tracdap/rt/_plugins/storage_aws.py +399 -0
  25. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/storage_azure.py +17 -11
  26. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/storage_gcp.py +35 -18
  27. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_version.py +1 -1
  28. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/api/model_api.py +45 -0
  29. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/config/__init__.py +8 -10
  30. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/config/common.py +0 -16
  31. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/config/job.py +4 -0
  32. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/config/platform.py +9 -32
  33. tracdap_runtime-0.9.0b2/src/tracdap/rt/config/runtime.py +23 -0
  34. tracdap_runtime-0.9.0b2/src/tracdap/rt/config/tenant.py +28 -0
  35. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/launch/cli.py +0 -8
  36. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/launch/launch.py +1 -3
  37. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/__init__.py +18 -19
  38. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/data.py +19 -31
  39. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/job.py +1 -1
  40. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/type.py +9 -5
  41. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2/tracdap_runtime.egg-info}/PKG-INFO +3 -3
  42. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/tracdap_runtime.egg-info/SOURCES.txt +1 -0
  43. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/tracdap_runtime.egg-info/requires.txt +2 -2
  44. tracdap_runtime-0.9.0b1/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.py +0 -63
  45. tracdap_runtime-0.9.0b1/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.py +0 -134
  46. tracdap_runtime-0.9.0b1/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.py +0 -47
  47. tracdap_runtime-0.9.0b1/src/tracdap/rt/_plugins/storage_aws.py +0 -384
  48. tracdap_runtime-0.9.0b1/src/tracdap/rt/config/runtime.py +0 -30
  49. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/LICENSE +0 -0
  50. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/README.md +0 -0
  51. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/pyproject.toml +0 -0
  52. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/__init__.py +0 -0
  53. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/__init__.py +0 -0
  54. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/__init__.py +0 -0
  55. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/guard_rails.py +0 -0
  56. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/logging.py +0 -0
  57. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/models.py +0 -0
  58. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/schemas.py +0 -0
  59. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/shim.py +0 -0
  60. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/type_system.py +0 -0
  61. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/core/validation.py +0 -0
  62. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/exec/__init__.py +0 -0
  63. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/exec/actors.py +0 -0
  64. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/ext/__init__.py +0 -0
  65. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/ext/sql.py +0 -0
  66. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/ext/storage.py +0 -0
  67. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/__init__.py +0 -0
  68. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/server.py +0 -0
  69. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.py +0 -0
  70. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.pyi +0 -0
  71. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2_grpc.py +0 -0
  72. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.py +0 -0
  73. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.pyi +0 -0
  74. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/config_pb2.py +0 -0
  75. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/config_pb2.pyi +0 -0
  76. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.py +0 -0
  77. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.pyi +0 -0
  78. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.py +0 -0
  79. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.pyi +0 -0
  80. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.py +0 -0
  81. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.pyi +0 -0
  82. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.pyi +0 -0
  83. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.py +0 -0
  84. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.pyi +0 -0
  85. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.py +0 -0
  86. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.pyi +0 -0
  87. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.py +0 -0
  88. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.pyi +0 -0
  89. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.py +0 -0
  90. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.pyi +0 -0
  91. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.py +0 -0
  92. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.pyi +0 -0
  93. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/storage_pb2.py +0 -0
  94. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/storage_pb2.pyi +0 -0
  95. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.py +0 -0
  96. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.pyi +0 -0
  97. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.py +0 -0
  98. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.pyi +0 -0
  99. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/__init__.py +0 -0
  100. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/_helpers.py +0 -0
  101. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/config_local.py +0 -0
  102. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/format_arrow.py +0 -0
  103. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/format_parquet.py +0 -0
  104. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/repo_git.py +0 -0
  105. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/repo_local.py +0 -0
  106. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/repo_pypi.py +0 -0
  107. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/storage_local.py +0 -0
  108. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/storage_sql.py +0 -0
  109. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/_plugins/storage_sql_dialects.py +0 -0
  110. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/api/__init__.py +0 -0
  111. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/api/constants.py +0 -0
  112. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/api/experimental.py +0 -0
  113. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/api/hook.py +0 -0
  114. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/api/static_api.py +0 -0
  115. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/config/dynamic.py +0 -0
  116. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/config/result.py +0 -0
  117. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/exceptions.py +0 -0
  118. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/ext/__init__.py +0 -0
  119. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/ext/config.py +0 -0
  120. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/ext/embed.py +0 -0
  121. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/ext/plugins.py +0 -0
  122. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/ext/repos.py +0 -0
  123. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/ext/storage.py +0 -0
  124. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/launch/__init__.py +0 -0
  125. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/launch/__main__.py +0 -0
  126. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/common.py +0 -0
  127. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/config.py +0 -0
  128. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/custom.py +0 -0
  129. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/file.py +0 -0
  130. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/flow.py +0 -0
  131. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/model.py +0 -0
  132. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/object.py +0 -0
  133. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/object_id.py +0 -0
  134. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/resource.py +0 -0
  135. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/search.py +0 -0
  136. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/storage.py +0 -0
  137. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/tag.py +0 -0
  138. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/src/tracdap/rt/metadata/tag_update.py +0 -0
  139. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/tracdap_runtime.egg-info/dependency_links.txt +0 -0
  140. {tracdap_runtime-0.9.0b1 → tracdap_runtime-0.9.0b2}/tracdap_runtime.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tracdap-runtime
3
- Version: 0.9.0b1
3
+ Version: 0.9.0b2
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
@@ -16,11 +16,11 @@ Classifier: Operating System :: OS Independent
16
16
  Requires-Python: <3.14,>=3.9
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: protobuf==5.29.3
19
+ Requires-Dist: protobuf==5.29.5
20
20
  Requires-Dist: pyarrow==18.1.0
21
21
  Requires-Dist: pyyaml==6.0.2
22
22
  Requires-Dist: dulwich==0.22.7
23
- Requires-Dist: requests==2.32.3
23
+ Requires-Dist: requests==2.32.4
24
24
  Requires-Dist: typing_extensions<4.13
25
25
  Requires-Dist: urllib3<2.4.0
26
26
  Provides-Extra: grpc
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = tracdap-runtime
3
- version = 0.9.0b1
3
+ version = 0.9.0b2
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
@@ -40,11 +40,11 @@ package_dir =
40
40
  tracdap.rt = src/tracdap/rt
41
41
  python_requires = >= 3.9, < 3.14
42
42
  install_requires =
43
- protobuf == 5.29.3
43
+ protobuf == 5.29.5
44
44
  pyarrow == 18.1.0
45
45
  pyyaml == 6.0.2
46
46
  dulwich == 0.22.7
47
- requests == 2.32.3
47
+ requests == 2.32.4
48
48
  typing_extensions < 4.13
49
49
  urllib3 < 2.4.0
50
50
 
@@ -45,6 +45,26 @@ except ModuleNotFoundError:
45
45
  _T = tp.TypeVar('_T')
46
46
 
47
47
 
48
+ class ConfigKeys:
49
+
50
+ STORAGE_DEFAULT_LOCATION = "storage.default.location"
51
+ STORAGE_DEFAULT_FORMAT = "storage.default.format"
52
+ STORAGE_DEFAULT_LAYOUT = "storage.default.layout"
53
+
54
+ RESULT_ENABLED = "result.enabled"
55
+ RESULT_LOGS_ENABLED = "result.logs.enabled"
56
+ RESULT_STORAGE_LOCATION = "result.storage.location"
57
+ RESULT_STORAGE_PATH = "result.storage.path"
58
+ RESULT_FORMAT = "result.format"
59
+
60
+
61
+
62
+ class ConfigKDefaults:
63
+
64
+ STORAGE_DEFAULT_FORMAT = "CSV"
65
+ STORAGE_DEFAULT_LAYOUT = "OBJECT_ID_LAYOUT"
66
+
67
+
48
68
  class ConfigManager:
49
69
 
50
70
  @classmethod
@@ -479,10 +499,16 @@ class ConfigParser(tp.Generic[_T]):
479
499
  # Now go back over the members and look for any that weren't declared in __init__
480
500
  # Members with non-generic default values can still be read from the input stream
481
501
 
482
- for member_name in obj.__dict__:
502
+ def member_names():
503
+ if hasattr(obj, "__slots__"):
504
+ return filter(lambda s: hasattr(obj, s), obj.__slots__)
505
+ else:
506
+ return dir(obj)
507
+
508
+ for member_name in member_names():
483
509
 
484
510
  member_location = self._child_location(location, member_name)
485
- default_value = obj.__dict__[member_name]
511
+ default_value = getattr(obj, member_name)
486
512
 
487
513
  if member_name in init_signature.parameters or member_name.startswith("_"):
488
514
  continue
@@ -510,7 +536,7 @@ class ConfigParser(tp.Generic[_T]):
510
536
 
511
537
  for raw_name in raw_dict.keys():
512
538
 
513
- if raw_name not in obj.__dict__:
539
+ if not hasattr(obj, raw_name):
514
540
  self._error(location, f"Unrecognised config parameter '{raw_name}'")
515
541
 
516
542
  if raw_name == "self" or raw_name.startswith("_"):
@@ -40,6 +40,7 @@ import tracdap.rt.api.experimental as _api
40
40
  import tracdap.rt.metadata as _meta
41
41
  import tracdap.rt.config as _cfg
42
42
  import tracdap.rt.exceptions as _ex
43
+ import tracdap.rt._impl.core.config_parser as _cfg_p
43
44
  import tracdap.rt._impl.core.logging as _log
44
45
  import tracdap.rt._impl.core.util as _util
45
46
 
@@ -70,6 +71,8 @@ class DataSpec:
70
71
  schema_id: tp.Optional[_meta.TagHeader] = None
71
72
  context_key: tp.Optional[str] = None
72
73
 
74
+ metadata: tp.Optional[_api.RuntimeMetadata] = None
75
+
73
76
  @staticmethod
74
77
  def create_data_spec(
75
78
  data_item: str,
@@ -108,37 +111,44 @@ class DataSpec:
108
111
  schema_id: tp.Optional[_meta.TagHeader] = None,
109
112
  context_key: tp.Optional[str] = None):
110
113
 
111
- return DataSpec(
112
- self.object_type, self.schema_type, self.data_item,
113
- self.definition, self.storage, self.schema,
114
- primary_id, storage_id, schema_id, context_key)
114
+ return dc.replace(self,
115
+ primary_id=primary_id,
116
+ storage_id=storage_id,
117
+ schema_id=schema_id,
118
+ context_key=context_key)
119
+
120
+ def with_metadata(self, metadata: tp.Optional[_api.RuntimeMetadata]):
121
+ return dc.replace(self, metadata=metadata)
115
122
 
116
123
  def is_empty(self):
117
124
  return self.data_item is None or len(self.data_item) == 0
118
125
 
119
126
 
120
- class StorageLayout:
127
+ class StorageLayout(metaclass=abc.ABCMeta):
121
128
 
122
- __LAYOUTS: "tp.Dict[_meta.StorageLayout, StorageLayout]" = dict()
129
+ __LAYOUTS: "tp.Dict[str, StorageLayout]" = dict()
123
130
 
124
131
  @classmethod
125
- def select(cls, layout_key: _meta.StorageLayout) -> "StorageLayout":
132
+ def select(cls, layout_key: tp.Union[str, _meta.StorageLayout]) -> "StorageLayout":
126
133
 
127
134
  # Legacy compatibility - layout key not set in storage definition
128
- if not layout_key or layout_key.value == 0:
129
- layout_key = _meta.StorageLayout.OBJECT_ID_LAYOUT
135
+ if not layout_key or layout_key == "":
136
+ layout_key = _meta.StorageLayout.OBJECT_ID_LAYOUT.name
137
+
138
+ if isinstance(layout_key, _meta.StorageLayout):
139
+ layout_key = layout_key.name
130
140
 
131
141
  layout = cls.__LAYOUTS.get(layout_key)
132
142
 
133
143
  if layout is not None:
134
144
  return layout
135
145
 
136
- if layout_key == _meta.StorageLayout.OBJECT_ID_LAYOUT:
146
+ if layout_key == _meta.StorageLayout.OBJECT_ID_LAYOUT.name:
137
147
  layout = ObjectIdLayout()
138
- elif layout_key == _meta.StorageLayout.DEVELOPER_LAYOUT:
148
+ elif layout_key == _meta.StorageLayout.DEVELOPER_LAYOUT.name:
139
149
  layout = DevelopmentLayout()
140
150
  else:
141
- raise _ex.ETracInternal(f"Unknown storage layout [{layout_key.name}]")
151
+ raise _ex.ETracInternal(f"Unknown storage layout [{layout_key}]")
142
152
 
143
153
  cls.__LAYOUTS[layout_key] = layout
144
154
 
@@ -152,7 +162,7 @@ class StorageLayout:
152
162
  def new_data_spec(
153
163
  self, data_id: _meta.TagHeader, storage_id: _meta.TagHeader,
154
164
  context_key: tp.Optional[str], trac_schema: _meta.SchemaDefinition,
155
- storage_config: _cfg.StorageConfig) -> DataSpec:
165
+ sys_config: _cfg.RuntimeConfig) -> DataSpec:
156
166
  pass
157
167
 
158
168
  @abc.abstractmethod
@@ -166,7 +176,7 @@ class StorageLayout:
166
176
  def new_file_spec(
167
177
  self, file_id: _meta.TagHeader, storage_id: _meta.TagHeader,
168
178
  context_key: str, file_type: _meta.FileType,
169
- storage_config: _cfg.StorageConfig) -> DataSpec:
179
+ sys_config: _cfg.RuntimeConfig) -> DataSpec:
170
180
  pass
171
181
 
172
182
  @abc.abstractmethod
@@ -177,7 +187,7 @@ class StorageLayout:
177
187
  pass
178
188
 
179
189
 
180
- class BaseLayout(StorageLayout):
190
+ class BaseLayout(StorageLayout, metaclass=abc.ABCMeta):
181
191
 
182
192
  __DATA_ITEM_TEMPLATE = "data/{}/{}/{}/snap-{:d}/delta-{:d}"
183
193
  __FILE_ITEM_TEMPLATE = "file/{}/version-{}"
@@ -198,7 +208,7 @@ class BaseLayout(StorageLayout):
198
208
  def new_data_spec(
199
209
  self, data_id: _meta.TagHeader, storage_id: _meta.TagHeader,
200
210
  context_key: tp.Optional[str], trac_schema: _meta.SchemaDefinition,
201
- storage_config: _cfg.StorageConfig) -> DataSpec:
211
+ sys_config: _cfg.RuntimeConfig) -> DataSpec:
202
212
 
203
213
  part_key = _meta.PartKey("part-root", _meta.PartType.PART_ROOT)
204
214
  snap_index = 0
@@ -215,8 +225,11 @@ class BaseLayout(StorageLayout):
215
225
  data_def = self._add_new_snap(new_data_def, data_item, part_key, snap_index)
216
226
 
217
227
  # Take default location from the storage config
218
- storage_key = storage_config.defaultBucket
219
- storage_format = "JSON" if trac_schema.schemaType == _meta.SchemaType.STRUCT else storage_config.defaultFormat
228
+ storage_key = _util.read_property(sys_config.properties, _cfg_p.ConfigKeys.STORAGE_DEFAULT_LOCATION)
229
+ if trac_schema.schemaType == _meta.SchemaType.STRUCT_SCHEMA:
230
+ storage_format = "text/json"
231
+ else:
232
+ storage_format = _util.read_property(sys_config.properties, _cfg_p.ConfigKeys.STORAGE_DEFAULT_FORMAT, "text/csv")
220
233
  storage_path = self._data_storage_path(data_id, context_key, trac_schema, part_key, snap_index, 0, storage_format, prior_copy=None)
221
234
 
222
235
  storage_copy = _meta.StorageCopy(
@@ -276,7 +289,7 @@ class BaseLayout(StorageLayout):
276
289
  def new_file_spec(
277
290
  self, file_id: _meta.TagHeader, storage_id: _meta.TagHeader,
278
291
  context_key: str, file_type: _meta.FileType,
279
- storage_config: _cfg.StorageConfig) -> DataSpec:
292
+ sys_config: _cfg.RuntimeConfig) -> DataSpec:
280
293
 
281
294
  data_item = self.__FILE_ITEM_TEMPLATE.format(file_id.objectId, file_id.objectVersion)
282
295
 
@@ -288,7 +301,7 @@ class BaseLayout(StorageLayout):
288
301
  storageId=_util.selector_for_latest(storage_id),
289
302
  size=0)
290
303
 
291
- storage_key = storage_config.defaultBucket
304
+ storage_key = _util.read_property(sys_config.properties, _cfg_p.ConfigKeys.STORAGE_DEFAULT_LOCATION)
292
305
  storage_format = file_def.mimeType
293
306
  storage_path = self._file_storage_path(file_id, file_def, prior_copy=None)
294
307
 
@@ -429,11 +442,17 @@ class ObjectIdLayout(BaseLayout):
429
442
  schema_type = trac_schema.schemaType.name.lower()
430
443
  version_suffix = self.__random.randint(0, 1 << 24)
431
444
 
432
- return self.__DATA_STORAGE_TEMPLATE.format(
445
+ base_path = self.__DATA_STORAGE_TEMPLATE.format(
433
446
  schema_type, data_id.objectId,
434
447
  part_key.opaqueKey, snap_index, delta_index,
435
448
  version_suffix)
436
449
 
450
+ # STRUCT stored as a single file, not directory layout
451
+ if trac_schema.schemaType == _meta.SchemaType.STRUCT_SCHEMA:
452
+ return base_path + ".json"
453
+ else:
454
+ return base_path
455
+
437
456
  def _file_storage_path(self, file_id, file_def, prior_copy):
438
457
 
439
458
  version_suffix = self.__random.randint(0, 1 << 24)
@@ -494,37 +513,44 @@ class DevelopmentLayout(BaseLayout):
494
513
  def build_data_spec(
495
514
  data_id: _meta.TagHeader, storage_id: _meta.TagHeader,
496
515
  context_key: tp.Optional[str], trac_schema: _meta.SchemaDefinition,
497
- storage_config: _cfg.StorageConfig,
498
- prior_spec: tp.Optional[DataSpec] = None) \
516
+ sys_config: _cfg.RuntimeConfig,
517
+ prior_spec: tp.Optional[DataSpec] = None,
518
+ metadata: tp.Optional[_api.RuntimeMetadata] = None) \
499
519
  -> DataSpec:
500
520
 
501
521
  if prior_spec is None:
502
- layout_key = storage_config.defaultLayout
522
+ layout_key = _util.read_property(sys_config.properties, _cfg_p.ConfigKeys.STORAGE_DEFAULT_LAYOUT, _cfg_p.ConfigKDefaults.STORAGE_DEFAULT_LAYOUT)
503
523
  layout = StorageLayout.select(layout_key)
504
- return layout.new_data_spec(data_id, storage_id, context_key, trac_schema, storage_config)
505
-
524
+ spec = layout.new_data_spec(data_id, storage_id, context_key, trac_schema, sys_config)
506
525
  else:
507
526
  layout_key = prior_spec.storage.layout
508
527
  layout = StorageLayout.select(layout_key)
509
- return layout.new_data_version(data_id, storage_id, context_key, trac_schema, prior_spec)
528
+ spec = layout.new_data_version(data_id, storage_id, context_key, trac_schema, prior_spec)
529
+
530
+ # Attach metadata if it is available
531
+ return spec.with_metadata(metadata) if metadata is not None else spec
510
532
 
511
533
 
512
534
  def build_file_spec(
513
535
  file_id: _meta.TagHeader, storage_id: _meta.TagHeader,
514
536
  context_key: tp.Optional[str], file_type: _meta.FileType,
515
- storage_config: _cfg.StorageConfig,
516
- prior_spec: tp.Optional[DataSpec] = None) \
537
+ sys_config: _cfg.RuntimeConfig,
538
+ prior_spec: tp.Optional[DataSpec] = None,
539
+ metadata: tp.Optional[_api.RuntimeMetadata] = None) \
517
540
  -> DataSpec:
518
541
 
519
542
  if prior_spec is None:
520
- layout_key = storage_config.defaultLayout
543
+ layout_key = _util.read_property(sys_config.properties, _cfg_p.ConfigKeys.STORAGE_DEFAULT_LAYOUT, _cfg_p.ConfigKDefaults.STORAGE_DEFAULT_LAYOUT)
521
544
  layout = StorageLayout.select(layout_key)
522
- return layout.new_file_spec(file_id, storage_id, context_key, file_type, storage_config)
545
+ spec = layout.new_file_spec(file_id, storage_id, context_key, file_type, sys_config)
523
546
 
524
547
  else:
525
548
  layout_key = prior_spec.storage.layout
526
549
  layout = StorageLayout.select(layout_key)
527
- return layout.new_file_version(file_id, storage_id, context_key, file_type, prior_spec)
550
+ spec = layout.new_file_version(file_id, storage_id, context_key, file_type, prior_spec)
551
+
552
+ # Attach metadata if it is available
553
+ return spec.with_metadata(metadata) if metadata is not None else spec
528
554
 
529
555
 
530
556
  @dc.dataclass(frozen=True)
@@ -544,6 +570,8 @@ class DataItem:
544
570
  schema: pa.Schema = None
545
571
  table: tp.Optional[pa.Table] = None
546
572
 
573
+ metadata: tp.Optional[_api.RuntimeMetadata] = None
574
+
547
575
  def is_empty(self) -> bool:
548
576
  return self.content is None
549
577
 
@@ -561,7 +589,7 @@ class DataItem:
561
589
  def for_table(table: pa.Table, schema: pa.Schema, trac_schema: _meta.SchemaDefinition) -> "DataItem":
562
590
 
563
591
  return DataItem(
564
- _meta.ObjectType.DATA, _meta.SchemaType.TABLE,
592
+ _meta.ObjectType.DATA, _meta.SchemaType.TABLE_SCHEMA,
565
593
  content=table, content_type=pa.Table,
566
594
  trac_schema=trac_schema, native_schema=schema,
567
595
  table=table, schema=schema)
@@ -570,7 +598,7 @@ class DataItem:
570
598
  def for_struct(content: tp.Any):
571
599
 
572
600
  return DataItem(
573
- _meta.ObjectType.DATA, _meta.SchemaType.STRUCT,
601
+ _meta.ObjectType.DATA, _meta.SchemaType.STRUCT_SCHEMA,
574
602
  content=content, content_type=type(content))
575
603
 
576
604
  @staticmethod
@@ -580,6 +608,9 @@ class DataItem:
580
608
  _meta.ObjectType.FILE, _meta.SchemaType.SCHEMA_TYPE_NOT_SET,
581
609
  content=content, content_type=bytes)
582
610
 
611
+ def with_metadata(self, metadata: _api.RuntimeMetadata) -> "DataItem":
612
+ return dc.replace(self, metadata=metadata)
613
+
583
614
 
584
615
  @dc.dataclass(frozen=True)
585
616
  class DataView:
@@ -592,6 +623,8 @@ class DataView:
592
623
  parts: tp.Dict[DataPartKey, tp.List[DataItem]] = None
593
624
  file_item: tp.Optional[DataItem] = None
594
625
 
626
+ metadata: tp.Optional[_api.RuntimeMetadata] = None
627
+
595
628
  @staticmethod
596
629
  def create_empty(object_type: _meta.ObjectType = _meta.ObjectType.DATA) -> "DataView":
597
630
  if object_type == _meta.ObjectType.DATA:
@@ -618,15 +651,30 @@ class DataView:
618
651
 
619
652
  def with_trac_schema(self, trac_schema: _meta.SchemaDefinition):
620
653
  arrow_schema = DataMapping.trac_to_arrow_schema(trac_schema)
621
- return DataView(_meta.ObjectType.DATA, trac_schema, arrow_schema, self.parts)
654
+ return dc.replace(self, trac_schema=trac_schema, arrow_schema=arrow_schema)
622
655
 
623
656
  def with_part(self, part_key: DataPartKey, part: DataItem):
624
- new_parts = copy.copy(self.parts)
657
+ new_parts = copy.copy(self.parts) if self.parts is not None else {}
625
658
  new_parts[part_key] = [part]
626
- return DataView(self.object_type, self.trac_schema, self.arrow_schema, new_parts)
659
+ return dc.replace(self, parts=new_parts)
627
660
 
628
661
  def with_file_item(self, file_item: DataItem):
629
- return DataView(self.object_type, file_item=file_item)
662
+ return dc.replace(self, file_item=file_item)
663
+
664
+ def with_metadata(self, metadata: _api.RuntimeMetadata) -> "DataView":
665
+ return dc.replace(self, metadata=metadata)
666
+
667
+ def get_metadata(self) -> tp.Optional[_api.RuntimeMetadata]:
668
+ if self.metadata:
669
+ return self.metadata
670
+ if self.object_type == _meta.ObjectType.FILE and self.file_item:
671
+ return self.file_item.metadata
672
+ if self.parts:
673
+ for items in self.parts.values():
674
+ for item in items:
675
+ if item and item.metadata:
676
+ return item.metadata
677
+ return None
630
678
 
631
679
  def is_empty(self) -> bool:
632
680
  if self.object_type == _meta.ObjectType.FILE:
@@ -687,15 +735,6 @@ class DataMapping:
687
735
  pa.date64(): _meta.BasicType.DATE
688
736
  }
689
737
 
690
- # For now, categorical handling is disabled by default and enabled by this setting
691
- # The default will change to "true" for the 0.9 release
692
- CATEGORICAL_CONFIG_KEY = "trac.runtime.categorical"
693
- __categorical_enabled = False
694
-
695
- @classmethod
696
- def enable_categorical(cls, enabled: bool):
697
- cls.__categorical_enabled = enabled
698
-
699
738
  @classmethod
700
739
  def arrow_to_python_type(cls, arrow_type: pa.DataType) -> type:
701
740
 
@@ -785,7 +824,7 @@ class DataMapping:
785
824
 
786
825
  # Categorical data uses an unordered dictionary with int32 index, ordered encoding not (currently) supported
787
826
  # For legacy compatability, only use dictionary encoding if the categorical feature is enabled
788
- if trac_field.categorical and cls.__categorical_enabled:
827
+ if trac_field.categorical:
789
828
  arrow_type = pa.dictionary(pa.int32(), arrow_type, False)
790
829
 
791
830
  nullable = not (trac_field.notNull or trac_field.businessKey)
@@ -926,7 +965,7 @@ T_INTERNAL_DATA = tp.TypeVar("T_INTERNAL_DATA")
926
965
  T_INTERNAL_SCHEMA = tp.TypeVar("T_INTERNAL_SCHEMA")
927
966
 
928
967
 
929
- class DataConverter(tp.Generic[T_DATA_API, T_INTERNAL_DATA, T_INTERNAL_SCHEMA]):
968
+ class DataConverter(tp.Generic[T_DATA_API, T_INTERNAL_DATA, T_INTERNAL_SCHEMA], metaclass=abc.ABCMeta):
930
969
 
931
970
  # Available per-framework args, to enable framework-specific type-checking in public APIs
932
971
  # These should (for a purist point of view) be in the individual converter classes
@@ -1702,8 +1741,11 @@ class DataConformance:
1702
1741
 
1703
1742
  # Special handling for chunked dictionaries
1704
1743
  elif isinstance(vector, pa.ChunkedArray):
1705
- chunks = [cls._coerce_dictionary(chunk, field) for chunk in vector.chunks]
1706
- return pa.chunked_array(chunks)
1744
+ if any(vector.chunks):
1745
+ chunks = [cls._coerce_dictionary(chunk, field) for chunk in vector.chunks]
1746
+ return pa.chunked_array(chunks)
1747
+ else:
1748
+ return pa.array([], type=field.type, size=0) # noqa
1707
1749
 
1708
1750
  # Vector type not recognized, coercion is not possible
1709
1751
  else:
@@ -17,6 +17,7 @@ import typing as _tp
17
17
 
18
18
  import tracdap.rt.ext.plugins as plugins
19
19
  import tracdap.rt.config as cfg
20
+ import tracdap.rt.metadata as meta
20
21
  import tracdap.rt.exceptions as ex
21
22
  import tracdap.rt._impl.core.logging as _logging
22
23
 
@@ -34,26 +35,27 @@ class RepositoryManager:
34
35
  # Initialize all repos in the system config
35
36
  # Any errors for missing repo types (plugins) will be raised during startup
36
37
 
37
- for repo_name, repo_config in sys_config.repositories.items():
38
+ for resource_key, resource in sys_config.resources.items():
39
+ if resource.resourceType == meta.ResourceType.MODEL_REPOSITORY:
38
40
 
39
- try:
41
+ try:
40
42
 
41
- # Add global properties related to the repo protocol
42
- related_props = {
43
- k: v for (k, v) in sys_config.properties.items()
44
- if k.startswith(f"{repo_config.protocol}.")}
43
+ # Add global properties related to the repo protocol
44
+ related_props = {
45
+ k: v for (k, v) in sys_config.properties.items()
46
+ if k.startswith(f"{resource.protocol}.")}
45
47
 
46
- repo_config.properties.update(related_props)
48
+ resource.properties.update(related_props)
47
49
 
48
- self._repos[repo_name] = plugins.PluginManager.load_plugin(IModelRepository, repo_config)
50
+ self._repos[resource_key] = plugins.PluginManager.load_plugin(IModelRepository, resource)
49
51
 
50
- except ex.EPluginNotAvailable as e:
52
+ except ex.EPluginNotAvailable as e:
51
53
 
52
- msg = f"Model repository type [{repo_config.protocol}] is not recognised" \
53
- + " (this could indicate a missing model repository plugin)"
54
+ msg = f"Model repository type [{resource.protocol}] is not recognised" \
55
+ + " (this could indicate a missing model repository plugin)"
54
56
 
55
- self._log.error(msg)
56
- raise ex.EStartup(msg) from e
57
+ self._log.error(msg)
58
+ raise ex.EStartup(msg) from e
57
59
 
58
60
  def get_repository(self, repo_name: str) -> IModelRepository:
59
61
 
@@ -29,6 +29,7 @@ import tracdap.rt.metadata as _meta
29
29
  import tracdap.rt.config as _cfg
30
30
  import tracdap.rt.exceptions as _ex
31
31
  import tracdap.rt.ext.plugins as plugins
32
+ import tracdap.rt._impl.core.config_parser as _cfg_p
32
33
  import tracdap.rt._impl.core.data as _data
33
34
  import tracdap.rt._impl.core.logging as _logging
34
35
  import tracdap.rt._impl.core.util as _util
@@ -83,20 +84,23 @@ class StorageManager:
83
84
  self.__external: tp.List[str] = list()
84
85
  self.__sys_config = sys_config
85
86
 
86
- for storage_key, storage_config in sys_config.storage.buckets.items():
87
- self.create_storage(storage_key, storage_config)
87
+ self.__default_location = _util.read_property(sys_config.properties, _cfg_p.ConfigKeys.STORAGE_DEFAULT_LOCATION)
88
+ self.__default_format = _util.read_property(sys_config.properties, _cfg_p.ConfigKeys.STORAGE_DEFAULT_FORMAT, "CSV")
88
89
 
89
- for storage_key, storage_config in sys_config.storage.external.items():
90
- if storage_key in self.__file_storage or storage_key in self.__data_storage:
91
- raise _ex.EConfig(f"Storage key [{storage_key}] is defined as both internal and external storage")
92
- self.__external.append(storage_key)
93
- self.create_storage(storage_key, storage_config)
90
+ for storage_key, storage_config in sys_config.resources.items():
91
+
92
+ if storage_config.resourceType == _meta.ResourceType.INTERNAL_STORAGE:
93
+ self.create_storage(storage_key, storage_config)
94
+
95
+ elif storage_config.resourceType == _meta.ResourceType.EXTERNAL_STORAGE:
96
+ self.__external.append(storage_key)
97
+ self.create_storage(storage_key, storage_config)
94
98
 
95
99
  def default_storage_key(self):
96
- return self.__sys_config.storage.defaultBucket
100
+ return self.__default_location
97
101
 
98
102
  def default_storage_format(self):
99
- return self.__sys_config.storage.defaultFormat
103
+ return self.__default_format
100
104
 
101
105
  def create_storage(self, storage_key: str, storage_config: _cfg.PluginConfig):
102
106
 
@@ -116,11 +120,12 @@ class StorageManager:
116
120
 
117
121
  provider = plugins.PluginManager.load_plugin(IStorageProvider, storage_config)
118
122
 
119
- if provider.has_file_storage():
120
- file_storage = provider.get_file_storage()
121
- elif provider.has_arrow_native():
123
+ # Prefer arrow native FS if it is available
124
+ if provider.has_arrow_native():
122
125
  fs = provider.get_arrow_native()
123
126
  file_storage = CommonFileStorage(storage_key, storage_config, fs)
127
+ elif provider.has_file_storage():
128
+ file_storage = provider.get_file_storage()
124
129
  else:
125
130
  file_storage = None
126
131