data_pipeline_api 0.7.2__tar.gz → 0.7.3__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 (185) hide show
  1. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/PKG-INFO +1 -1
  2. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/README.md +1 -1
  3. data_pipeline_api-0.7.3/data_pipeline_api/data_processing_api.py +18 -0
  4. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/database_file_api.py +0 -2
  5. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/file_api.py +4 -1
  6. data_pipeline_api-0.7.3/data_pipeline_api/file_formats/parameter_file.py +188 -0
  7. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/metadata.py +1 -1
  8. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/access_upload.py +24 -25
  9. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/download.py +11 -2
  10. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/downloader.py +34 -14
  11. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/standard_api.py +1 -1
  12. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api.egg-info/PKG-INFO +1 -1
  13. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api.egg-info/SOURCES.txt +3 -0
  14. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/config/Config.java +1 -0
  15. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/metadata/MetadataItem.java +14 -3
  16. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/yaml/BaseYamlWriter.java +3 -1
  17. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/api/FileApiIntegrationTest.java +1 -1
  18. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/api/StandardApi.java +45 -16
  19. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/distribution/Distribution.java +21 -7
  20. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/distribution/MinMaxDeserializer.java +8 -4
  21. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/distribution/MinMaxSerializer.java +6 -2
  22. data_pipeline_api-0.7.3/java_api/standard_api/src/main/java/uk/ramp/mapper/DataPipelineMapper.java +51 -0
  23. data_pipeline_api-0.7.3/java_api/standard_api/src/main/java/uk/ramp/parameters/Component.java +9 -0
  24. data_pipeline_api-0.7.3/java_api/standard_api/src/main/java/uk/ramp/parameters/Components.java +9 -0
  25. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/parameters/ComponentsDeserializer.java +16 -4
  26. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/parameters/ComponentsSerializer.java +18 -5
  27. data_pipeline_api-0.7.3/java_api/standard_api/src/main/java/uk/ramp/parameters/RandomGeneratorDeserializer.java +19 -0
  28. data_pipeline_api-0.7.3/java_api/standard_api/src/main/java/uk/ramp/parameters/RandomGeneratorSerializer.java +17 -0
  29. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/samples/Samples.java +1 -0
  30. data_pipeline_api-0.7.3/java_api/standard_api/src/main/java/uk/ramp/toml/TOMLFactory.java +12 -0
  31. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/toml/TOMLInputDecorator.java +9 -7
  32. data_pipeline_api-0.7.3/java_api/standard_api/src/main/java/uk/ramp/toml/TOMLMapper.java +10 -0
  33. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/toml/TOMLOutputDecorator.java +10 -7
  34. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/api/StandardApiIntegrationTest.java +71 -62
  35. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/api/StandardApiTest.java +17 -13
  36. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/distribution/DistributionTest.java +58 -45
  37. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/estimate/EstimateTest.java +15 -3
  38. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/parameters/ComponentsDeserializerTest.java +11 -7
  39. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/parameters/ComponentsSerializerTest.java +11 -7
  40. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/parameters/ParameterDataWriterImplTest.java +5 -1
  41. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/samples/SamplesTest.java +12 -3
  42. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/toml/TomlReaderPairwiseIntegrationTest.java +14 -2
  43. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/toml/TomlWriterPairwiseIntegrationTest.java +10 -3
  44. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/folder/data/object/example5.h5 +1 -1
  45. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/data/parameter/example-v2.toml +2 -2
  46. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/data/parameter/example.toml +2 -2
  47. data_pipeline_api-0.7.3/tests/file_formats/test_parameter_file.py +140 -0
  48. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/registry/test_downloader.py +122 -54
  49. data_pipeline_api-0.7.3/tests/test_data_processing_api.py +42 -0
  50. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/test_file_api.py +17 -3
  51. data_pipeline_api-0.7.2/data_pipeline_api/data_processing_api.py +0 -14
  52. data_pipeline_api-0.7.2/data_pipeline_api/file_formats/parameter_file.py +0 -121
  53. data_pipeline_api-0.7.2/java_api/standard_api/src/main/java/uk/ramp/parameters/Component.java +0 -3
  54. data_pipeline_api-0.7.2/java_api/standard_api/src/main/java/uk/ramp/parameters/Components.java +0 -13
  55. data_pipeline_api-0.7.2/java_api/standard_api/src/main/java/uk/ramp/toml/TOMLFactory.java +0 -11
  56. data_pipeline_api-0.7.2/java_api/standard_api/src/main/java/uk/ramp/toml/TOMLMapper.java +0 -13
  57. data_pipeline_api-0.7.2/tests/file_formats/test_parameter_file.py +0 -91
  58. data_pipeline_api-0.7.2/tests/test_data_processing_api.py +0 -21
  59. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/.gitignore +0 -0
  60. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/.pylintrc +0 -0
  61. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/.travis.yml +0 -0
  62. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/LICENSE +0 -0
  63. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/conda/meta.yaml +0 -0
  64. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/contributing.md +0 -0
  65. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/__init__.py +0 -0
  66. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/file_formats/object_file.py +0 -0
  67. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/git_info.py +0 -0
  68. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/metadata_store.py +0 -0
  69. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/overrides.py +0 -0
  70. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/README.md +0 -0
  71. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/__init__.py +0 -0
  72. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/common.py +0 -0
  73. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/templates/data_product.yaml +0 -0
  74. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/upload.py +0 -0
  75. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/upload_data_product.py +0 -0
  76. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api/registry/utils.py +0 -0
  77. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api.egg-info/dependency_links.txt +0 -0
  78. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api.egg-info/entry_points.txt +0 -0
  79. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api.egg-info/requires.txt +0 -0
  80. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/data_pipeline_api.egg-info/top_level.txt +0 -0
  81. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/environment.yml +0 -0
  82. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/examples/example_configs/simple_network_sim_config.yaml +0 -0
  83. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/examples/example_configs/simple_network_sim_upload.yaml +0 -0
  84. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/examples/standard_api_usage.py +0 -0
  85. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/build.gradle +0 -0
  86. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/build.gradle +0 -0
  87. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/access/AccessEntry.java +0 -0
  88. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/access/AccessLog.java +0 -0
  89. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/access/AccessLogWriter.java +0 -0
  90. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/access/AccessLogger.java +0 -0
  91. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/access/AccessLoggerFactory.java +0 -0
  92. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/access/AccessLoggerImpl.java +0 -0
  93. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/access/NoImplAccessLogger.java +0 -0
  94. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/api/FileApi.java +0 -0
  95. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/config/ConfigFactory.java +0 -0
  96. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/config/ConfigReader.java +0 -0
  97. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/file/CleanableFileChannel.java +0 -0
  98. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/file/FileDirectoryNormaliser.java +0 -0
  99. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/file/FileReader.java +0 -0
  100. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/hash/HashMetadataAppender.java +0 -0
  101. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/hash/Hasher.java +0 -0
  102. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/hash/Sha1Hasher.java +0 -0
  103. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/metadata/IssueItem.java +0 -0
  104. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/metadata/MatchingMetadataSelector.java +0 -0
  105. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/metadata/MetaDataReader.java +0 -0
  106. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/metadata/MetadataFactory.java +0 -0
  107. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/metadata/MetadataSelector.java +0 -0
  108. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/metadata/ReadOnlyRunMetadata.java +0 -0
  109. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/metadata/RunMetadata.java +0 -0
  110. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/metadata/WriteOnlyRunMetadata.java +0 -0
  111. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/overrides/OverridesApplier.java +0 -0
  112. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/yaml/BaseYamlReader.java +0 -0
  113. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/yaml/YamlFactory.java +0 -0
  114. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/yaml/YamlReader.java +0 -0
  115. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/main/java/uk/ramp/yaml/YamlWriter.java +0 -0
  116. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/access/AccessLoggerTest.java +0 -0
  117. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/file/CleanableFileChannelIntegrationTest.java +0 -0
  118. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/file/FileDirectoryNormaliserTest.java +0 -0
  119. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/hash/HashMetadataAppenderTest.java +0 -0
  120. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/hash/Sha1HasherTest.java +0 -0
  121. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/metadata/MatchingMetadataSelectorTest.java +0 -0
  122. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/metadata/MetadataItemTest.java +0 -0
  123. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/metadata/MetadataItemVersionComparisonTest.java +0 -0
  124. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/java/uk/ramp/yaml/BaseYamlWriterTest.java +0 -0
  125. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/resources/config.yaml +0 -0
  126. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/resources/folder/data/metadata.yaml +0 -0
  127. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/file_api/src/test/resources/folder/data/parameter/example1.toml +0 -0
  128. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/gradle/wrapper/gradle-wrapper.jar +0 -0
  129. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/gradle/wrapper/gradle-wrapper.properties +0 -0
  130. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/gradlew +0 -0
  131. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/gradlew.bat +0 -0
  132. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/settings.gradle +0 -0
  133. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/build.gradle +0 -0
  134. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/distribution/MinMax.java +0 -0
  135. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/estimate/Estimate.java +0 -0
  136. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/objects/NumericalArray.java +0 -0
  137. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/objects/NumericalArrayImpl.java +0 -0
  138. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/objects/StandardArrayDataReader.java +0 -0
  139. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/objects/StandardTable.java +0 -0
  140. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/objects/StandardTableDataReader.java +0 -0
  141. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/parameters/ParameterDataReader.java +0 -0
  142. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/parameters/ParameterDataReaderImpl.java +0 -0
  143. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/parameters/ParameterDataWriter.java +0 -0
  144. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/parameters/ParameterDataWriterImpl.java +0 -0
  145. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/parameters/ReadComponent.java +0 -0
  146. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/parameters/WriteComponent.java +0 -0
  147. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/samples/Sampler.java +0 -0
  148. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/toml/TomlReader.java +0 -0
  149. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/main/java/uk/ramp/toml/TomlWriter.java +0 -0
  150. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/parameters/ParameterDataReaderTest.java +0 -0
  151. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/java/uk/ramp/samples/SamplerTest.java +0 -0
  152. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/config.yaml +0 -0
  153. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/folder/data/expectedDistribution.toml +0 -0
  154. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/folder/data/expectedDistributionCategorical.toml +0 -0
  155. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/folder/data/expectedEstimate.toml +0 -0
  156. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/folder/data/expectedSamples.toml +0 -0
  157. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/folder/data/expectedSamplesMultiple.toml +0 -0
  158. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/folder/data/metadata.yaml +0 -0
  159. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/folder/data/parameter/example1.toml +0 -0
  160. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/location.txt +0 -0
  161. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/table.csv +0 -0
  162. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/java_api/standard_api/src/test/resources/table.h5 +0 -0
  163. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/jitpack.yml +0 -0
  164. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/scripts/convert_access_to_config.py +0 -0
  165. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/scripts/release.sh +0 -0
  166. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/setup.cfg +0 -0
  167. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/setup.py +0 -0
  168. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/__init__.py +0 -0
  169. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/conftest.py +0 -0
  170. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/data/config.yaml +0 -0
  171. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/data/demographics.h5 +0 -0
  172. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/data/metadata.yaml +0 -0
  173. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/data/object/example-v2.h5 +0 -0
  174. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/data/object/example.h5 +0 -0
  175. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/file_formats/test_object_file.py +0 -0
  176. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/registry/__init__.py +0 -0
  177. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/registry/test_access_upload.py +0 -0
  178. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/registry/test_common.py +0 -0
  179. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/registry/test_download.py +0 -0
  180. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/registry/test_upload.py +0 -0
  181. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/registry/test_utils.py +0 -0
  182. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/test_git_info.py +0 -0
  183. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/test_metadata_store.py +0 -0
  184. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/test_overrides.py +0 -0
  185. {data_pipeline_api-0.7.2 → data_pipeline_api-0.7.3}/tests/test_standard_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.0
2
2
  Name: data_pipeline_api
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: Interacts with SCRC data pipeline
5
5
  Home-page: UNKNOWN
6
6
  Author: SCRC
@@ -36,7 +36,7 @@ This is most useful for testing and development.
36
36
  A packaged version can be installed via [Anaconda Cloud](https://anaconda.org/scottishcovidresponse/data_pipeline_api) for use in other applications:
37
37
 
38
38
  ```bash
39
- conda install -c ScottishCovidResponse data-pipeline-api
39
+ conda install -c scottishcovidresponse data-pipeline-api
40
40
  ```
41
41
 
42
42
  ### Pip
@@ -0,0 +1,18 @@
1
+ from io import IOBase
2
+ from typing import Optional
3
+ from data_pipeline_api.standard_api import StandardAPI
4
+
5
+
6
+ class DataProcessingAPI(StandardAPI):
7
+ """The DataProcessingAPI extends the StandardAPI with access to external objects.
8
+ """
9
+
10
+ def read_external_object(
11
+ self, doi_or_unique_name: str, title: str, component: Optional[str] = None,
12
+ ) -> IOBase:
13
+ """Return an open file handle to read the given external object.
14
+ """
15
+ kwds = dict(doi_or_unique_name=doi_or_unique_name, title=title)
16
+ if component is not None:
17
+ kwds["component"] = component
18
+ return self.file_api.open_for_read(**kwds)
@@ -18,8 +18,6 @@ class DatabaseFileAPI(FileAPI):
18
18
  RUN_METADATA_NEEDED_FOR_UPLOAD = {
19
19
  RunMetadata.data_directory,
20
20
  RunMetadata.run_id,
21
- RunMetadata.model_version,
22
- RunMetadata.model_name,
23
21
  RunMetadata.open_timestamp,
24
22
  RunMetadata.git_sha,
25
23
  RunMetadata.git_repo,
@@ -202,7 +202,10 @@ class FileAPI:
202
202
  self._run_metadata["run_id"] = self._run_id
203
203
  self._run_metadata["data_directory"] = str(self._unnormalised_data_directory)
204
204
  self._run_metadata["open_timestamp"] = self._open_timestamp
205
- self._run_metadata.update(self._config.get("run_metadata", {}))
205
+ run_metadata = self._config.get("run_metadata", {})
206
+ if any(key in run_metadata for key in FileAPI.RESERVED_RUN_METADATA_KEYS):
207
+ raise ValueError(f"reserved key {key} is set in run_metadata")
208
+ self._run_metadata.update(run_metadata)
206
209
 
207
210
  self._read_overrides = FileAPI.construct_overrides(self._config.get("read", ()))
208
211
  self._write_overrides = FileAPI.construct_overrides(
@@ -0,0 +1,188 @@
1
+ from io import TextIOBase
2
+ from enum import Enum
3
+ from numbers import Real
4
+ from typing import Union, Dict, Any, Tuple
5
+ import toml
6
+ import numpy as np
7
+ from scipy import stats
8
+
9
+ # ======================================================================================
10
+ # Common
11
+ # ======================================================================================
12
+
13
+ ParameterComponent = Dict[str, Any]
14
+ Estimate = Real
15
+ Distribution = Union[stats.rv_discrete, stats.rv_continuous]
16
+ Samples = np.ndarray
17
+
18
+
19
+ class ParameterType(Enum):
20
+ POINT_ESTIMATE = "point-estimate"
21
+ DISTRIBUTION = "distribution"
22
+ SAMPLES = "samples"
23
+
24
+
25
+ def read_parameter(file: TextIOBase, component: str) -> ParameterComponent:
26
+ file.seek(0)
27
+ return toml.load(file)[component]
28
+
29
+
30
+ def write_parameter(file: TextIOBase, component: str, parameter: ParameterComponent):
31
+ parameter_data = toml.load(file)
32
+ parameter_data[component] = parameter
33
+ file.seek(0)
34
+ file.truncate()
35
+ toml.dump(parameter_data, file)
36
+
37
+
38
+ def read_type(file: TextIOBase, component: str) -> ParameterType:
39
+ parameter = read_parameter(file, component)
40
+ return ParameterType(parameter["type"])
41
+
42
+
43
+ # ======================================================================================
44
+ # Estimate
45
+ # ======================================================================================
46
+
47
+
48
+ def read_estimate(file: TextIOBase, component: str) -> Estimate:
49
+ parameter = read_parameter(file, component)
50
+ if ParameterType(parameter["type"]) is ParameterType.POINT_ESTIMATE:
51
+ # TODO : validate
52
+ return parameter["value"]
53
+ else:
54
+ raise ValueError(f"{parameter['type']} != 'point-estimate'")
55
+
56
+
57
+ def write_estimate(file: TextIOBase, component: str, estimate: Estimate):
58
+ write_parameter(
59
+ file, component, {"type": "point-estimate", "value": float(estimate)}
60
+ )
61
+
62
+
63
+ # ======================================================================================
64
+ # Distribution
65
+ # ======================================================================================
66
+
67
+
68
+ class Categorical(stats._multivariate.multinomial_frozen):
69
+ """A scipy-compatible categorical distribution, built on top of a multinomial.
70
+ """
71
+
72
+ def __init__(self, categories, p):
73
+ super().__init__(n=1, p=p)
74
+ self.categories = np.array(categories)
75
+
76
+ def rvs(self, size=1, random_state=None):
77
+ return self.categories[
78
+ super().rvs(size=size, random_state=random_state).argmax(axis=-1)
79
+ ]
80
+
81
+
82
+ def distribution_parameters(
83
+ distribution: Distribution,
84
+ ) -> Tuple[Tuple[float, ...], float, float]:
85
+ """Extract the parameters from a scipy rv_frozen object, in the form
86
+ ((shape, ...), loc, scale).
87
+ """
88
+ return distribution.dist._parse_args(*distribution.args, **distribution.kwds)
89
+
90
+
91
+ # Mapping between scipy and standard names.
92
+ distribution_name_mapping = {
93
+ "gamma": "gamma",
94
+ "norm": "normal",
95
+ "uniform": "uniform",
96
+ "poisson": "poisson",
97
+ "expon": "exponential",
98
+ "beta": "beta",
99
+ "binom": "binomial",
100
+ }
101
+
102
+ # Functions to encode (scipy) distribution parameters.
103
+ distribution_parameter_encoders = {
104
+ "gamma": lambda shapes, loc, scale: dict(k=shapes[0], theta=scale),
105
+ "normal": lambda shapes, loc, scale: dict(mu=loc, sigma=scale),
106
+ "uniform": lambda shapes, loc, scale: dict(a=loc, b=loc + scale),
107
+ "poisson": lambda shapes, loc, scale: {"lambda": shapes[0]},
108
+ "exponential": lambda shapes, loc, scale: {"lambda": 1 / scale},
109
+ "beta": lambda shapes, loc, scale: dict(alpha=shapes[0], beta=shapes[1]),
110
+ "binomial": lambda shapes, loc, scale: dict(n=shapes[0], p=shapes[1]),
111
+ }
112
+
113
+
114
+ def encode_distribution(distribution: Distribution) -> Dict[str, Any]:
115
+ """Encode distribution into a serialisable format."""
116
+ if isinstance(distribution, Categorical):
117
+ name = "categorical"
118
+ encoded_parameters = {
119
+ "bins": [str(c) for c in distribution.categories],
120
+ "weights": list(distribution.p),
121
+ }
122
+ elif isinstance(distribution, stats._multivariate.multinomial_frozen):
123
+ name = "multinomial"
124
+ encoded_parameters = {
125
+ "n": distribution.n,
126
+ "p": list(distribution.p),
127
+ }
128
+ elif isinstance(distribution, stats.distributions.rv_frozen):
129
+ name = distribution_name_mapping[distribution.dist.name]
130
+ encoded_parameters = distribution_parameter_encoders[name](
131
+ *distribution_parameters(distribution)
132
+ )
133
+ else:
134
+ raise ValueError(f"Do not have a codec for {distribution}")
135
+ return dict(type="distribution", distribution=name, **encoded_parameters)
136
+
137
+
138
+ # Functions to decode serialised distributions.
139
+ distribution_decoders = {
140
+ "categorical": lambda data: Categorical(data["bins"], data["weights"]),
141
+ "gamma": lambda data: stats.gamma(data["k"], scale=data["theta"]),
142
+ "normal": lambda data: stats.norm(data["mu"], data["sigma"]),
143
+ "uniform": lambda data: stats.uniform(data["a"], data["b"] - data["a"]),
144
+ "poisson": lambda data: stats.poisson(data["lambda"]),
145
+ "exponential": lambda data: stats.expon(scale=1 / data["lambda"]),
146
+ "beta": lambda data: stats.beta(data["alpha"], data["beta"]),
147
+ "binomial": lambda data: stats.binom(data["n"], data["p"]),
148
+ "multinomial": lambda data: stats.multinomial(data["n"], data["p"]),
149
+ }
150
+
151
+
152
+ def decode_distribution(encoded_distribution: Dict[str, Any]) -> Distribution:
153
+ """Decode distribution from serialised format.
154
+ """
155
+ return distribution_decoders[encoded_distribution["distribution"]](
156
+ encoded_distribution
157
+ )
158
+
159
+
160
+ def read_distribution(file: TextIOBase, component: str) -> Distribution:
161
+ parameter = read_parameter(file, component)
162
+ if ParameterType(parameter["type"]) is ParameterType.DISTRIBUTION:
163
+ return decode_distribution(parameter)
164
+ raise ValueError(f"{parameter['type']} != 'distribution'")
165
+
166
+
167
+ def write_distribution(file: TextIOBase, component: str, distribution: Distribution):
168
+ """Write distribution to file under component."""
169
+ write_parameter(
170
+ file, component, encode_distribution(distribution),
171
+ )
172
+
173
+
174
+ # ======================================================================================
175
+ # Samples
176
+ # ======================================================================================
177
+
178
+
179
+ def read_samples(file: TextIOBase, component: str) -> Samples:
180
+ parameter = read_parameter(file, component)
181
+ if ParameterType(parameter["type"]) is ParameterType.SAMPLES:
182
+ return np.array(parameter["samples"])
183
+ else:
184
+ raise ValueError(f"{parameter['type']} != 'samples'")
185
+
186
+
187
+ def write_samples(file: TextIOBase, component: str, samples: Samples):
188
+ write_parameter(file, component, {"type": "samples", "samples": samples.tolist()})
@@ -4,7 +4,6 @@ from typing import Mapping, Any
4
4
  Metadata = Mapping[str, Any]
5
5
 
6
6
 
7
-
8
7
  class MetadataKey:
9
8
  """Metadata key constants.
10
9
  """
@@ -20,6 +19,7 @@ class MetadataKey:
20
19
  calculated_hash = "calculated_hash"
21
20
  accessibility = "accessibility"
22
21
  doi_or_unique_name = "doi_or_unique_name"
22
+ title = "title"
23
23
 
24
24
 
25
25
  def value_matches(value_a: Any, value_b: Any) -> bool:
@@ -189,7 +189,6 @@ def _add_data_product_output_posts(
189
189
  path: str,
190
190
  data_product_name: str,
191
191
  namespace_str: str,
192
- model_version_str: str,
193
192
  run_id: str,
194
193
  component_name: str,
195
194
  calculated_hash: str,
@@ -203,7 +202,6 @@ def _add_data_product_output_posts(
203
202
  :param path: StorageLocation path
204
203
  :param data_product_name: Name of the output data product
205
204
  :param namespace_str: namespace that the data product is a member of
206
- :param model_version_str: version number of the model
207
205
  :param run_id: id of the run
208
206
  :param component_name: name of the output component
209
207
  :param calculated_hash: calculated hash of the output data product file
@@ -229,7 +227,7 @@ def _add_data_product_output_posts(
229
227
  DataRegistryTarget.data_product,
230
228
  {
231
229
  DataRegistryField.name: data_product_name,
232
- DataRegistryField.version: f"{model_version_str}+{run_id}",
230
+ DataRegistryField.version: f"{run_id}",
233
231
  DataRegistryField.namespace: namespace,
234
232
  DataRegistryField.object: obj,
235
233
  },
@@ -327,21 +325,21 @@ def to_github_uri(input_uri: str, git_sha: str = "master") -> str:
327
325
 
328
326
  def _add_code_repo(
329
327
  posts: List[YamlDict],
330
- model_name: str,
331
- model_version: str,
332
328
  model_git_sha: str,
333
329
  model_uri: str,
330
+ model_name: Optional[str],
331
+ model_version: Optional[str],
334
332
  ) -> YamlDict:
335
333
  """
336
- Creates a code_repo_release and storage_location for the model and adds them to the list of objects to post to the
337
- data registry
334
+ Creates a code_repo and storage_location, and optionally a code_repo_release for the
335
+ model and adds them to the list of objects to post to the data registry
338
336
 
339
337
  :param posts: List of posts to the data registry, will be modified
340
- :param model_name: name of the model
341
- :param model_version: version of the model
342
338
  :param model_git_sha: git sha of the model
343
339
  :param model_uri: uri that the model is located at
344
- :return: the object reference to the code repo release
340
+ :param model_name: name of the model
341
+ :param model_version: version of the model
342
+ :return: the object reference to the code repo
345
343
  """
346
344
  storage_root_uri = to_github_uri(model_uri, model_git_sha)
347
345
 
@@ -368,22 +366,24 @@ def _add_code_repo(
368
366
  code_repo_obj = _create_target_data_dict(
369
367
  DataRegistryTarget.object,
370
368
  {
371
- DataRegistryField.description: f"{model_name}+{model_version}",
369
+ DataRegistryField.description: f"{storage_root_uri}",
372
370
  DataRegistryField.storage_location: code_repo_location,
373
371
  },
374
372
  )
375
- code_repo_release = _create_target_data_dict(
376
- DataRegistryTarget.code_repo_release,
377
- {
378
- DataRegistryField.name: model_name,
379
- DataRegistryField.version: model_version,
380
- DataRegistryField.website: model_uri,
381
- DataRegistryField.object: code_repo_obj,
382
- },
383
- )
384
373
  posts.extend(
385
- [code_repo_storage, code_repo_location, code_repo_obj, code_repo_release]
374
+ [code_repo_storage, code_repo_location, code_repo_obj]
386
375
  )
376
+ if model_name is not None and model_version is not None:
377
+ code_repo_release = _create_target_data_dict(
378
+ DataRegistryTarget.code_repo_release,
379
+ {
380
+ DataRegistryField.name: model_name,
381
+ DataRegistryField.version: model_version,
382
+ DataRegistryField.website: model_uri,
383
+ DataRegistryField.object: code_repo_obj,
384
+ },
385
+ )
386
+ posts.append(code_repo_release)
387
387
 
388
388
  return code_repo_obj
389
389
 
@@ -482,8 +482,8 @@ def upload_model_run(
482
482
  data_directory = config_filename.parent / data_directory
483
483
  run_id = run_metadata[RunMetadata.run_id]
484
484
  namespace = run_metadata.get(RunMetadata.default_output_namespace)
485
- model_version_str = run_metadata[RunMetadata.model_version]
486
- model_name = run_metadata[RunMetadata.model_name]
485
+ model_version_str = run_metadata.get(RunMetadata.model_version)
486
+ model_name = run_metadata.get(RunMetadata.model_name)
487
487
  open_timestamp = run_metadata[RunMetadata.open_timestamp]
488
488
  model_git_sha = run_metadata[RunMetadata.git_sha]
489
489
  model_uri = run_metadata[RunMetadata.git_repo]
@@ -502,7 +502,7 @@ def upload_model_run(
502
502
  posts, remote_uri_override, accessibility, data_registry_url, token
503
503
  )
504
504
  code_repo = _add_code_repo(
505
- posts, model_name, model_version_str, model_git_sha, model_uri
505
+ posts, model_git_sha, model_uri, model_name, model_version_str
506
506
  )
507
507
 
508
508
  for event in config["io"]:
@@ -540,7 +540,6 @@ def upload_model_run(
540
540
  path,
541
541
  data_product_name,
542
542
  event_namespace,
543
- model_version_str,
544
543
  run_id,
545
544
  component,
546
545
  access_calculated_hash,
@@ -6,6 +6,7 @@ from typing import Dict, List, Union, Optional, Any
6
6
  import click
7
7
  import yaml
8
8
 
9
+ from data_pipeline_api.metadata import MetadataKey
9
10
  from data_pipeline_api.registry.common import (
10
11
  configure_cli_logging,
11
12
  DATA_REGISTRY_ACCESS_TOKEN,
@@ -61,7 +62,10 @@ def _parse_read_config(
61
62
 
62
63
 
63
64
  def download_from_configs(
64
- run_metadata: Dict[str, Any], read_configs: ReadConfigs, token: str, root_dir: Optional[Union[Path, str]] = None
65
+ run_metadata: Dict[str, Any],
66
+ read_configs: ReadConfigs,
67
+ token: str,
68
+ root_dir: Optional[Union[Path, str]] = None,
65
69
  ) -> None:
66
70
  """
67
71
  Iterates through the config read blocks and downloads the relevant data for each block
@@ -85,7 +89,10 @@ def download_from_configs(
85
89
  config = read_config["where"].copy()
86
90
  config.update(read_config.get("use", {}))
87
91
  downloader.add_external_object(
88
- config["doi_or_unique_name"], config.get("version")
92
+ config[MetadataKey.doi_or_unique_name],
93
+ config.get(MetadataKey.title),
94
+ config.get(MetadataKey.component),
95
+ config.get(MetadataKey.version),
89
96
  )
90
97
  else:
91
98
  parsed_config = _parse_read_config(
@@ -113,6 +120,8 @@ def download_from_config_file(config_filename: Union[Path, str], token: str) ->
113
120
  with open(config_filename, "r") as cf:
114
121
  config = yaml.safe_load(cf)
115
122
  run_metadata = config.get("run_metadata", {})
123
+ # Copy the top level data_directory into the run_metadata.
124
+ run_metadata[RunMetadata.data_directory] = config["data_directory"]
116
125
  read_configs = config.get("read")
117
126
  if not read_configs:
118
127
  raise ValueError("No read config specified in configuration file")
@@ -72,13 +72,15 @@ class Downloader:
72
72
  }
73
73
  )
74
74
 
75
- def add_external_object(self, doi_or_unique_name: str, version: Optional[str] = None) -> None:
75
+ def add_external_object(self, doi_or_unique_name: str, title: Optional[str] = None, component: Optional[str] = None, version: Optional[str] = None) -> None:
76
76
  """
77
77
  Registers an external object to be downloaded
78
78
  """
79
79
  self._external_objects.append(
80
80
  {
81
81
  (DataRegistryTarget.external_object, DataRegistryField.doi_or_unique_name): doi_or_unique_name,
82
+ (DataRegistryTarget.external_object, DataRegistryField.title): title,
83
+ (DataRegistryTarget.object_component, DataRegistryField.name): component,
82
84
  (DataRegistryTarget.external_object, DataRegistryField.version): version,
83
85
  }
84
86
  )
@@ -137,7 +139,7 @@ class Downloader:
137
139
  resolved = []
138
140
  for block in input_blocks:
139
141
  obj = None
140
- component = None if external else block.get((DataRegistryTarget.object_component, DataRegistryField.name))
142
+ component = block.get((DataRegistryTarget.object_component, DataRegistryField.name))
141
143
  target = DataRegistryTarget.external_object if external else DataRegistryTarget.data_product
142
144
  object_ref = block[target, DataRegistryField.object]
143
145
  if component:
@@ -176,11 +178,22 @@ class Downloader:
176
178
  next(iter(sort_by_semver(v, key=(DataRegistryTarget.data_product, DataRegistryField.version))))
177
179
  )
178
180
  else:
179
- versioned_blocks = input_blocks
181
+ grouped = defaultdict(list)
182
+ for block in input_blocks:
183
+ grouped[
184
+ block[DataRegistryTarget.external_object, DataRegistryField.doi_or_unique_name],
185
+ block[DataRegistryTarget.external_object, DataRegistryField.title],
186
+ block[DataRegistryTarget.object_component, DataRegistryField.name],
187
+ ].append(block)
188
+ versioned_blocks = []
189
+ for k, v in grouped.items():
190
+ versioned_blocks.append(
191
+ next(iter(sort_by_semver(v, key=(DataRegistryTarget.external_object, DataRegistryField.version))))
192
+ )
180
193
 
181
194
  resolved = []
182
195
  for block in versioned_blocks:
183
- cname = None if external else block.get((DataRegistryTarget.object_component, DataRegistryField.name))
196
+ cname = block.get((DataRegistryTarget.object_component, DataRegistryField.name))
184
197
  components = block[DataRegistryTarget.object, DataRegistryField.components]
185
198
  for component_url in components:
186
199
  cblock = block.copy()
@@ -203,11 +216,10 @@ class Downloader:
203
216
  for k, v in storage_location.items():
204
217
  cblock[DataRegistryTarget.storage_location, k] = v
205
218
  target = DataRegistryTarget.external_object if external else DataRegistryTarget.data_product
206
- name_field = DataRegistryField.doi_or_unique_name if external else DataRegistryField.name
207
- name = Path(cblock[target, name_field])
208
- version = cblock[target, DataRegistryField.version]
219
+ name_fields = (DataRegistryField.doi_or_unique_name, DataRegistryField.title, DataRegistryField.version) if external else (DataRegistryField.name, DataRegistryField.version)
220
+ name = Path("/".join(filter(None, (cblock.get((target, name_field)) for name_field in name_fields))))
209
221
  output_filename = (
210
- name / version / Path(cblock[DataRegistryTarget.storage_location, DataRegistryField.path]).name
222
+ name / Path(cblock[DataRegistryTarget.storage_location, DataRegistryField.path]).name
211
223
  )
212
224
  cblock[OUTPUT_FILENAME] = output_filename.as_posix()
213
225
  cblock[FULL_OUTPUT_FILENAME] = (self._data_directory / output_filename).as_posix()
@@ -238,17 +250,22 @@ class Downloader:
238
250
  version = block.get((DataRegistryTarget.external_object, DataRegistryField.version))
239
251
  if version is not None:
240
252
  query_data[DataRegistryField.version] = version
253
+ title = block.get((DataRegistryTarget.external_object, DataRegistryField.title))
254
+ if title is not None:
255
+ query_data[DataRegistryField.title] = title
241
256
  external_objects = get_data(
242
257
  query_data, DataRegistryTarget.external_object, self._data_registry_url, self._token, exact=False
243
258
  )
244
259
  if external_objects:
245
260
  external_objects = sort_by_semver(external_objects)
246
- grouped_external_objects = {}
247
- for external_object in external_objects:
248
- external_object_name = external_object[DataRegistryField.doi_or_unique_name]
249
- if external_object_name not in grouped_external_objects:
250
- grouped_external_objects[external_object_name] = external_object
251
- external_objects = list(grouped_external_objects.values())
261
+ if block.get((DataRegistryTarget.object_component, DataRegistryField.name)) is None:
262
+ grouped_external_objects = {}
263
+ for external_object in external_objects:
264
+ external_object_name = external_object[DataRegistryField.doi_or_unique_name]
265
+ external_object_title = external_object[DataRegistryField.title]
266
+ if (external_object_name, external_object_title) not in grouped_external_objects:
267
+ grouped_external_objects[external_object_name, external_object_title] = external_object
268
+ external_objects = list(grouped_external_objects.values())
252
269
  for external_object in external_objects:
253
270
  cblock = block.copy()
254
271
  for k, v in external_object.items():
@@ -280,6 +297,9 @@ class Downloader:
280
297
  MetadataKey.doi_or_unique_name: block[
281
298
  DataRegistryTarget.external_object, DataRegistryField.doi_or_unique_name
282
299
  ],
300
+ MetadataKey.title: block[
301
+ DataRegistryTarget.external_object, DataRegistryField.title
302
+ ],
283
303
  MetadataKey.accessibility: block[DataRegistryTarget.storage_root, DataRegistryField.accessibility],
284
304
  MetadataKey.version: block[DataRegistryTarget.external_object, DataRegistryField.version],
285
305
  MetadataKey.verified_hash: block[DataRegistryTarget.storage_location, DataRegistryField.hash],
@@ -5,7 +5,7 @@ from typing import Union, NamedTuple, Optional, Sequence, Type
5
5
  from data_pipeline_api.file_api import FileAPI, RunMetadata
6
6
  from data_pipeline_api.metadata import Metadata
7
7
  from data_pipeline_api.file_formats.parameter_file import (
8
- Type as ParameterType,
8
+ ParameterType,
9
9
  Estimate,
10
10
  Distribution,
11
11
  Samples,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.0
2
2
  Name: data-pipeline-api
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: Interacts with SCRC data pipeline
5
5
  Home-page: UNKNOWN
6
6
  Author: SCRC
@@ -97,6 +97,7 @@ java_api/standard_api/src/main/java/uk/ramp/distribution/MinMax.java
97
97
  java_api/standard_api/src/main/java/uk/ramp/distribution/MinMaxDeserializer.java
98
98
  java_api/standard_api/src/main/java/uk/ramp/distribution/MinMaxSerializer.java
99
99
  java_api/standard_api/src/main/java/uk/ramp/estimate/Estimate.java
100
+ java_api/standard_api/src/main/java/uk/ramp/mapper/DataPipelineMapper.java
100
101
  java_api/standard_api/src/main/java/uk/ramp/objects/NumericalArray.java
101
102
  java_api/standard_api/src/main/java/uk/ramp/objects/NumericalArrayImpl.java
102
103
  java_api/standard_api/src/main/java/uk/ramp/objects/StandardArrayDataReader.java
@@ -110,6 +111,8 @@ java_api/standard_api/src/main/java/uk/ramp/parameters/ParameterDataReader.java
110
111
  java_api/standard_api/src/main/java/uk/ramp/parameters/ParameterDataReaderImpl.java
111
112
  java_api/standard_api/src/main/java/uk/ramp/parameters/ParameterDataWriter.java
112
113
  java_api/standard_api/src/main/java/uk/ramp/parameters/ParameterDataWriterImpl.java
114
+ java_api/standard_api/src/main/java/uk/ramp/parameters/RandomGeneratorDeserializer.java
115
+ java_api/standard_api/src/main/java/uk/ramp/parameters/RandomGeneratorSerializer.java
113
116
  java_api/standard_api/src/main/java/uk/ramp/parameters/ReadComponent.java
114
117
  java_api/standard_api/src/main/java/uk/ramp/parameters/WriteComponent.java
115
118
  java_api/standard_api/src/main/java/uk/ramp/samples/Sampler.java
@@ -16,6 +16,7 @@ import uk.ramp.metadata.ImmutableMetadataItem;
16
16
  @JsonSerialize
17
17
  @JsonDeserialize
18
18
  public interface Config {
19
+
19
20
  @JsonProperty("data_directory")
20
21
  Optional<String> internalDataDirectory();
21
22
 
@@ -65,6 +65,8 @@ public interface MetadataItem {
65
65
 
66
66
  Optional<String> description();
67
67
 
68
+ Optional<String> accessibility();
69
+
68
70
  default boolean isSuperSetOf(MetadataItem key) {
69
71
  return List.<Function<MetadataItem, Optional<String>>>of(
70
72
  MetadataItem::internalFilename,
@@ -78,7 +80,8 @@ public interface MetadataItem {
78
80
  MetadataItem::source,
79
81
  metadataItem -> issuesInComparableFormat(metadataItem.issues().orElse(List.of())),
80
82
  MetadataItem::namespace,
81
- MetadataItem::description)
83
+ MetadataItem::description,
84
+ MetadataItem::accessibility)
82
85
  .stream()
83
86
  .map(func -> func.andThen(s -> s.orElse("")))
84
87
  .allMatch(func -> keyIsEitherNotPresentOrEqual(func.apply(key), func.apply(this)));
@@ -158,6 +161,10 @@ public interface MetadataItem {
158
161
  Function<MetadataItem, Boolean> isDataDirectoryPresent =
159
162
  meta -> meta.dataDirectory().isPresent();
160
163
  Function<MetadataItem, Boolean> isIssuesPresent = meta -> meta.issues().isPresent();
164
+ Function<MetadataItem, Boolean> isNamespacePresent = meta -> meta.namespace().isPresent();
165
+ Function<MetadataItem, Boolean> isDescriptionPresent = meta -> meta.description().isPresent();
166
+ Function<MetadataItem, Boolean> isAccessibilityPresent =
167
+ meta -> meta.accessibility().isPresent();
161
168
 
162
169
  if (shouldOverride.apply(isFilenamePresent)) {
163
170
  newMetadataItem =
@@ -205,14 +212,18 @@ public interface MetadataItem {
205
212
  newMetadataItem = newMetadataItem.withIssues(metadataOverride.issues().get());
206
213
  }
207
214
 
208
- if (metadataOverride.namespace().isPresent()) {
215
+ if (shouldOverride.apply(isNamespacePresent)) {
209
216
  newMetadataItem = newMetadataItem.withNamespace(metadataOverride.namespace().get());
210
217
  }
211
218
 
212
- if (metadataOverride.description().isPresent()) {
219
+ if (shouldOverride.apply(isDescriptionPresent)) {
213
220
  newMetadataItem = newMetadataItem.withDescription(metadataOverride.description().get());
214
221
  }
215
222
 
223
+ if (shouldOverride.apply(isAccessibilityPresent)) {
224
+ newMetadataItem = newMetadataItem.withAccessibility(metadataOverride.accessibility().get());
225
+ }
226
+
216
227
  return newMetadataItem;
217
228
  }
218
229
  }
@@ -1,5 +1,6 @@
1
1
  package uk.ramp.yaml;
2
2
 
3
+ import com.fasterxml.jackson.annotation.JsonInclude.Include;
3
4
  import com.fasterxml.jackson.databind.ObjectMapper;
4
5
  import com.fasterxml.jackson.databind.SerializationFeature;
5
6
  import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
@@ -19,7 +20,8 @@ public class BaseYamlWriter implements YamlWriter {
19
20
  .disable(Feature.WRITE_DOC_START_MARKER)
20
21
  .registerModule(new Jdk8Module())
21
22
  .registerModule(new JavaTimeModule())
22
- .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
23
+ .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
24
+ .setSerializationInclusion(Include.NON_DEFAULT);
23
25
  }
24
26
 
25
27
  @Override
@@ -89,7 +89,7 @@ public class FileApiIntegrationTest {
89
89
  fileHandle.write(buffer);
90
90
  fileApi.close();
91
91
 
92
- assertThat(Files.readString(Path.of(parentPath, "access-runId.yaml"))).contains("io: []");
92
+ assertThat(Files.readString(Path.of(parentPath, "access-runId.yaml"))).doesNotContain("io:");
93
93
  }
94
94
 
95
95
  @Test