tracdap-runtime 0.8.0rc2__tar.gz → 0.9.0rc1__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 (134) hide show
  1. {tracdap_runtime-0.8.0rc2/tracdap_runtime.egg-info → tracdap_runtime-0.9.0rc1}/PKG-INFO +3 -1
  2. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/setup.cfg +3 -1
  3. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/data.py +127 -5
  4. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/repos.py +7 -0
  5. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/storage.py +10 -3
  6. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/exec/functions.py +2 -2
  7. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.py +1 -1
  8. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.py +1 -1
  9. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/config_pb2.py +1 -1
  10. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.py +1 -1
  11. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.py +1 -1
  12. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.py +1 -1
  13. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.py +1 -1
  14. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.py +1 -1
  15. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.py +1 -1
  16. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.py +1 -1
  17. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.py +1 -1
  18. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.py +1 -1
  19. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.py +1 -1
  20. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/storage_pb2.py +1 -1
  21. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.py +1 -1
  22. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.py +1 -1
  23. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.py +1 -1
  24. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/runtime.py +8 -0
  25. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/repo_git.py +56 -11
  26. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_version.py +1 -1
  27. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/config/runtime.py +2 -0
  28. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1/tracdap_runtime.egg-info}/PKG-INFO +3 -1
  29. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/tracdap_runtime.egg-info/requires.txt +2 -0
  30. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/LICENSE +0 -0
  31. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/README.md +0 -0
  32. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/pyproject.toml +0 -0
  33. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/__init__.py +0 -0
  34. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/__init__.py +0 -0
  35. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/__init__.py +0 -0
  36. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/config_parser.py +0 -0
  37. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/guard_rails.py +0 -0
  38. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/logging.py +0 -0
  39. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/models.py +0 -0
  40. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/schemas.py +0 -0
  41. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/shim.py +0 -0
  42. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/struct.py +0 -0
  43. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/type_system.py +0 -0
  44. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/util.py +0 -0
  45. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/core/validation.py +0 -0
  46. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/exec/__init__.py +0 -0
  47. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/exec/actors.py +0 -0
  48. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/exec/context.py +0 -0
  49. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/exec/dev_mode.py +0 -0
  50. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/exec/engine.py +0 -0
  51. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/exec/graph.py +0 -0
  52. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/exec/graph_builder.py +0 -0
  53. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/ext/__init__.py +0 -0
  54. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/ext/sql.py +0 -0
  55. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/ext/storage.py +0 -0
  56. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/__init__.py +0 -0
  57. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/codec.py +0 -0
  58. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/server.py +0 -0
  59. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.pyi +0 -0
  60. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2_grpc.py +0 -0
  61. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.pyi +0 -0
  62. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/config_pb2.pyi +0 -0
  63. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.pyi +0 -0
  64. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.pyi +0 -0
  65. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.pyi +0 -0
  66. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.pyi +0 -0
  67. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.pyi +0 -0
  68. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.pyi +0 -0
  69. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.pyi +0 -0
  70. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.pyi +0 -0
  71. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.pyi +0 -0
  72. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.pyi +0 -0
  73. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/storage_pb2.pyi +0 -0
  74. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.pyi +0 -0
  75. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.pyi +0 -0
  76. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.pyi +0 -0
  77. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_impl/static_api.py +0 -0
  78. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/__init__.py +0 -0
  79. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/_helpers.py +0 -0
  80. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/config_local.py +0 -0
  81. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/format_arrow.py +0 -0
  82. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/format_csv.py +0 -0
  83. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/format_parquet.py +0 -0
  84. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/repo_local.py +0 -0
  85. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/repo_pypi.py +0 -0
  86. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/storage_aws.py +0 -0
  87. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/storage_azure.py +0 -0
  88. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/storage_gcp.py +0 -0
  89. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/storage_local.py +0 -0
  90. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/storage_sql.py +0 -0
  91. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/_plugins/storage_sql_dialects.py +0 -0
  92. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/api/__init__.py +0 -0
  93. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/api/constants.py +0 -0
  94. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/api/experimental.py +0 -0
  95. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/api/hook.py +0 -0
  96. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/api/model_api.py +0 -0
  97. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/api/static_api.py +0 -0
  98. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/config/__init__.py +6 -6
  99. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/config/common.py +0 -0
  100. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/config/dynamic.py +0 -0
  101. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/config/job.py +0 -0
  102. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/config/platform.py +0 -0
  103. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/config/result.py +0 -0
  104. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/exceptions.py +0 -0
  105. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/ext/__init__.py +0 -0
  106. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/ext/config.py +0 -0
  107. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/ext/embed.py +0 -0
  108. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/ext/plugins.py +0 -0
  109. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/ext/repos.py +0 -0
  110. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/ext/storage.py +0 -0
  111. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/launch/__init__.py +0 -0
  112. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/launch/__main__.py +0 -0
  113. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/launch/cli.py +0 -0
  114. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/launch/launch.py +0 -0
  115. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/__init__.py +36 -36
  116. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/common.py +0 -0
  117. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/config.py +0 -0
  118. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/custom.py +0 -0
  119. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/data.py +0 -0
  120. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/file.py +0 -0
  121. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/flow.py +0 -0
  122. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/job.py +0 -0
  123. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/model.py +0 -0
  124. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/object.py +0 -0
  125. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/object_id.py +0 -0
  126. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/resource.py +0 -0
  127. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/search.py +0 -0
  128. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/storage.py +0 -0
  129. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/tag.py +0 -0
  130. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/tag_update.py +0 -0
  131. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/src/tracdap/rt/metadata/type.py +0 -0
  132. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/tracdap_runtime.egg-info/SOURCES.txt +0 -0
  133. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/tracdap_runtime.egg-info/dependency_links.txt +0 -0
  134. {tracdap_runtime-0.8.0rc2 → tracdap_runtime-0.9.0rc1}/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.8.0rc2
3
+ Version: 0.9.0rc1
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
@@ -21,6 +21,8 @@ Requires-Dist: pyarrow==18.1.0
21
21
  Requires-Dist: pyyaml==6.0.2
22
22
  Requires-Dist: dulwich==0.22.7
23
23
  Requires-Dist: requests==2.32.3
24
+ Requires-Dist: typing_extensions<4.13
25
+ Requires-Dist: urllib3<2.4.0
24
26
  Provides-Extra: grpc
25
27
  Requires-Dist: grpcio==1.70.0; extra == "grpc"
26
28
  Requires-Dist: grpcio-status==1.70.0; extra == "grpc"
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = tracdap-runtime
3
- version = 0.8.0rc2
3
+ version = 0.9.0rc1
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
@@ -45,6 +45,8 @@ install_requires =
45
45
  pyyaml == 6.0.2
46
46
  dulwich == 0.22.7
47
47
  requests == 2.32.3
48
+ typing_extensions < 4.13
49
+ urllib3 < 2.4.0
48
50
 
49
51
  [options.extras_require]
50
52
  grpc =
@@ -184,6 +184,11 @@ class DataView:
184
184
  else:
185
185
  return DataView(_meta.ObjectType.DATA, trac_schema, parts = dict())
186
186
 
187
+ @staticmethod
188
+ def for_arrow_schema(arrow_schema: pa.Schema):
189
+ trac_schema = DataMapping.arrow_to_trac_schema(arrow_schema)
190
+ return DataView(_meta.ObjectType.DATA, trac_schema, arrow_schema, dict())
191
+
187
192
  @staticmethod
188
193
  def for_file_item(file_item: DataItem):
189
194
  return DataView(file_item.object_type, file_item=file_item)
@@ -259,8 +264,17 @@ class DataMapping:
259
264
  pa.date64(): _meta.BasicType.DATE
260
265
  }
261
266
 
262
- @staticmethod
263
- def arrow_to_python_type(arrow_type: pa.DataType) -> type:
267
+ # For now, categorical handling is disabled by default and enabled by this setting
268
+ # The default will change to "true" for the 0.9 release
269
+ CATEGORICAL_CONFIG_KEY = "trac.runtime.categorical"
270
+ __categorical_enabled = False
271
+
272
+ @classmethod
273
+ def enable_categorical(cls, enabled: bool):
274
+ cls.__categorical_enabled = enabled
275
+
276
+ @classmethod
277
+ def arrow_to_python_type(cls, arrow_type: pa.DataType) -> type:
264
278
 
265
279
  if pa.types.is_boolean(arrow_type):
266
280
  return bool
@@ -283,6 +297,11 @@ class DataMapping:
283
297
  if pa.types.is_timestamp(arrow_type):
284
298
  return dt.datetime
285
299
 
300
+ # The python type for a dictionary-encoded field is its value type
301
+ if pa.types.is_dictionary(arrow_type):
302
+ if isinstance(arrow_type, pa.DictionaryType):
303
+ return cls.arrow_to_python_type(arrow_type.value_type)
304
+
286
305
  raise _ex.ETracInternal(f"No Python type mapping available for Arrow type [{arrow_type}]")
287
306
 
288
307
  @classmethod
@@ -340,7 +359,13 @@ class DataMapping:
340
359
  def trac_to_arrow_field(cls, trac_field: _meta.FieldSchema):
341
360
 
342
361
  arrow_type = cls.trac_to_arrow_basic_type(trac_field.fieldType)
343
- nullable = not trac_field.notNull if trac_field.notNull is not None else not trac_field.businessKey
362
+
363
+ # Categorical data uses an unordered dictionary with int32 index, ordered encoding not (currently) supported
364
+ # For legacy compatability, only use dictionary encoding if the categorical feature is enabled
365
+ if trac_field.categorical and cls.__categorical_enabled:
366
+ arrow_type = pa.dictionary(pa.int32(), arrow_type, False)
367
+
368
+ nullable = not (trac_field.notNull or trac_field.businessKey)
344
369
 
345
370
  return pa.field(trac_field.fieldName, arrow_type, nullable)
346
371
 
@@ -369,12 +394,15 @@ class DataMapping:
369
394
  field_type = cls.arrow_to_trac_type(field.type)
370
395
  label = field.metadata["label"] if field.metadata and "label" in field.metadata else field.name
371
396
 
397
+ # When converting Arrow -> TRAC, always set the categorical flag for dictionary encoded fields
398
+ # This affects dynamic imports and is informational only (physical layout is controlled by Arrow schemas)
399
+
372
400
  return _meta.FieldSchema(
373
401
  field.name, field_index, field_type,
374
402
  label=label,
375
403
  businessKey=False,
376
404
  notNull=not field.nullable,
377
- categorical=False)
405
+ categorical=pa.types.is_dictionary(field.type))
378
406
 
379
407
  @classmethod
380
408
  def arrow_to_trac_type(cls, arrow_type: pa.DataType) -> _meta.BasicType:
@@ -390,6 +418,11 @@ class DataMapping:
390
418
  if pa.types.is_timestamp(arrow_type):
391
419
  return _meta.BasicType.DATETIME
392
420
 
421
+ # The basic type for a dictionary-encoded field is its value type
422
+ if pa.types.is_dictionary(arrow_type):
423
+ if isinstance(arrow_type, pa.DictionaryType):
424
+ return cls.arrow_to_trac_type(arrow_type.value_type)
425
+
393
426
  raise _ex.ETracInternal(f"No data type mapping available for Arrow type [{arrow_type}]")
394
427
 
395
428
  @classmethod
@@ -766,6 +799,10 @@ class DataConformance:
766
799
  "Field [{field_name}] cannot be converted from {vector_type} to {field_type}, " + \
767
800
  "source and target have different time zones"
768
801
 
802
+ __E_WRONG_CATEGORICAL_TYPE = \
803
+ "Field [{field_name}] categorical types do not match" + \
804
+ "(expected {field_type}, got {vector_type})"
805
+
769
806
  @classmethod
770
807
  def column_filter(cls, columns: tp.List[str], schema: tp.Optional[pa.Schema]) -> tp.Optional[tp.List[str]]:
771
808
 
@@ -918,13 +955,19 @@ class DataConformance:
918
955
  @classmethod
919
956
  def _coerce_vector(cls, vector: pa.Array, field: pa.Field, pandas_type=None) -> pa.Array:
920
957
 
958
+ # Handle null vector
921
959
  if pa.types.is_null(vector.type):
922
-
923
960
  if field.nullable:
924
961
  return pa.nulls(size=len(vector), type=field.type)
925
962
  else:
926
963
  raise _ex.EDataConformance(f"All null values in non-null field [{field.name}]")
927
964
 
965
+ # If the vector is dict-encoded but the expected result is not, decode the dictionary
966
+ if pa.types.is_dictionary(vector.type) and not pa.types.is_dictionary(field.type):
967
+ if isinstance(vector, pa.DictionaryArray):
968
+ dict_vector: pa.DictionaryArray = vector
969
+ vector = dict_vector.dictionary_decode()
970
+
928
971
  if pa.types.is_boolean(field.type):
929
972
  return cls._coerce_boolean(vector, field)
930
973
 
@@ -946,6 +989,9 @@ class DataConformance:
946
989
  if pa.types.is_timestamp(field.type):
947
990
  return cls._coerce_timestamp(vector, field)
948
991
 
992
+ if pa.types.is_dictionary(field.type):
993
+ return cls._coerce_dictionary(vector, field)
994
+
949
995
  error_message = cls._format_error(cls.__E_WRONG_DATA_TYPE, vector, field)
950
996
  cls.__log.error(error_message)
951
997
  raise _ex.EDataConformance(error_message)
@@ -1188,6 +1234,82 @@ class DataConformance:
1188
1234
 
1189
1235
  return pc.cast(scaled_vector, field.type)
1190
1236
 
1237
+ @classmethod
1238
+ def _coerce_dictionary(cls, vector: pa.Array, field: pa.Field):
1239
+
1240
+ try:
1241
+
1242
+ if not isinstance(field.type, pa.DictionaryType):
1243
+ raise _ex.EUnexpected()
1244
+
1245
+ field_type: pa.DictionaryType = field.type
1246
+
1247
+ # Supplied vector is a dictionary (but the dictionary type is not an exact match)
1248
+ if pa.types.is_dictionary(vector.type):
1249
+
1250
+ if not isinstance(vector.type, pa.DictionaryType):
1251
+ raise _ex.EUnexpected()
1252
+
1253
+ vector_type: pa.DictionaryType = vector.type
1254
+
1255
+ # Do not allow coercion to a smaller index type or from unordered to ordered
1256
+ if (vector_type.index_type.bit_width > field_type.index_type.bit_width) or \
1257
+ (field_type.ordered and not vector_type.ordered):
1258
+
1259
+ error_message = cls._format_error(cls.__E_WRONG_DATA_TYPE, vector, field)
1260
+ cls.__log.error(error_message)
1261
+ raise _ex.EDataConformance(error_message)
1262
+
1263
+ # Value types are the same - basic cast should succeed
1264
+ if vector_type.value_type == field_type.value_type:
1265
+ return pc.cast(vector, field.type)
1266
+
1267
+ # Value types differ - try to coerce the underlying dictionary
1268
+ elif isinstance(vector, pa.DictionaryArray):
1269
+ try:
1270
+ values_field = pa.field(field.name, field_type.value_type, field.nullable)
1271
+ values_vector = cls._coerce_vector(vector.dictionary, values_field)
1272
+ dict_vector = pa.DictionaryArray.from_arrays(vector.indices, values_vector, ordered=field_type.ordered) # noqa
1273
+ return pc.cast(dict_vector, field.type)
1274
+ # Handle errors converting the value type
1275
+ except _ex.EDataConformance as e:
1276
+ error_message = cls._format_error(cls.__E_WRONG_CATEGORICAL_TYPE, vector, field)
1277
+ cls.__log.error(error_message)
1278
+ raise _ex.EDataConformance(error_message) from e
1279
+
1280
+ # Special handling for chunked dictionaries
1281
+ elif isinstance(vector, pa.ChunkedArray):
1282
+ chunks = [cls._coerce_dictionary(chunk, field) for chunk in vector.chunks]
1283
+ return pa.chunked_array(chunks)
1284
+
1285
+ # Vector type not recognized, coercion is not possible
1286
+ else:
1287
+ error_message = cls._format_error(cls.__E_WRONG_DATA_TYPE, vector, field)
1288
+ cls.__log.error(error_message)
1289
+ raise _ex.EDataConformance(error_message)
1290
+
1291
+ # Supplied vector matches the dictionary value type - perform dictionary encoding
1292
+ elif vector.type == field_type.value_type and not field_type.ordered:
1293
+ return vector.dictionary_encode().cast(field.type)
1294
+
1295
+ # Fallback option - try to coerce the value type first, then perform dictionary encoding
1296
+ else:
1297
+ try:
1298
+ values_field = pa.field(field.name, field_type.value_type, field.nullable)
1299
+ values_vector = cls._coerce_vector(vector, values_field)
1300
+ return values_vector.dictionary_encode().cast(field.type)
1301
+ # Handle errors converting the value type
1302
+ except _ex.EDataConformance as e:
1303
+ error_message = cls._format_error(cls.__E_WRONG_CATEGORICAL_TYPE, vector, field)
1304
+ cls.__log.error(error_message)
1305
+ raise _ex.EDataConformance(error_message) from e
1306
+
1307
+ except pa.ArrowInvalid as e:
1308
+
1309
+ error_message = cls._format_error(cls.__E_DATA_LOSS_DID_OCCUR, vector, field, e)
1310
+ cls.__log.error(error_message)
1311
+ raise _ex.EDataConformance(error_message) from e
1312
+
1191
1313
  @classmethod
1192
1314
  def _format_error(cls, error_template: str, vector: pa.Array, field: pa.Field, e: Exception = None):
1193
1315
 
@@ -38,6 +38,13 @@ class RepositoryManager:
38
38
 
39
39
  try:
40
40
 
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}.")}
45
+
46
+ repo_config.properties.update(related_props)
47
+
41
48
  self._repos[repo_name] = plugins.PluginManager.load_plugin(IModelRepository, repo_config)
42
49
 
43
50
  except ex.EPluginNotAvailable as e:
@@ -81,7 +81,7 @@ class StorageManager:
81
81
  self.__file_storage: tp.Dict[str, IFileStorage] = dict()
82
82
  self.__data_storage: tp.Dict[str, IDataStorage] = dict()
83
83
  self.__external: tp.List[str] = list()
84
- self.__settings = sys_config.storage
84
+ self.__sys_config = sys_config
85
85
 
86
86
  for storage_key, storage_config in sys_config.storage.buckets.items():
87
87
  self.create_storage(storage_key, storage_config)
@@ -93,13 +93,20 @@ class StorageManager:
93
93
  self.create_storage(storage_key, storage_config)
94
94
 
95
95
  def default_storage_key(self):
96
- return self.__settings.defaultBucket
96
+ return self.__sys_config.storage.defaultBucket
97
97
 
98
98
  def default_storage_format(self):
99
- return self.__settings.defaultFormat
99
+ return self.__sys_config.storage.defaultFormat
100
100
 
101
101
  def create_storage(self, storage_key: str, storage_config: _cfg.PluginConfig):
102
102
 
103
+ # Add global properties related to the storage protocol
104
+ related_props = {
105
+ k: v for (k, v) in self.__sys_config.properties.items()
106
+ if k.startswith(f"{storage_config.protocol}.")}
107
+
108
+ storage_config.properties.update(related_props)
109
+
103
110
  if plugins.PluginManager.is_plugin_available(IStorageProvider, storage_config.protocol):
104
111
  self._create_storage_from_provider(storage_key, storage_config)
105
112
  else:
@@ -294,11 +294,11 @@ class DataViewFunc(NodeFunction[_data.DataView]):
294
294
  # Everything else is a regular data view
295
295
  if self.node.schema is not None and len(self.node.schema.table.fields) > 0:
296
296
  trac_schema = self.node.schema
297
+ data_view = _data.DataView.for_trac_schema(trac_schema)
297
298
  else:
298
299
  arrow_schema = root_item.schema
299
- trac_schema = _data.DataMapping.arrow_to_trac_schema(arrow_schema)
300
+ data_view = _data.DataView.for_arrow_schema(arrow_schema)
300
301
 
301
- data_view = _data.DataView.for_trac_schema(trac_schema)
302
302
  data_view = _data.DataMapping.add_item_to_view(data_view, root_part_key, root_item)
303
303
 
304
304
  return data_view
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/api/internal/runtime.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/common.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/config.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/custom.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/data.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/file.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/flow.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/job.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/model.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/object_id.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/object.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/resource.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/search.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/storage.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/tag.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/tag_update.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: tracdap/rt/_impl/grpc/tracdap/metadata/type.proto
4
- # Protobuf Python Version: 4.25.3
4
+ # Protobuf Python Version: 4.25.5
5
5
  """Generated protocol buffer code."""
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
@@ -30,6 +30,7 @@ import tracdap.rt.config as _cfg
30
30
  import tracdap.rt.exceptions as _ex
31
31
  import tracdap.rt.ext.plugins as _plugins
32
32
  import tracdap.rt._impl.core.config_parser as _cparse
33
+ import tracdap.rt._impl.core.data as _data
33
34
  import tracdap.rt._impl.core.guard_rails as _guard
34
35
  import tracdap.rt._impl.core.logging as _logging
35
36
  import tracdap.rt._impl.core.models as _models
@@ -167,6 +168,13 @@ class TracRuntime:
167
168
  else:
168
169
  self._log.info("Using embedded system config")
169
170
 
171
+ # Check whether to enable categorical processing in the data layer
172
+
173
+ if _data.DataMapping.CATEGORICAL_CONFIG_KEY in self._sys_config.properties:
174
+ categorical_prop = self._sys_config.properties[_data.DataMapping.CATEGORICAL_CONFIG_KEY]
175
+ categorical_flag = categorical_prop and categorical_prop.lower() == "true"
176
+ _data.DataMapping.enable_categorical(categorical_flag)
177
+
170
178
  # Dev mode translation is controlled by the dev mode flag
171
179
  # I.e. it can be applied to embedded configs
172
180
 
@@ -23,6 +23,7 @@ import time
23
23
  import dulwich.repo as git_repo
24
24
  import dulwich.client as git_client
25
25
  import dulwich.index as git_index
26
+ import urllib3.exceptions # noqa
26
27
 
27
28
  import tracdap.rt.metadata as meta
28
29
  import tracdap.rt.exceptions as ex
@@ -75,20 +76,45 @@ class GitRepository(IModelRepository):
75
76
 
76
77
  def do_checkout(self, model_def: meta.ModelDefinition, checkout_dir: pathlib.Path) -> pathlib.Path:
77
78
 
78
- self._log.info(
79
- f"Git checkout: repo = [{model_def.repository}], " +
80
- f"group = [{model_def.packageGroup}], package = [{model_def.package}], version = [{model_def.version}]")
79
+ try:
81
80
 
82
- self._log.info(f"Checkout location: [{checkout_dir}]")
81
+ self._log.info(
82
+ f"Git checkout: repo = [{model_def.repository}], " +
83
+ f"group = [{model_def.packageGroup}], package = [{model_def.package}], version = [{model_def.version}]")
83
84
 
84
- if self._native_git:
85
- package_path = self._do_native_checkout(model_def, checkout_dir)
86
- else:
87
- package_path = self._do_python_checkout(model_def, checkout_dir)
85
+ self._log.info(f"Checkout location: [{checkout_dir}]")
86
+
87
+ if self._native_git:
88
+ package_path = self._do_native_checkout(model_def, checkout_dir)
89
+ else:
90
+ package_path = self._do_python_checkout(model_def, checkout_dir)
91
+
92
+ self._log.info(f"Git checkout succeeded for {model_def.package} {model_def.version}")
93
+
94
+ return package_path
95
+
96
+ except Exception as e:
97
+
98
+ error = e
99
+
100
+ # For retry failures, try to find the original cause
101
+ while e.__cause__ is not None:
102
+ if isinstance(e, urllib3.exceptions.MaxRetryError):
103
+ error = e.__cause__
104
+ break
105
+ else:
106
+ e = e.__cause__
107
+
108
+ # Try to sanitize error messages from urllib3
109
+ if isinstance(error, urllib3.exceptions.HTTPError):
110
+ detail = self._clean_urllib3_error(error)
111
+ else:
112
+ detail = str(error)
88
113
 
89
- self._log.info(f"Git checkout succeeded for {model_def.package} {model_def.version}")
114
+ message = f"Failed to check out [{model_def.repository}]: {detail}"
90
115
 
91
- return package_path
116
+ self._log.error(message)
117
+ raise ex.EModelRepo(message) from error
92
118
 
93
119
  def _do_native_checkout(self, model_def: meta.ModelDefinition, checkout_dir: pathlib.Path) -> pathlib.Path:
94
120
 
@@ -150,10 +176,15 @@ class GitRepository(IModelRepository):
150
176
  for line in cmd_err:
151
177
  self._log.info(line)
152
178
 
153
- else:
179
+ elif cmd_err:
180
+
154
181
  for line in cmd_err:
155
182
  self._log.error(line)
156
183
 
184
+ raise ex.EModelRepo(cmd_err[-1])
185
+
186
+ else:
187
+
157
188
  error_msg = f"Git checkout failed for {model_def.package} {model_def.version}"
158
189
  self._log.error(error_msg)
159
190
  raise ex.EModelRepo(error_msg)
@@ -265,6 +296,20 @@ class GitRepository(IModelRepository):
265
296
  def _ref_key(key):
266
297
  return bytes(key, "ascii")
267
298
 
299
+ @classmethod
300
+ def _clean_urllib3_error(cls, error: urllib3.exceptions.HTTPError):
301
+
302
+ match = cls._URLLIB3_ERROR_PATTERN.match(str(error))
303
+
304
+ # Best efforts to clean up the message, fall back on str(error)
305
+ if match:
306
+ return match.group(1)
307
+ else:
308
+ return str(error)
309
+
310
+ # Error message format is like this:
311
+ # <pkg.ClassName object at 0xXXXXXXX>: Message
312
+ _URLLIB3_ERROR_PATTERN = re.compile(r"<[^>]*>: (.*)")
268
313
 
269
314
  # Register plugin
270
315
  plugins.PluginManager.register_plugin(IModelRepository, GitRepository, ["git"])
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- __version__ = "0.8.0rc2"
16
+ __version__ = "0.9.0rc1"
@@ -21,6 +21,8 @@ class RuntimeConfig:
21
21
 
22
22
  runtimeApi: "ServiceConfig" = _dc.field(default_factory=lambda: ServiceConfig())
23
23
 
24
+ properties: "_tp.Dict[str, str]" = _dc.field(default_factory=dict)
25
+
24
26
 
25
27
  @_dc.dataclass
26
28
  class SparkSettings:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tracdap-runtime
3
- Version: 0.8.0rc2
3
+ Version: 0.9.0rc1
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
@@ -21,6 +21,8 @@ Requires-Dist: pyarrow==18.1.0
21
21
  Requires-Dist: pyyaml==6.0.2
22
22
  Requires-Dist: dulwich==0.22.7
23
23
  Requires-Dist: requests==2.32.3
24
+ Requires-Dist: typing_extensions<4.13
25
+ Requires-Dist: urllib3<2.4.0
24
26
  Provides-Extra: grpc
25
27
  Requires-Dist: grpcio==1.70.0; extra == "grpc"
26
28
  Requires-Dist: grpcio-status==1.70.0; extra == "grpc"
@@ -3,6 +3,8 @@ pyarrow==18.1.0
3
3
  pyyaml==6.0.2
4
4
  dulwich==0.22.7
5
5
  requests==2.32.3
6
+ typing_extensions<4.13
7
+ urllib3<2.4.0
6
8
 
7
9
  [aws]
8
10
  botocore==1.34.93
@@ -1,6 +1,7 @@
1
1
  # Code generated by TRAC
2
2
 
3
- from .job import JobConfig
3
+ from .result import TagUpdateList
4
+ from .result import JobResult
4
5
 
5
6
  from .common import _ConfigFile
6
7
  from .common import PluginConfig
@@ -8,11 +9,6 @@ from .common import PlatformInfo
8
9
  from .common import StorageConfig
9
10
  from .common import ServiceConfig
10
11
 
11
- from .dynamic import DynamicConfig
12
-
13
- from .result import TagUpdateList
14
- from .result import JobResult
15
-
16
12
  from .platform import RoutingProtocol
17
13
  from .platform import DeploymentLayout
18
14
  from .platform import PlatformConfig
@@ -28,3 +24,7 @@ from .platform import ClientConfig
28
24
 
29
25
  from .runtime import RuntimeConfig
30
26
  from .runtime import SparkSettings
27
+
28
+ from .job import JobConfig
29
+
30
+ from .dynamic import DynamicConfig
@@ -9,40 +9,16 @@ from .type import Value
9
9
  from .type import ArrayValue
10
10
  from .type import MapValue
11
11
 
12
- from .tag_update import TagOperation
13
- from .tag_update import TagUpdate
14
-
15
12
  from .object_id import ObjectType
16
13
  from .object_id import TagHeader
17
14
  from .object_id import TagSelector
18
15
 
19
- from .job import JobType
20
- from .job import JobStatusCode
21
- from .job import JobGroupType
22
- from .job import JobDefinition
23
- from .job import ResultDefinition
24
- from .job import RunModelJob
25
- from .job import RunFlowJob
26
- from .job import ImportModelJob
27
- from .job import ImportDataJob
28
- from .job import ExportDataJob
29
- from .job import JobGroup
30
- from .job import SequentialJobGroup
31
- from .job import ParallelJobGroup
32
-
33
- from .common import MetadataFormat
34
- from .common import MetadataVersion
35
- from .common import TenantInfo
36
-
37
- from .resource import ResourceType
38
- from .resource import ResourceDefinition
39
-
40
- from .config import ConfigType
41
- from .config import ConfigEntry
42
- from .config import ConfigDetails
43
- from .config import ConfigDefinition
44
-
45
- from .custom import CustomDefinition
16
+ from .search import SearchOperator
17
+ from .search import LogicalOperator
18
+ from .search import SearchTerm
19
+ from .search import LogicalExpression
20
+ from .search import SearchExpression
21
+ from .search import SearchParameters
46
22
 
47
23
  from .data import SchemaType
48
24
  from .data import PartType
@@ -63,12 +39,8 @@ from .model import ModelInputSchema
63
39
  from .model import ModelOutputSchema
64
40
  from .model import ModelDefinition
65
41
 
66
- from .search import SearchOperator
67
- from .search import LogicalOperator
68
- from .search import SearchTerm
69
- from .search import LogicalExpression
70
- from .search import SearchExpression
71
- from .search import SearchParameters
42
+ from .tag_update import TagOperation
43
+ from .tag_update import TagUpdate
72
44
 
73
45
  from .flow import FlowNodeType
74
46
  from .flow import FlowNode
@@ -76,6 +48,34 @@ from .flow import FlowSocket
76
48
  from .flow import FlowEdge
77
49
  from .flow import FlowDefinition
78
50
 
51
+ from .custom import CustomDefinition
52
+
53
+ from .resource import ResourceType
54
+ from .resource import ResourceDefinition
55
+
56
+ from .job import JobType
57
+ from .job import JobStatusCode
58
+ from .job import JobGroupType
59
+ from .job import JobDefinition
60
+ from .job import ResultDefinition
61
+ from .job import RunModelJob
62
+ from .job import RunFlowJob
63
+ from .job import ImportModelJob
64
+ from .job import ImportDataJob
65
+ from .job import ExportDataJob
66
+ from .job import JobGroup
67
+ from .job import SequentialJobGroup
68
+ from .job import ParallelJobGroup
69
+
70
+ from .common import MetadataFormat
71
+ from .common import MetadataVersion
72
+ from .common import TenantInfo
73
+
74
+ from .config import ConfigType
75
+ from .config import ConfigEntry
76
+ from .config import ConfigDetails
77
+ from .config import ConfigDefinition
78
+
79
79
  from .storage import CopyStatus
80
80
  from .storage import IncarnationStatus
81
81
  from .storage import StorageCopy