h5rdmtoolbox 2.8.0__tar.gz → 2.8.2__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 (162) hide show
  1. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/PKG-INFO +32 -17
  2. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/README.md +28 -13
  3. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/core.py +68 -24
  4. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/generate.py +85 -20
  5. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/metrics.py +9 -0
  6. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/shacl.py +63 -20
  7. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/repository/interface.py +20 -23
  8. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/repository/utils.py +19 -27
  9. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/repository/zenodo/core.py +28 -27
  10. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/repository/zenodo/tokens.py +4 -0
  11. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/server/static/graph.css +222 -5
  12. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/server/static/graph.js +261 -29
  13. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/server/templates/graph.html +28 -10
  14. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/server.py +245 -36
  15. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/tutorial.py +6 -5
  16. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/user.py +14 -9
  17. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/utils/download.py +180 -26
  18. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/jsonld.py +67 -0
  19. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox.egg-info/PKG-INFO +32 -17
  20. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox.egg-info/SOURCES.txt +1 -0
  21. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox.egg-info/requires.txt +3 -3
  22. h5rdmtoolbox-2.8.2/h5rdmtoolbox_cli.py +353 -0
  23. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/pyproject.toml +4 -4
  24. h5rdmtoolbox-2.8.2/tests/test_cli.py +331 -0
  25. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_server.py +333 -3
  26. h5rdmtoolbox-2.8.2/tests/test_tutorial.py +18 -0
  27. h5rdmtoolbox-2.8.0/h5rdmtoolbox_cli.py +0 -168
  28. h5rdmtoolbox-2.8.0/tests/test_cli.py +0 -190
  29. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/LICENSE +0 -0
  30. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/__init__.py +0 -0
  31. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/_cfg.py +0 -0
  32. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/_repr.py +0 -0
  33. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/_version.py +0 -0
  34. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/catalog/__init__.py +0 -0
  35. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/catalog/_initialization.py +0 -0
  36. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/catalog/abstracts.py +0 -0
  37. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/catalog/core.py +0 -0
  38. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/catalog/profiles.py +0 -0
  39. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/catalog/query_templates.py +0 -0
  40. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/catalog/stores/__init__.py +0 -0
  41. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/catalog/stores/hdf5.py +0 -0
  42. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/catalog/utils.py +0 -0
  43. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/cli.py +0 -0
  44. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/consts.py +0 -0
  45. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/__init__.py +0 -0
  46. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/cfg.py +0 -0
  47. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/consts.py +0 -0
  48. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/errors.py +0 -0
  49. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/ontology/__init__.py +0 -0
  50. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/ontology/h5ontocls.py +0 -0
  51. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/ontology/hdf_datatypes.py +0 -0
  52. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/references.py +0 -0
  53. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/standard_attributes.py +0 -0
  54. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/toolbox_validators.py +0 -0
  55. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/convention/utils.py +0 -0
  56. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/def_icon.png +0 -0
  57. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/fluid-v1.yml +0 -0
  58. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/h5tbx.yaml +0 -0
  59. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/id_icon.png +0 -0
  60. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/iri_icon.png +0 -0
  61. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/ld_icon.png +0 -0
  62. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/piv-v1.yml +0 -0
  63. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/style.css +0 -0
  64. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/tutorial_convention.yaml +0 -0
  65. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/tutorial_convention_vfuncs.py +0 -0
  66. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/tutorial_standard_name_table.yaml +0 -0
  67. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/data/type_icon.png +0 -0
  68. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/database/__init__.py +0 -0
  69. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/database/hdfdb/__init__.py +0 -0
  70. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/database/hdfdb/filedb.py +0 -0
  71. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/database/hdfdb/objdb.py +0 -0
  72. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/database/hdfdb/query.py +0 -0
  73. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/database/hdfdb/utils.py +0 -0
  74. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/database/interface.py +0 -0
  75. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/database/lazy.py +0 -0
  76. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/database/mongo.py +0 -0
  77. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/errors.py +0 -0
  78. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/extensions/__init__.py +0 -0
  79. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/extensions/magnitude.py +0 -0
  80. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/extensions/normalize.py +0 -0
  81. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/extensions/onto.py +0 -0
  82. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/extensions/units.py +0 -0
  83. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/extensions/vector.py +0 -0
  84. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/gui/__init__.py +0 -0
  85. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/gui/fairify.py +0 -0
  86. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/gui/src/__init__.py +0 -0
  87. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/gui/src/main.py +0 -0
  88. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/identifiers.py +0 -0
  89. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/layout/__init__.py +0 -0
  90. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/layout/core.py +0 -0
  91. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/__init__.py +0 -0
  92. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/_types.py +0 -0
  93. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/globals.py +0 -0
  94. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/hdf/__init__.py +0 -0
  95. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/hdf/attributes.py +0 -0
  96. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/hdf/datasets.py +0 -0
  97. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/hdf/file.py +0 -0
  98. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/hdf/groups.py +0 -0
  99. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/rdf.py +0 -0
  100. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/sparql.py +0 -0
  101. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/user/__init__.py +0 -0
  102. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/user/attributes.py +0 -0
  103. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/user/datasets.py +0 -0
  104. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/user/file.py +0 -0
  105. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/user/groups.py +0 -0
  106. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/user/utils.py +0 -0
  107. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/ld/utils.py +0 -0
  108. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/__init__.py +0 -0
  109. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/chat.py +0 -0
  110. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/errors.py +0 -0
  111. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/executor.py +0 -0
  112. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/interfaces.py +0 -0
  113. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/models.py +0 -0
  114. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/ontology.py +0 -0
  115. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/prompting.py +0 -0
  116. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/providers/__init__.py +0 -0
  117. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/providers/openai_adapter.py +0 -0
  118. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/sparql_guard.py +0 -0
  119. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/llm/summary.py +0 -0
  120. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/plotting.py +0 -0
  121. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/protected_attributes.py +0 -0
  122. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/protocols.py +0 -0
  123. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/repository/__init__.py +0 -0
  124. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/repository/default_metamapper.py +0 -0
  125. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/repository/zenodo/__init__.py +0 -0
  126. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/repository/zenodo/metadata.py +0 -0
  127. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/repository/zenodo/utils.py +0 -0
  128. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/server/static/style.css +0 -0
  129. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/server/templates/file.html +0 -0
  130. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/server/templates/index.html +0 -0
  131. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/server/templates/resource.html +0 -0
  132. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/utils/__init__.py +0 -0
  133. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/utils/docstring.py +0 -0
  134. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/utils/file_io.py +0 -0
  135. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/utils/hdf5.py +0 -0
  136. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/utils/string.py +0 -0
  137. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/utils.py +0 -0
  138. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/__init__.py +0 -0
  139. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/accessor.py +0 -0
  140. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/accessors/__init__.py +0 -0
  141. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/accessors/provenance.py +0 -0
  142. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/core.py +0 -0
  143. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/ds_decoder.py +0 -0
  144. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/h5attr.py +0 -0
  145. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/h5ext.py +0 -0
  146. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/h5utils.py +0 -0
  147. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/h5yaml.py +0 -0
  148. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox/wrapper/xr2hdf.py +0 -0
  149. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox.egg-info/dependency_links.txt +0 -0
  150. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox.egg-info/entry_points.txt +0 -0
  151. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/h5rdmtoolbox.egg-info/top_level.txt +0 -0
  152. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/setup.cfg +0 -0
  153. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_config.py +0 -0
  154. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_extensions.py +0 -0
  155. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_identifiers.py +0 -0
  156. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_plotting.py +0 -0
  157. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_readme.py +0 -0
  158. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_repr.py +0 -0
  159. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_user.py +0 -0
  160. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_utils.py +0 -0
  161. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_version.py +0 -0
  162. {h5rdmtoolbox-2.8.0 → h5rdmtoolbox-2.8.2}/tests/test_xarray_export.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: h5rdmtoolbox
3
- Version: 2.8.0
3
+ Version: 2.8.2
4
4
  Summary: Supporting a FAIR Research Data lifecycle using Python and HDF5.
5
5
  Author-email: Matthias Probst <matth.probst@gmail.com>
6
6
  License-Expression: MIT
@@ -37,11 +37,11 @@ Requires-Dist: python-forge==18.6.0
37
37
  Requires-Dist: requests>=2.32.4
38
38
  Requires-Dist: pydantic~=2.8
39
39
  Requires-Dist: rdflib~=7.1
40
- Requires-Dist: click>=8.1.7
40
+ Requires-Dist: typer>=0.12
41
41
  Requires-Dist: cftime>=1.6.4
42
42
  Requires-Dist: pyshacl<1.0.0,>=0.30.1
43
43
  Provides-Extra: database
44
- Requires-Dist: pymongo<=4.10.1,>=4.2.0; extra == "database"
44
+ Requires-Dist: pymongo<=4.10.1,>=4.6.3; extra == "database"
45
45
  Provides-Extra: layout-validation
46
46
  Requires-Dist: tabulate<=0.9.0,>=0.8.10; extra == "layout-validation"
47
47
  Provides-Extra: csv
@@ -81,7 +81,7 @@ Requires-Dist: h5rdmtoolbox[complete,docs]; extra == "complete-with-docs"
81
81
  Provides-Extra: server
82
82
  Requires-Dist: fastapi>=0.95; extra == "server"
83
83
  Requires-Dist: uvicorn[standard]>=0.22; extra == "server"
84
- Requires-Dist: jinja2>=3.1; extra == "server"
84
+ Requires-Dist: jinja2>=3.1.6; extra == "server"
85
85
  Dynamic: license-file
86
86
 
87
87
  # HDF5 Research Data Management Toolbox
@@ -91,6 +91,7 @@ Dynamic: license-file
91
91
  [![Documentation Status](https://readthedocs.org/projects/h5rdmtoolbox/badge/?version=latest)](https://h5rdmtoolbox.readthedocs.io/en/latest/?badge=latest)
92
92
  [![PyPI version](https://badge.fury.io/py/h5RDMtoolbox.svg)](https://badge.fury.io/py/h5RDMtoolbox)
93
93
  ![pyvers](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)
94
+ [![Paper](https://img.shields.io/badge/Paper-View-green?style=flat&logo=adobeacrobatreader)](https://preprints.inggrid.org/repository/view/23/)
94
95
 
95
96
  A Python package that helps researchers achieve sustainable
96
97
  [**FAIR (Findable, Accessible, Interoperable, Reusable)**](https://www.nature.com/articles/sdata201618) data management with HDF5 files. The toolbox provides a comprehensive
@@ -169,7 +170,7 @@ Below we show the first two serializations.
169
170
  schema:description "Room temperature measurements" .
170
171
  ```
171
172
 
172
- `ttl_ctx`:
173
+ `ttl_struc`:
173
174
  ```ttl
174
175
  @prefix hdf: <http://purl.allotrope.org/ontologies/hdf5/1.8#> .
175
176
  @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@@ -255,8 +256,14 @@ To inspect files in a browser, run:
255
256
  h5tbx serve example.h5
256
257
  h5tbx serve data/ --h5ext=.h5 --h5ext=.hdf5
257
258
  ```
259
+ This allows you to serve a single HDF5 file or a directory of HDF5 files, and view their metadata and structure in a web interface.
260
+
261
+ You may perform SPARQL queries or view the file as a graph, as shown below:
262
+
263
+ <p align="center">
264
+ <img src="docs/_static/screenshot-served-hdf5-as-graph.png" alt="Serve UI screenshot" width="640">
265
+ </p>
258
266
 
259
- The local web app links to Turtle, JSON-LD, N-Triples, RDF/XML, an interactive graph view, SPARQL query editor, graph metrics, and SHACL validation. Per-file buttons are scoped to that file; the landing page also offers a separate combined graph section for all served files plus loaded enrichment. Combined graph visualization is reduced by default with node/edge limits and search controls, and combined metrics skip exact largest-distance computation on very large graphs to keep the local server responsive. HDF5 object URLs such as `/example.h5/group/dataset` dereference to a browser HTML page by default, while `Accept: text/turtle`, `Accept: application/ld+json`, or `?format=ttl|jsonld|nt|xml|html` return the requested representation. For published DOI-style file URIs, use `/resolve?iri=https://doi.org/...%23path` to resolve an exact external RDF subject locally. The resolver uses the first matching served HDF5 subject, caches all served files in one shared query graph, and enriches that graph with known ontology TTL sources, QUDT unit definitions, Zenodo RDF attachments, generic ontology documents, and Wikidata direct claims where applicable. URI values in resource pages link back into `/resolve?iri=...` so browsing stays inside the local app; if a browser request cannot be resolved locally, the app opens the original IRI in a new tab as a fallback. `h5tbx serve` accepts files and folders; folder discovery uses `.h5`, `.hdf`, and `.hdf5` by default, or repeated `--h5ext` values. `--local-iri-pattern` is optional and only limits which external IRIs get local resolver links in the graph view. If no filename is provided, `h5tbx serve` lists all matching HDF5 files in the current directory.
260
267
 
261
268
  The same graph metrics are available from Python:
262
269
 
@@ -312,7 +319,7 @@ module implements the main interface between the user and the HDF5 file. It
312
319
  extends the features of the underlying `h5py` library. Some of the features are implemented in other modules, hence the
313
320
  wrapper module depends on the convention, database and linked data (ld) module.
314
321
 
315
- <a href="https://h5rdmtoolbox.readthedocs.io/en/latest/"><img src="docs/_static/h5tbx_modules.svg" alt="H5TBX modules" style="widht:600px;"></a>
322
+ <a href="https://h5rdmtoolbox.readthedocs.io/en/latest/"><img src="docs/_static/h5tbx_modules.svg" alt="H5TBX modules" style="width:600px;"></a>
316
323
 
317
324
  Current implementation highlights in the modules:
318
325
 
@@ -326,7 +333,7 @@ Current implementation highlights in the modules:
326
333
  - For the **repository** module, a Zenodo interface is implemented. Zenodo is a repository, which allows to upload and
327
334
  download data with a persistent identifier.
328
335
  - For the **convention** module,
329
- the [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/conventions/standard_attributes_and_conventions.html)
336
+ the [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/userguide/convention/index.html)
330
337
  are implemented.
331
338
  - The **layout** module allows to define expectations on the internal layout (object names, location, attributes,
332
339
  properties) of HDF5 files.
@@ -350,7 +357,7 @@ A paper is published in the journal [inggrid](https://preprints.inggrid.org/repo
350
357
 
351
358
  ## Installation
352
359
 
353
- Use python 3.9 or higher (automatic testing is performed until 3.13). If you are a regular user, you can install the
360
+ Use Python 3.9 through 3.13. If you are a regular user, you can install the
354
361
  package via pip:
355
362
 
356
363
  pip install h5RDMtoolbox
@@ -359,7 +366,7 @@ package via pip:
359
366
 
360
367
  Developers may clone the repository and install the package from source. Clone the repository first:
361
368
 
362
- git clone https://github.com/matthiasprobst/h5RDMtoolbox.git@main
369
+ git clone --branch main https://github.com/matthiasprobst/h5RDMtoolbox.git
363
370
 
364
371
  Then, run
365
372
 
@@ -381,6 +388,7 @@ specific to the features of the package:
381
388
  - `numpy`: Scientific computing, handling of arrays
382
389
  - `matplotlib`: Plotting
383
390
  - `appdirs`: Managing user and application directories
391
+ - `importlib_resources`: Accessing package resources consistently
384
392
  - `packaging`: Version handling
385
393
  - `IPython`: Pretty display of data in notebooks
386
394
  - `regex`: Working with regular expressions
@@ -393,14 +401,17 @@ specific to the features of the package:
393
401
  - `pint`: Allows working with units
394
402
  - `pint_xarray`: Working with units for usage with xarray
395
403
  - `python-forge`: Used to update function signatures when using
396
- the [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/conventions/standard_attributes_and_conventions.html)
404
+ the [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/userguide/convention/index.html)
397
405
  - `pydantic`: Used to
398
- validate [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/conventions/standard_attributes_and_conventions.html)
406
+ validate [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/userguide/convention/index.html)
399
407
  - `pyyaml`: Reading and writing of yaml files, e.g. metadata definitions (conventions). Note, lower versions
400
408
  collide with python 3.11
401
409
  - `requests`: Used to download files from the internet or validate URLs, e.g. metadata definitions (conventions)
402
410
  - `rdflib`: Used to enable working with RDF
403
411
  - `ontolutils`: Required to work with RDF and derive semantic description of HDF5 file content
412
+ - `cftime`: Handling non-standard calendars and time coordinates
413
+ - `pyshacl`: Validating RDF graphs against SHACL shapes
414
+ - `typer`: Providing the `h5tbx` command-line interface
404
415
 
405
416
  #### Optional dependencies
406
417
 
@@ -408,9 +419,9 @@ To run unit tests or to enable certain features, additional dependencies must be
408
419
 
409
420
  Install optional dependencies by specifying them in square brackets after the package name, e.g.:
410
421
 
411
- pip install h5RDMtoolbox[mongodb]
422
+ pip install h5RDMtoolbox[database]
412
423
 
413
- [mongodb]
424
+ [database]
414
425
 
415
426
  - `pymongo`: Database solution for HDF5 files
416
427
 
@@ -425,6 +436,10 @@ Install optional dependencies by specifying them in square brackets after the pa
425
436
  - `python-gitlab`: Access to gitlab repositories
426
437
  - `pypandoc`: Conversion of markdown files to html
427
438
 
439
+ Other supported extras are `layout_validation`, `catalog`, `gui`, `server`, `test`, `docs`, `complete`, and
440
+ `complete-with-docs`. See the [installation guide](https://h5rdmtoolbox.readthedocs.io/en/latest/gettingstarted/installation.html)
441
+ for their purpose. The authoritative dependency lists and version constraints are in [`pyproject.toml`](./pyproject.toml).
442
+
428
443
  ## Citing the package
429
444
 
430
445
  If you intend to use the package in your work, you may cite the software itself as published on paper in the
@@ -457,10 +472,10 @@ Here is the BibTeX entry:
457
472
  Feel free to contribute. Make sure to write `docstrings` to your methods and classes and please write tests and use PEP
458
473
  8 (https://peps.python.org/pep-0008/)
459
474
 
460
- Please write tests for your code and put them into the `test/` folder. Visit the [README file](./tests/README.md) in the
461
- test-folder for more information.
475
+ Please write tests for your code and put them into the `tests/` folder. Visit the [README file](./tests/README.md) in the
476
+ tests folder for more information.
462
477
 
463
- Pleas also add a jupyter notebook in the `docs/` folder in order to document your code. Please visit
478
+ Please also add a Jupyter notebook in the `docs/` folder in order to document your code. Please visit
464
479
  the [README file](./docs/README.md) in the docs-folder for more information on how to compile the documentation.
465
480
 
466
481
  Please use the **numpy style for the docstrings**:
@@ -5,6 +5,7 @@
5
5
  [![Documentation Status](https://readthedocs.org/projects/h5rdmtoolbox/badge/?version=latest)](https://h5rdmtoolbox.readthedocs.io/en/latest/?badge=latest)
6
6
  [![PyPI version](https://badge.fury.io/py/h5RDMtoolbox.svg)](https://badge.fury.io/py/h5RDMtoolbox)
7
7
  ![pyvers](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)
8
+ [![Paper](https://img.shields.io/badge/Paper-View-green?style=flat&logo=adobeacrobatreader)](https://preprints.inggrid.org/repository/view/23/)
8
9
 
9
10
  A Python package that helps researchers achieve sustainable
10
11
  [**FAIR (Findable, Accessible, Interoperable, Reusable)**](https://www.nature.com/articles/sdata201618) data management with HDF5 files. The toolbox provides a comprehensive
@@ -83,7 +84,7 @@ Below we show the first two serializations.
83
84
  schema:description "Room temperature measurements" .
84
85
  ```
85
86
 
86
- `ttl_ctx`:
87
+ `ttl_struc`:
87
88
  ```ttl
88
89
  @prefix hdf: <http://purl.allotrope.org/ontologies/hdf5/1.8#> .
89
90
  @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@@ -169,8 +170,14 @@ To inspect files in a browser, run:
169
170
  h5tbx serve example.h5
170
171
  h5tbx serve data/ --h5ext=.h5 --h5ext=.hdf5
171
172
  ```
173
+ This allows you to serve a single HDF5 file or a directory of HDF5 files, and view their metadata and structure in a web interface.
174
+
175
+ You may perform SPARQL queries or view the file as a graph, as shown below:
176
+
177
+ <p align="center">
178
+ <img src="docs/_static/screenshot-served-hdf5-as-graph.png" alt="Serve UI screenshot" width="640">
179
+ </p>
172
180
 
173
- The local web app links to Turtle, JSON-LD, N-Triples, RDF/XML, an interactive graph view, SPARQL query editor, graph metrics, and SHACL validation. Per-file buttons are scoped to that file; the landing page also offers a separate combined graph section for all served files plus loaded enrichment. Combined graph visualization is reduced by default with node/edge limits and search controls, and combined metrics skip exact largest-distance computation on very large graphs to keep the local server responsive. HDF5 object URLs such as `/example.h5/group/dataset` dereference to a browser HTML page by default, while `Accept: text/turtle`, `Accept: application/ld+json`, or `?format=ttl|jsonld|nt|xml|html` return the requested representation. For published DOI-style file URIs, use `/resolve?iri=https://doi.org/...%23path` to resolve an exact external RDF subject locally. The resolver uses the first matching served HDF5 subject, caches all served files in one shared query graph, and enriches that graph with known ontology TTL sources, QUDT unit definitions, Zenodo RDF attachments, generic ontology documents, and Wikidata direct claims where applicable. URI values in resource pages link back into `/resolve?iri=...` so browsing stays inside the local app; if a browser request cannot be resolved locally, the app opens the original IRI in a new tab as a fallback. `h5tbx serve` accepts files and folders; folder discovery uses `.h5`, `.hdf`, and `.hdf5` by default, or repeated `--h5ext` values. `--local-iri-pattern` is optional and only limits which external IRIs get local resolver links in the graph view. If no filename is provided, `h5tbx serve` lists all matching HDF5 files in the current directory.
174
181
 
175
182
  The same graph metrics are available from Python:
176
183
 
@@ -226,7 +233,7 @@ module implements the main interface between the user and the HDF5 file. It
226
233
  extends the features of the underlying `h5py` library. Some of the features are implemented in other modules, hence the
227
234
  wrapper module depends on the convention, database and linked data (ld) module.
228
235
 
229
- <a href="https://h5rdmtoolbox.readthedocs.io/en/latest/"><img src="docs/_static/h5tbx_modules.svg" alt="H5TBX modules" style="widht:600px;"></a>
236
+ <a href="https://h5rdmtoolbox.readthedocs.io/en/latest/"><img src="docs/_static/h5tbx_modules.svg" alt="H5TBX modules" style="width:600px;"></a>
230
237
 
231
238
  Current implementation highlights in the modules:
232
239
 
@@ -240,7 +247,7 @@ Current implementation highlights in the modules:
240
247
  - For the **repository** module, a Zenodo interface is implemented. Zenodo is a repository, which allows to upload and
241
248
  download data with a persistent identifier.
242
249
  - For the **convention** module,
243
- the [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/conventions/standard_attributes_and_conventions.html)
250
+ the [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/userguide/convention/index.html)
244
251
  are implemented.
245
252
  - The **layout** module allows to define expectations on the internal layout (object names, location, attributes,
246
253
  properties) of HDF5 files.
@@ -264,7 +271,7 @@ A paper is published in the journal [inggrid](https://preprints.inggrid.org/repo
264
271
 
265
272
  ## Installation
266
273
 
267
- Use python 3.9 or higher (automatic testing is performed until 3.13). If you are a regular user, you can install the
274
+ Use Python 3.9 through 3.13. If you are a regular user, you can install the
268
275
  package via pip:
269
276
 
270
277
  pip install h5RDMtoolbox
@@ -273,7 +280,7 @@ package via pip:
273
280
 
274
281
  Developers may clone the repository and install the package from source. Clone the repository first:
275
282
 
276
- git clone https://github.com/matthiasprobst/h5RDMtoolbox.git@main
283
+ git clone --branch main https://github.com/matthiasprobst/h5RDMtoolbox.git
277
284
 
278
285
  Then, run
279
286
 
@@ -295,6 +302,7 @@ specific to the features of the package:
295
302
  - `numpy`: Scientific computing, handling of arrays
296
303
  - `matplotlib`: Plotting
297
304
  - `appdirs`: Managing user and application directories
305
+ - `importlib_resources`: Accessing package resources consistently
298
306
  - `packaging`: Version handling
299
307
  - `IPython`: Pretty display of data in notebooks
300
308
  - `regex`: Working with regular expressions
@@ -307,14 +315,17 @@ specific to the features of the package:
307
315
  - `pint`: Allows working with units
308
316
  - `pint_xarray`: Working with units for usage with xarray
309
317
  - `python-forge`: Used to update function signatures when using
310
- the [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/conventions/standard_attributes_and_conventions.html)
318
+ the [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/userguide/convention/index.html)
311
319
  - `pydantic`: Used to
312
- validate [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/conventions/standard_attributes_and_conventions.html)
320
+ validate [standard attributes](https://h5rdmtoolbox.readthedocs.io/en/latest/userguide/convention/index.html)
313
321
  - `pyyaml`: Reading and writing of yaml files, e.g. metadata definitions (conventions). Note, lower versions
314
322
  collide with python 3.11
315
323
  - `requests`: Used to download files from the internet or validate URLs, e.g. metadata definitions (conventions)
316
324
  - `rdflib`: Used to enable working with RDF
317
325
  - `ontolutils`: Required to work with RDF and derive semantic description of HDF5 file content
326
+ - `cftime`: Handling non-standard calendars and time coordinates
327
+ - `pyshacl`: Validating RDF graphs against SHACL shapes
328
+ - `typer`: Providing the `h5tbx` command-line interface
318
329
 
319
330
  #### Optional dependencies
320
331
 
@@ -322,9 +333,9 @@ To run unit tests or to enable certain features, additional dependencies must be
322
333
 
323
334
  Install optional dependencies by specifying them in square brackets after the package name, e.g.:
324
335
 
325
- pip install h5RDMtoolbox[mongodb]
336
+ pip install h5RDMtoolbox[database]
326
337
 
327
- [mongodb]
338
+ [database]
328
339
 
329
340
  - `pymongo`: Database solution for HDF5 files
330
341
 
@@ -339,6 +350,10 @@ Install optional dependencies by specifying them in square brackets after the pa
339
350
  - `python-gitlab`: Access to gitlab repositories
340
351
  - `pypandoc`: Conversion of markdown files to html
341
352
 
353
+ Other supported extras are `layout_validation`, `catalog`, `gui`, `server`, `test`, `docs`, `complete`, and
354
+ `complete-with-docs`. See the [installation guide](https://h5rdmtoolbox.readthedocs.io/en/latest/gettingstarted/installation.html)
355
+ for their purpose. The authoritative dependency lists and version constraints are in [`pyproject.toml`](./pyproject.toml).
356
+
342
357
  ## Citing the package
343
358
 
344
359
  If you intend to use the package in your work, you may cite the software itself as published on paper in the
@@ -371,10 +386,10 @@ Here is the BibTeX entry:
371
386
  Feel free to contribute. Make sure to write `docstrings` to your methods and classes and please write tests and use PEP
372
387
  8 (https://peps.python.org/pep-0008/)
373
388
 
374
- Please write tests for your code and put them into the `test/` folder. Visit the [README file](./tests/README.md) in the
375
- test-folder for more information.
389
+ Please write tests for your code and put them into the `tests/` folder. Visit the [README file](./tests/README.md) in the
390
+ tests folder for more information.
376
391
 
377
- Pleas also add a jupyter notebook in the `docs/` folder in order to document your code. Please visit
392
+ Please also add a Jupyter notebook in the `docs/` folder in order to document your code. Please visit
378
393
  the [README file](./docs/README.md) in the docs-folder for more information on how to compile the documentation.
379
394
 
380
395
  Please use the **numpy style for the docstrings**:
@@ -306,7 +306,10 @@ class Convention(AbstractConvention):
306
306
 
307
307
  @classmethod
308
308
  def from_yaml(
309
- cls, yaml_filename: Union[str, pathlib.Path], overwrite: bool = False
309
+ cls,
310
+ yaml_filename: Union[str, pathlib.Path],
311
+ overwrite: bool = False,
312
+ allow_python_validators: bool = True,
310
313
  ):
311
314
  """Create a convention from a yaml file.
312
315
  The YAML file must have the following structure:
@@ -333,6 +336,8 @@ class Convention(AbstractConvention):
333
336
  path to the yaml file
334
337
  overwrite: bool
335
338
  if True, overwrite an existing (registered) convention with the same name
339
+ allow_python_validators: bool
340
+ Whether to copy and execute an adjacent ``*_vfuncs.py`` module.
336
341
 
337
342
  Returns
338
343
  -------
@@ -364,8 +369,10 @@ class Convention(AbstractConvention):
364
369
  f'YAML file {yaml_filename} does not contain "__contact__". Is the file a valid convention?'
365
370
  )
366
371
 
372
+ from . import generate
373
+
367
374
  # check if name already exists!
368
- convention_name = attrs["__name__"].lower().replace("-", "_")
375
+ convention_name = generate.normalize_convention_name(attrs["__name__"])
369
376
  if convention_name in [d.name for d in CV_DIR.glob("*")]:
370
377
  if not overwrite:
371
378
  return _get_convention_from_dir(attrs["__name__"])
@@ -375,10 +382,10 @@ class Convention(AbstractConvention):
375
382
  f'Convention exists and overwrite is True: Deleting convention "{convention_name}"'
376
383
  )
377
384
 
378
- from . import generate
379
-
380
385
  generate.write_convention_module_from_yaml(
381
- yaml_filename, name=attrs["__name__"]
386
+ yaml_filename,
387
+ name=attrs["__name__"],
388
+ allow_python_validators=allow_python_validators,
382
389
  )
383
390
 
384
391
  # add_convention(yaml_filename, name=attrs['__name__'])
@@ -504,9 +511,6 @@ class Convention(AbstractConvention):
504
511
  """
505
512
  from ..wrapper.core import File
506
513
 
507
- if not isinstance(file_or_filename, (str, pathlib.Path)):
508
- with File(file_or_filename, "r") as f:
509
- return self.check(f)
510
514
  failed = []
511
515
 
512
516
  convention = self
@@ -575,13 +579,19 @@ class Convention(AbstractConvention):
575
579
  )
576
580
  )
577
581
 
578
- with File(file_or_filename, "r") as f:
582
+ def _validate_file(f):
579
583
  logger.debug(
580
584
  f"Checking file {file_or_filename} for compliance with convention {self.name}"
581
585
  )
582
586
  _validate_convention("/", f)
583
587
  f.visititems(_validate_convention)
584
588
 
589
+ if isinstance(file_or_filename, (str, pathlib.Path)):
590
+ with File(file_or_filename, "r") as f:
591
+ _validate_file(f)
592
+ else:
593
+ _validate_file(file_or_filename)
594
+
585
595
  return failed
586
596
 
587
597
 
@@ -621,8 +631,9 @@ def _import_convention(convention_name) -> "module":
621
631
 
622
632
 
623
633
  def _get_convention_from_dir(convention_name: str) -> "Convention":
624
- _convention_name = convention_name.lower().replace("-", "_")
625
- assert "-" not in _convention_name
634
+ from .generate import normalize_convention_name
635
+
636
+ _convention_name = normalize_convention_name(convention_name)
626
637
  if _convention_name in get_registered_conventions():
627
638
  return get_registered_conventions()[convention_name]
628
639
  _convention_py_filename = CV_DIR / f"{_convention_name}" / f"{_convention_name}.py"
@@ -799,19 +810,22 @@ def delete(convention: Union[str, Convention]):
799
810
  convention_name = convention.name
800
811
  else:
801
812
  convention_name = convention
802
- cv_dir = CV_DIR / convention_name
813
+ from .generate import normalize_convention_name
814
+
815
+ safe_convention_name = normalize_convention_name(convention_name)
816
+ cv_dir = CV_DIR / safe_convention_name
803
817
  if cv_dir.exists():
804
- shutil.rmtree(CV_DIR / convention_name)
818
+ shutil.rmtree(cv_dir)
805
819
  cfg._registered_conventions.pop(convention_name, None)
806
820
  if convention_name in sys.modules:
807
821
  # if the convention (py script) already has been imported, remove it from the list of imported modules:
808
822
  del sys.modules[convention_name]
809
823
 
810
824
 
811
- def from_file(filename) -> Convention:
825
+ def from_file(filename, allow_python_validators: bool = True) -> Convention:
812
826
  """Load a convention from a file. Currently yaml and json files are supported"""
813
827
  if filename.suffix == ".yaml":
814
- return from_yaml(filename)
828
+ return from_yaml(filename, allow_python_validators=allow_python_validators)
815
829
  elif filename.suffix == ".json":
816
830
  return from_json(filename)
817
831
  else:
@@ -819,11 +833,17 @@ def from_file(filename) -> Convention:
819
833
 
820
834
 
821
835
  def from_yaml(
822
- filename: Union[str, pathlib.Path], overwrite: bool = False
836
+ filename: Union[str, pathlib.Path],
837
+ overwrite: bool = False,
838
+ allow_python_validators: bool = True,
823
839
  ) -> Convention:
824
840
  """Load a convention from a YAML file. See Convention.from_yaml() for details"""
825
841
  logger.debug(f"Reading Convention from yaml file: {filename}")
826
- return Convention.from_yaml(filename, overwrite=overwrite)
842
+ return Convention.from_yaml(
843
+ filename,
844
+ overwrite=overwrite,
845
+ allow_python_validators=allow_python_validators,
846
+ )
827
847
 
828
848
 
829
849
  def from_json(
@@ -833,7 +853,11 @@ def from_json(
833
853
  return Convention.from_json(filename, overwrite=overwrite)
834
854
 
835
855
 
836
- def from_repo(repo_interface: RepositoryInterface, name: str):
856
+ def from_repo(
857
+ repo_interface: RepositoryInterface,
858
+ name: str,
859
+ allow_python_validators: bool = False,
860
+ ):
837
861
  """Download a YAML file from a repository
838
862
 
839
863
  Parameters
@@ -842,6 +866,9 @@ def from_repo(repo_interface: RepositoryInterface, name: str):
842
866
  The repository interface to use for downloading the file
843
867
  name: str
844
868
  Name of the file to download
869
+ allow_python_validators: bool
870
+ Whether to download and execute a repository-provided ``*_vfuncs.py``
871
+ file. Disabled by default because it is executable code.
845
872
  """
846
873
  logger.debug(f"Downloading file {name} from repository {repo_interface}")
847
874
 
@@ -849,19 +876,20 @@ def from_repo(repo_interface: RepositoryInterface, name: str):
849
876
  _suffix = pathlib.Path(name).suffix
850
877
  vfunc_filename = name.split(_suffix, 1)
851
878
  has_vfunc = False
852
- if len(vfunc_filename) == 2:
879
+ downloaded_vfunc_filename = None
880
+ if allow_python_validators and len(vfunc_filename) == 2:
853
881
  vfunc_filename = f"{vfunc_filename[0]}_vfuncs.py"
854
882
  try:
855
883
  downloaded_vfunc_filename = repo_interface.download_file(vfunc_filename)
856
884
  has_vfunc = True
857
885
  except Exception as e:
858
886
  logger.debug(f"No vfuncs file found for {name}: {e}")
859
- if has_vfunc:
887
+ if has_vfunc and downloaded_vfunc_filename is not None:
860
888
  shutil.copy(
861
889
  downloaded_vfunc_filename, filename.parent / downloaded_vfunc_filename.name
862
890
  )
863
891
  logger.debug(f"File downloaded to {filename}. Now loading convention from file.")
864
- return from_file(filename)
892
+ return from_file(filename, allow_python_validators=allow_python_validators)
865
893
 
866
894
 
867
895
  def from_zenodo(
@@ -869,6 +897,7 @@ def from_zenodo(
869
897
  name: str = None,
870
898
  overwrite: bool = False,
871
899
  force_download: bool = False,
900
+ allow_python_validators: bool = False,
872
901
  ) -> Convention:
873
902
  """Download a YAML file from a zenodo repository
874
903
 
@@ -885,6 +914,9 @@ def from_zenodo(
885
914
  Whether to overwrite existing convention with the same name. Default is False
886
915
  force_download: bool
887
916
  Whether to force download the file even if it is already cached. Default is False
917
+ allow_python_validators: bool
918
+ Whether to download and execute repository-provided validator Python.
919
+ Disabled by default.
888
920
 
889
921
  Returns
890
922
  -------
@@ -910,10 +942,18 @@ def from_zenodo(
910
942
  yaml_matches = [
911
943
  file for file in filenames if pathlib.Path(file).suffix == ".yaml"
912
944
  ]
913
- vfuns_matches = [file for file in filenames if file.endswith("vfuncs.py")]
945
+ vfuns_matches = (
946
+ [file for file in filenames if file.endswith("vfuncs.py")]
947
+ if allow_python_validators
948
+ else []
949
+ )
914
950
  else:
915
951
  yaml_matches = [file for file in filenames if file == name]
916
- vfuns_matches = [file for file in filenames if file == f"{name}_vfuncs.py"]
952
+ vfuns_matches = (
953
+ [file for file in filenames if file == f"{name}_vfuncs.py"]
954
+ if allow_python_validators
955
+ else []
956
+ )
917
957
  if len(yaml_matches) == 0:
918
958
  raise ValueError(
919
959
  f'No file with name "{name}" found in record {doi_or_recid}'
@@ -927,7 +967,11 @@ def from_zenodo(
927
967
  )
928
968
  shutil.move(_filename, match)
929
969
 
930
- return from_yaml(yaml_matches[0], overwrite=overwrite)
970
+ return from_yaml(
971
+ yaml_matches[0],
972
+ overwrite=overwrite,
973
+ allow_python_validators=allow_python_validators,
974
+ )
931
975
 
932
976
 
933
977
  def yaml2jsonld(