tracdap-runtime 0.7.0__tar.gz → 0.7.1__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 (126) hide show
  1. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/PKG-INFO +2 -2
  2. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/setup.cfg +1 -1
  3. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/dev_mode.py +14 -9
  4. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/config_parser.py +26 -18
  5. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/static_api.py +1 -1
  6. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/type_system.py +73 -33
  7. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/storage_sql.py +12 -5
  8. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_version.py +1 -1
  9. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/tracdap_runtime.egg-info/PKG-INFO +2 -2
  10. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/LICENSE +0 -0
  11. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/README.md +0 -0
  12. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/pyproject.toml +0 -0
  13. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/__init__.py +0 -0
  14. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/__init__.py +0 -0
  15. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/actors.py +0 -0
  16. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/context.py +0 -0
  17. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/engine.py +0 -0
  18. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/functions.py +0 -0
  19. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/graph.py +0 -0
  20. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/graph_builder.py +0 -0
  21. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/runtime.py +0 -0
  22. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_exec/server.py +0 -0
  23. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/__init__.py +0 -0
  24. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/data.py +0 -0
  25. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/ext/__init__.py +0 -0
  26. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/ext/sql.py +0 -0
  27. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/ext/storage.py +0 -0
  28. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/__init__.py +0 -0
  29. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/codec.py +0 -0
  30. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.py +0 -0
  31. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2.pyi +0 -0
  32. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/api/internal/runtime_pb2_grpc.py +0 -0
  33. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.py +0 -0
  34. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/common_pb2.pyi +0 -0
  35. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.py +0 -0
  36. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/custom_pb2.pyi +0 -0
  37. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.py +0 -0
  38. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/data_pb2.pyi +0 -0
  39. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.py +0 -0
  40. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/file_pb2.pyi +0 -0
  41. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.py +0 -0
  42. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/flow_pb2.pyi +0 -0
  43. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.py +0 -0
  44. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.pyi +0 -0
  45. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.py +0 -0
  46. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/model_pb2.pyi +0 -0
  47. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.py +0 -0
  48. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.pyi +0 -0
  49. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.py +0 -0
  50. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.pyi +0 -0
  51. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.py +0 -0
  52. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/resource_pb2.pyi +0 -0
  53. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.py +0 -0
  54. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/search_pb2.pyi +0 -0
  55. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/stoarge_pb2.py +0 -0
  56. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/stoarge_pb2.pyi +0 -0
  57. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.py +0 -0
  58. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_pb2.pyi +0 -0
  59. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.py +0 -0
  60. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/tag_update_pb2.pyi +0 -0
  61. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.py +0 -0
  62. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/grpc/tracdap/metadata/type_pb2.pyi +0 -0
  63. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/guard_rails.py +0 -0
  64. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/models.py +0 -0
  65. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/repos.py +0 -0
  66. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/schemas.py +0 -0
  67. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/shim.py +0 -0
  68. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/storage.py +0 -0
  69. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/util.py +0 -0
  70. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_impl/validation.py +0 -0
  71. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/__init__.py +0 -0
  72. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/_helpers.py +0 -0
  73. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/config_local.py +0 -0
  74. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/format_arrow.py +0 -0
  75. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/format_csv.py +0 -0
  76. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/format_parquet.py +0 -0
  77. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/repo_git.py +0 -0
  78. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/repo_local.py +0 -0
  79. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/repo_pypi.py +0 -0
  80. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/storage_aws.py +0 -0
  81. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/storage_azure.py +0 -0
  82. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/storage_gcp.py +0 -0
  83. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/storage_local.py +0 -0
  84. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/_plugins/storage_sql_dialects.py +0 -0
  85. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/api/__init__.py +0 -0
  86. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/api/experimental.py +0 -0
  87. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/api/hook.py +0 -0
  88. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/api/model_api.py +0 -0
  89. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/api/static_api.py +0 -0
  90. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/config/__init__.py +0 -0
  91. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/config/common.py +0 -0
  92. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/config/job.py +0 -0
  93. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/config/platform.py +0 -0
  94. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/config/result.py +0 -0
  95. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/config/runtime.py +0 -0
  96. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/exceptions.py +0 -0
  97. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/ext/__init__.py +0 -0
  98. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/ext/config.py +0 -0
  99. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/ext/embed.py +0 -0
  100. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/ext/plugins.py +0 -0
  101. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/ext/repos.py +0 -0
  102. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/ext/storage.py +0 -0
  103. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/launch/__init__.py +0 -0
  104. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/launch/__main__.py +0 -0
  105. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/launch/cli.py +0 -0
  106. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/launch/launch.py +0 -0
  107. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/__init__.py +15 -15
  108. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/common.py +0 -0
  109. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/custom.py +0 -0
  110. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/data.py +0 -0
  111. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/file.py +0 -0
  112. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/flow.py +0 -0
  113. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/job.py +0 -0
  114. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/model.py +0 -0
  115. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/object.py +0 -0
  116. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/object_id.py +0 -0
  117. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/resource.py +0 -0
  118. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/search.py +0 -0
  119. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/stoarge.py +0 -0
  120. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/tag.py +0 -0
  121. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/tag_update.py +0 -0
  122. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/src/tracdap/rt/metadata/type.py +0 -0
  123. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/tracdap_runtime.egg-info/SOURCES.txt +0 -0
  124. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/tracdap_runtime.egg-info/dependency_links.txt +0 -0
  125. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/tracdap_runtime.egg-info/requires.txt +0 -0
  126. {tracdap_runtime-0.7.0 → tracdap_runtime-0.7.1}/tracdap_runtime.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: tracdap-runtime
3
- Version: 0.7.0
3
+ Version: 0.7.1
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
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = tracdap-runtime
3
- version = 0.7.0
3
+ version = 0.7.1
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
@@ -37,12 +37,12 @@ DEV_MODE_JOB_CONFIG = [
37
37
  re.compile(r"job\.\w+\.model"),
38
38
  re.compile(r"job\.\w+\.flow"),
39
39
 
40
- re.compile(r".*\.jobs\.\d+\.\w+\.parameters\.\w+"),
41
- re.compile(r".*\.jobs\.\d+\.\w+\.inputs\.\w+"),
42
- re.compile(r".*\.jobs\.\d+\.\w+\.outputs\.\w+"),
43
- re.compile(r".*\.jobs\.\d+\.\w+\.models\.\w+"),
44
- re.compile(r".*\.jobs\.\d+\.\w+\.model"),
45
- re.compile(r".*\.jobs\.\d+\.\w+\.flow")
40
+ re.compile(r".*\.jobs\[\d+]\.\w+\.parameters\.\w+"),
41
+ re.compile(r".*\.jobs\[\d+]\.\w+\.inputs\.\w+"),
42
+ re.compile(r".*\.jobs\[\d+]\.\w+\.outputs\.\w+"),
43
+ re.compile(r".*\.jobs\[\d+]\.\w+\.models\.\w+"),
44
+ re.compile(r".*\.jobs\[\d+]\.\w+\.model"),
45
+ re.compile(r".*\.jobs\[\d+]\.\w+\.flow")
46
46
  ]
47
47
 
48
48
  DEV_MODE_SYS_CONFIG = []
@@ -764,10 +764,15 @@ class DevModeTranslator:
764
764
  else:
765
765
  p_spec = param_specs[p_name]
766
766
 
767
- cls._log.info(f"Encoding parameter [{p_name}] as {p_spec.paramType.basicType}")
767
+ try:
768
+ cls._log.info(f"Encoding parameter [{p_name}] as {p_spec.paramType.basicType}")
769
+ encoded_value = _types.MetadataCodec.convert_value(p_value, p_spec.paramType)
770
+ encoded_values[p_name] = encoded_value
768
771
 
769
- encoded_value = _types.MetadataCodec.convert_value(p_value, p_spec.paramType)
770
- encoded_values[p_name] = encoded_value
772
+ except Exception as e:
773
+ msg = f"Failed to encode parameter [{p_name}]: {str(e)}"
774
+ cls._log.error(msg)
775
+ raise _ex.EConfigParse(msg) from e
771
776
 
772
777
  return encoded_values
773
778
 
@@ -321,6 +321,23 @@ class ConfigParser(tp.Generic[_T]):
321
321
 
322
322
  def _parse_value(self, location: str, raw_value: tp.Any, annotation: type):
323
323
 
324
+ if self._is_dev_mode_location(location):
325
+
326
+ if type(raw_value) in ConfigParser.__primitive_types:
327
+ return self._parse_primitive(location, raw_value, type(raw_value))
328
+
329
+ if isinstance(raw_value, list):
330
+ if len(raw_value) == 0:
331
+ return []
332
+ items = iter((self._child_location(location, i), x) for i, x in enumerate(raw_value))
333
+ return list(self._parse_value(loc, x, tp.Any) for loc, x in items)
334
+
335
+ if isinstance(raw_value, dict):
336
+ if len(raw_value) == 0:
337
+ return {}
338
+ items = iter((self._child_location(location, k), k, v) for k, v in raw_value.items())
339
+ return dict((k, self._parse_value(loc, v, tp.Any)) for loc, k, v in items)
340
+
324
341
  if raw_value is None:
325
342
  return None
326
343
 
@@ -339,24 +356,13 @@ class ConfigParser(tp.Generic[_T]):
339
356
  return self._parse_enum(location, raw_value, annotation)
340
357
 
341
358
  if _dc.is_dataclass(annotation):
342
-
343
- if isinstance(raw_value, tp.Dict):
344
- return self._parse_simple_class(location, raw_value, annotation)
345
-
346
- if self._is_dev_mode_location(location):
347
- if type(raw_value) in ConfigParser.__primitive_types:
348
- return self._parse_primitive(location, raw_value, type(raw_value))
349
- if isinstance(raw_value, list):
350
- if len(raw_value) == 0:
351
- return []
352
- list_type = type(raw_value[0])
353
- return list(map(lambda x: self._parse_primitive(location, x, list_type), raw_value))
354
-
355
- return self._error(location, f"Expected type {annotation.__name__}, got '{str(raw_value)}'")
359
+ return self._parse_simple_class(location, raw_value, annotation)
356
360
 
357
361
  if isinstance(annotation, self.__generic_metaclass):
358
362
  return self._parse_generic_class(location, raw_value, annotation) # noqa
359
363
 
364
+ return self._error(location, f"Cannot parse value of type {annotation.__name__}")
365
+
360
366
  def _is_dev_mode_location(self, location):
361
367
 
362
368
  return any(map(lambda pattern: re.match(pattern, location), self._dev_mode_locations))
@@ -416,7 +422,7 @@ class ConfigParser(tp.Generic[_T]):
416
422
  def _parse_simple_class(self, location: str, raw_dict: tp.Any, metaclass: type) -> object:
417
423
 
418
424
  if raw_dict is not None and not isinstance(raw_dict, dict):
419
- pass
425
+ return self._error(location, f"Expected type {metaclass.__name__}, got '{str(raw_dict)}'")
420
426
 
421
427
  obj = metaclass.__new__(metaclass, object()) # noqa
422
428
 
@@ -510,7 +516,7 @@ class ConfigParser(tp.Generic[_T]):
510
516
  return self._error(location, f"Expected a list, got {type(raw_value)}")
511
517
 
512
518
  return [
513
- self._parse_value(self._child_location(location, str(idx)), item, list_type)
519
+ self._parse_value(self._child_location(location, idx), item, list_type)
514
520
  for (idx, item) in enumerate(raw_value)]
515
521
 
516
522
  if origin == tp.Dict or origin == dict:
@@ -541,12 +547,14 @@ class ConfigParser(tp.Generic[_T]):
541
547
  return None
542
548
 
543
549
  @staticmethod
544
- def _child_location(parent_location: str, item: str):
550
+ def _child_location(parent_location: str, item: tp.Union[str, int]):
545
551
 
546
552
  if parent_location is None or parent_location == "":
547
553
  return item
554
+ elif isinstance(item, int):
555
+ return f"{parent_location}[{item}]"
548
556
  else:
549
- return parent_location + "." + item
557
+ return f"{parent_location}.{item}"
550
558
 
551
559
 
552
560
  class ConfigQuoter:
@@ -55,7 +55,7 @@ class StaticApiImpl(_StaticApiHook):
55
55
  if not _val.is_primitive_type(entry_type):
56
56
  raise _ex.EModelValidation(f"Maps can only contain primitive types, [{entry_type}] is not primitive")
57
57
 
58
- return _meta.TypeDescriptor(_meta.BasicType.MAP, arrayType=_meta.TypeDescriptor(entry_type))
58
+ return _meta.TypeDescriptor(_meta.BasicType.MAP, mapType=_meta.TypeDescriptor(entry_type))
59
59
 
60
60
  def define_attribute(
61
61
  self, attr_name: str, attr_value: _tp.Any,
@@ -133,9 +133,13 @@ class MetadataCodec:
133
133
 
134
134
  if basic_type == _meta.BasicType.ARRAY:
135
135
  items = value.arrayValue.items
136
- return list(map(lambda x: MetadataCodec._decode_value_for_type(x, type_desc.arrayType), items))
136
+ return list(MetadataCodec._decode_value_for_type(x, type_desc.arrayType) for x in items)
137
137
 
138
- raise _ex.ETracInternal(f"Decoding value type [{basic_type}] is not supported yet")
138
+ if basic_type == _meta.BasicType.MAP:
139
+ items = value.mapValue.entries.items()
140
+ return dict((k, MetadataCodec._decode_value_for_type(v, type_desc.mapType)) for k, v in items)
141
+
142
+ raise _ex.ETracInternal(f"Cannot decode value of type [{basic_type}]")
139
143
 
140
144
  @classmethod
141
145
  def encode_value(cls, value: tp.Any) -> _meta.Value:
@@ -183,19 +187,36 @@ class MetadataCodec:
183
187
  if any(map(lambda x: type(x) != array_raw_type, value)):
184
188
  raise _ex.ETracInternal("Cannot encode a list with values of different types")
185
189
 
186
- encoded_items = list(map(lambda x: cls.convert_value(x, array_trac_type), value))
190
+ encoded_items = list(map(lambda x: cls.convert_value(x, array_trac_type, True), value))
187
191
 
188
192
  return _meta.Value(
189
193
  _meta.TypeDescriptor(_meta.BasicType.ARRAY, arrayType=array_trac_type),
190
194
  arrayValue=_meta.ArrayValue(encoded_items))
191
195
 
192
- raise _ex.ETracInternal(f"Value type [{type(value)}] is not supported yet")
196
+ if isinstance(value, dict):
197
+
198
+ if len(value) == 0:
199
+ raise _ex.ETracInternal("Cannot encode an empty dict")
200
+
201
+ map_raw_type = type(next(iter(value.values())))
202
+ map_trac_type = TypeMapping.python_to_trac(map_raw_type)
203
+
204
+ if any(map(lambda x: type(x) != array_raw_type, value.values())):
205
+ raise _ex.ETracInternal("Cannot encode a dict with values of different types")
206
+
207
+ encoded_entries = dict(map(lambda kv: (kv[0], cls.convert_value(kv[1], map_trac_type, True)), value.items()))
208
+
209
+ return _meta.Value(
210
+ _meta.TypeDescriptor(_meta.BasicType.ARRAY, mapType=map_trac_type),
211
+ mapValue=_meta.MapValue(encoded_entries))
212
+
213
+ raise _ex.ETracInternal(f"Cannot encode value of type [{type(value).__name__}]")
193
214
 
194
215
  @classmethod
195
- def convert_value(cls, raw_value: tp.Any, type_desc: _meta.TypeDescriptor):
216
+ def convert_value(cls, raw_value: tp.Any, type_desc: _meta.TypeDescriptor, nested: bool = False):
196
217
 
197
218
  if type_desc.basicType == _meta.BasicType.BOOLEAN:
198
- return cls.convert_boolean_value(raw_value)
219
+ return cls.convert_boolean_value(raw_value, nested)
199
220
 
200
221
  if type_desc.basicType == _meta.BasicType.INTEGER:
201
222
  return cls.convert_integer_value(raw_value)
@@ -218,78 +239,97 @@ class MetadataCodec:
218
239
  if type_desc.basicType == _meta.BasicType.ARRAY:
219
240
  return cls.convert_array_value(raw_value, type_desc.arrayType)
220
241
 
242
+ if type_desc.basicType == _meta.BasicType.MAP:
243
+ return cls.convert_map_value(raw_value, type_desc.mapType)
244
+
221
245
  raise _ex.ETracInternal(f"Conversion to value type [{type_desc.basicType.name}] is not supported yet")
222
246
 
223
247
  @staticmethod
224
248
  def convert_array_value(raw_value: tp.List[tp.Any], array_type: _meta.TypeDescriptor) -> _meta.Value:
225
249
 
226
- type_desc = _meta.TypeDescriptor(_meta.BasicType.ARRAY, array_type)
250
+ type_desc = _meta.TypeDescriptor(basicType=_meta.BasicType.ARRAY, arrayType=array_type)
227
251
 
228
252
  if not isinstance(raw_value, list):
229
- msg = f"Value of type [{type(raw_value)}] cannot be converted to {_meta.BasicType.ARRAY.name}"
253
+ msg = f"Value of type [{type(raw_value).__name__}] cannot be converted to {_meta.BasicType.ARRAY.name}"
230
254
  raise _ex.ETracInternal(msg)
231
255
 
232
- items = list(map(lambda x: MetadataCodec.convert_value(x, array_type), raw_value))
256
+ items = list(map(lambda x: MetadataCodec.convert_value(x, array_type, True), raw_value))
233
257
 
234
258
  return _meta.Value(type_desc, arrayValue=_meta.ArrayValue(items))
235
259
 
236
260
  @staticmethod
237
- def convert_boolean_value(raw_value: tp.Any) -> _meta.Value:
261
+ def convert_map_value(raw_value: tp.Dict[str, tp.Any], map_type: _meta.TypeDescriptor) -> _meta.Value:
262
+
263
+ type_desc = _meta.TypeDescriptor(basicType=_meta.BasicType.MAP, mapType=map_type)
264
+
265
+ if not isinstance(raw_value, dict):
266
+ msg = f"Value of type [{type(raw_value).__name__}] cannot be converted to {_meta.BasicType.MAP.name}"
267
+ raise _ex.ETracInternal(msg)
268
+
269
+ entries = dict(map(lambda kv: (kv[0], MetadataCodec.convert_value(kv[1], map_type, True)), raw_value.items()))
270
+
271
+ return _meta.Value(type_desc, mapValue=_meta.MapValue(entries))
272
+
273
+ @staticmethod
274
+ def convert_boolean_value(raw_value: tp.Any, nested: bool = False) -> _meta.Value:
238
275
 
239
- type_desc = _meta.TypeDescriptor(_meta.BasicType.BOOLEAN)
276
+ type_desc = _meta.TypeDescriptor(_meta.BasicType.BOOLEAN) if not nested else None
240
277
 
241
278
  if isinstance(raw_value, bool):
242
279
  return _meta.Value(type_desc, booleanValue=raw_value)
243
280
 
244
- msg = f"Value of type [{type(raw_value)}] cannot be converted to {_meta.BasicType.BOOLEAN.name}"
281
+ msg = f"Value of type [{type(raw_value).__name__}] cannot be converted to {_meta.BasicType.BOOLEAN.name}"
245
282
  raise _ex.ETracInternal(msg)
246
283
 
247
284
  @staticmethod
248
- def convert_integer_value(raw_value: tp.Any) -> _meta.Value:
285
+ def convert_integer_value(raw_value: tp.Any, nested: bool = False) -> _meta.Value:
249
286
 
250
- type_desc = _meta.TypeDescriptor(_meta.BasicType.INTEGER)
287
+ type_desc = _meta.TypeDescriptor(_meta.BasicType.INTEGER) if not nested else None
251
288
 
252
- if isinstance(raw_value, int):
289
+ # isinstance(bool_value, int) returns True! An explicit check is needed
290
+ if isinstance(raw_value, int) and not isinstance(raw_value, bool):
253
291
  return _meta.Value(type_desc, integerValue=raw_value)
254
292
 
255
293
  if isinstance(raw_value, float) and raw_value.is_integer():
256
294
  return _meta.Value(type_desc, integerValue=int(raw_value))
257
295
 
258
- msg = f"Value of type [{type(raw_value)}] cannot be converted to {_meta.BasicType.INTEGER.name}"
296
+ msg = f"Value of type [{type(raw_value).__name__}] cannot be converted to {_meta.BasicType.INTEGER.name}"
259
297
  raise _ex.ETracInternal(msg)
260
298
 
261
299
  @staticmethod
262
- def convert_float_value(raw_value: tp.Any) -> _meta.Value:
300
+ def convert_float_value(raw_value: tp.Any, nested: bool = False) -> _meta.Value:
263
301
 
264
- type_desc = _meta.TypeDescriptor(_meta.BasicType.FLOAT)
302
+ type_desc = _meta.TypeDescriptor(_meta.BasicType.FLOAT) if not nested else None
265
303
 
266
304
  if isinstance(raw_value, float):
267
305
  return _meta.Value(type_desc, floatValue=raw_value)
268
306
 
269
- if isinstance(raw_value, int):
307
+ # isinstance(bool_value, int) returns True! An explicit check is needed
308
+ if isinstance(raw_value, int) and not isinstance(raw_value, bool):
270
309
  return _meta.Value(type_desc, floatValue=float(raw_value))
271
310
 
272
- msg = f"Value of type [{type(raw_value)}] cannot be converted to {_meta.BasicType.FLOAT.name}"
311
+ msg = f"Value of type [{type(raw_value).__name__}] cannot be converted to {_meta.BasicType.FLOAT.name}"
273
312
  raise _ex.ETracInternal(msg)
274
313
 
275
314
  @staticmethod
276
- def convert_decimal_value(raw_value: tp.Any) -> _meta.Value:
315
+ def convert_decimal_value(raw_value: tp.Any, nested: bool = False) -> _meta.Value:
277
316
 
278
- type_desc = _meta.TypeDescriptor(_meta.BasicType.DECIMAL)
317
+ type_desc = _meta.TypeDescriptor(_meta.BasicType.DECIMAL) if not nested else None
279
318
 
280
319
  if isinstance(raw_value, decimal.Decimal):
281
320
  return _meta.Value(type_desc, decimalValue=_meta.DecimalValue(str(raw_value)))
282
321
 
283
- if isinstance(raw_value, int) or isinstance(raw_value, float):
322
+ # isinstance(bool_value, int) returns True! An explicit check is needed
323
+ if isinstance(raw_value, int) or isinstance(raw_value, float) and not isinstance(raw_value, bool):
284
324
  return _meta.Value(type_desc, decimalValue=_meta.DecimalValue(str(raw_value)))
285
325
 
286
- msg = f"Value of type [{type(raw_value)}] cannot be converted to {_meta.BasicType.DECIMAL.name}"
326
+ msg = f"Value of type [{type(raw_value).__name__}] cannot be converted to {_meta.BasicType.DECIMAL.name}"
287
327
  raise _ex.ETracInternal(msg)
288
328
 
289
329
  @staticmethod
290
- def convert_string_value(raw_value: tp.Any) -> _meta.Value:
330
+ def convert_string_value(raw_value: tp.Any, nested: bool = False) -> _meta.Value:
291
331
 
292
- type_desc = _meta.TypeDescriptor(_meta.BasicType.STRING)
332
+ type_desc = _meta.TypeDescriptor(_meta.BasicType.STRING) if not nested else None
293
333
 
294
334
  if isinstance(raw_value, str):
295
335
  return _meta.Value(type_desc, stringValue=raw_value)
@@ -301,13 +341,13 @@ class MetadataCodec:
301
341
 
302
342
  return _meta.Value(type_desc, stringValue=str(raw_value))
303
343
 
304
- msg = f"Value of type [{type(raw_value)}] cannot be converted to {_meta.BasicType.STRING.name}"
344
+ msg = f"Value of type [{type(raw_value).__name__}] cannot be converted to {_meta.BasicType.STRING.name}"
305
345
  raise _ex.ETracInternal(msg)
306
346
 
307
347
  @staticmethod
308
- def convert_date_value(raw_value: tp.Any) -> _meta.Value:
348
+ def convert_date_value(raw_value: tp.Any, nested: bool = False) -> _meta.Value:
309
349
 
310
- type_desc = _meta.TypeDescriptor(_meta.BasicType.DATE)
350
+ type_desc = _meta.TypeDescriptor(_meta.BasicType.DATE) if not nested else None
311
351
 
312
352
  if isinstance(raw_value, dt.date):
313
353
  return _meta.Value(type_desc, dateValue=_meta.DateValue(isoDate=raw_value.isoformat()))
@@ -316,13 +356,13 @@ class MetadataCodec:
316
356
  date_value = dt.date.fromisoformat(raw_value)
317
357
  return _meta.Value(type_desc, dateValue=_meta.DateValue(isoDate=date_value.isoformat()))
318
358
 
319
- msg = f"Value of type [{type(raw_value)}] cannot be converted to {_meta.BasicType.DATE.name}"
359
+ msg = f"Value of type [{type(raw_value).__name__}] cannot be converted to {_meta.BasicType.DATE.name}"
320
360
  raise _ex.ETracInternal(msg)
321
361
 
322
362
  @staticmethod
323
- def convert_datetime_value(raw_value: tp.Any) -> _meta.Value:
363
+ def convert_datetime_value(raw_value: tp.Any, nested: bool = False) -> _meta.Value:
324
364
 
325
- type_desc = _meta.TypeDescriptor(_meta.BasicType.DATETIME)
365
+ type_desc = _meta.TypeDescriptor(_meta.BasicType.DATETIME) if not nested else None
326
366
 
327
367
  if isinstance(raw_value, dt.datetime):
328
368
  return _meta.Value(type_desc, datetimeValue=_meta.DatetimeValue(isoDatetime=raw_value.isoformat()))
@@ -331,5 +371,5 @@ class MetadataCodec:
331
371
  datetime_value = dt.datetime.fromisoformat(raw_value)
332
372
  return _meta.Value(type_desc, datetimeValue=_meta.DatetimeValue(isoDatetime=datetime_value.isoformat()))
333
373
 
334
- msg = f"Value of type [{type(raw_value)}] cannot be converted to {_meta.BasicType.DATETIME.name}"
374
+ msg = f"Value of type [{type(raw_value).__name__}] cannot be converted to {_meta.BasicType.DATETIME.name}"
335
375
  raise _ex.ETracInternal(msg)
@@ -268,10 +268,18 @@ plugins.PluginManager.register_plugin(IStorageProvider, SqlStorageProvider, ["SQ
268
268
 
269
269
 
270
270
  try:
271
-
272
271
  import sqlalchemy as sqla # noqa
273
272
  import sqlalchemy.exc as sqla_exc # noqa
274
273
 
274
+ # Only 2.x versions of SQL Alchemy are currently supported
275
+ sqla_supported = sqla.__version__.startswith("2.")
276
+
277
+ except ModuleNotFoundError:
278
+ sqla = None
279
+ sqla_supported = False
280
+
281
+ if sqla_supported:
282
+
275
283
  class SqlAlchemyDriver(ISqlDriver):
276
284
 
277
285
  def __init__(self, properties: tp.Dict[str, str]):
@@ -336,7 +344,7 @@ try:
336
344
 
337
345
  class ConnectionWrapper(DbApiWrapper.Connection):
338
346
 
339
- def __init__(self, conn: sqla.Connection):
347
+ def __init__(self, conn: "sqla.Connection"):
340
348
  self.__conn = conn
341
349
 
342
350
  def close(self):
@@ -355,7 +363,7 @@ try:
355
363
 
356
364
  arraysize: int = 1000
357
365
 
358
- def __init__(self, conn: sqla.Connection):
366
+ def __init__(self, conn: "sqla.Connection"):
359
367
  self.__conn = conn
360
368
  self.__result: tp.Optional[sqla.CursorResult] = None
361
369
 
@@ -414,5 +422,4 @@ try:
414
422
 
415
423
  plugins.PluginManager.register_plugin(ISqlDriver, SqlAlchemyDriver, ["alchemy"])
416
424
 
417
- except ModuleNotFoundError:
418
- pass
425
+
@@ -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.7.0"
16
+ __version__ = "0.7.1"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: tracdap-runtime
3
- Version: 0.7.0
3
+ Version: 0.7.1
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
File without changes
@@ -9,6 +9,8 @@ from .type import Value
9
9
  from .type import ArrayValue
10
10
  from .type import MapValue
11
11
 
12
+ from .custom import CustomDefinition
13
+
12
14
  from .object_id import ObjectType
13
15
  from .object_id import TagHeader
14
16
  from .object_id import TagSelector
@@ -21,6 +23,13 @@ from .data import SchemaDefinition
21
23
  from .data import PartKey
22
24
  from .data import DataDefinition
23
25
 
26
+ from .stoarge import CopyStatus
27
+ from .stoarge import IncarnationStatus
28
+ from .stoarge import StorageCopy
29
+ from .stoarge import StorageIncarnation
30
+ from .stoarge import StorageItem
31
+ from .stoarge import StorageDefinition
32
+
24
33
  from .model import ModelType
25
34
  from .model import ModelParameter
26
35
  from .model import ModelInputSchema
@@ -56,23 +65,14 @@ from .job import JobGroup
56
65
  from .job import SequentialJobGroup
57
66
  from .job import ParallelJobGroup
58
67
 
59
- from .file import FileDefinition
60
-
61
- from .custom import CustomDefinition
62
-
63
- from .stoarge import CopyStatus
64
- from .stoarge import IncarnationStatus
65
- from .stoarge import StorageCopy
66
- from .stoarge import StorageIncarnation
67
- from .stoarge import StorageItem
68
- from .stoarge import StorageDefinition
69
-
70
- from .object import ObjectDefinition
71
-
72
- from .resource import ResourceType
73
-
74
68
  from .common import MetadataFormat
75
69
  from .common import MetadataVersion
76
70
  from .common import TenantInfo
77
71
 
72
+ from .file import FileDefinition
73
+
74
+ from .object import ObjectDefinition
75
+
78
76
  from .tag import Tag
77
+
78
+ from .resource import ResourceType