bam-masterdata 0.4.0__tar.gz → 0.4.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 (131) hide show
  1. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/.vscode/settings.json +1 -1
  2. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/PKG-INFO +1 -1
  3. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/_version.py +2 -2
  4. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/checker/checker.py +1 -1
  5. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/checker/masterdata_validator.py +6 -6
  6. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/cli/cli.py +54 -43
  7. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/excel/excel_to_entities.py +49 -34
  8. bam_masterdata-0.4.2/bam_masterdata/validation_rules/all_validation_rules.json +76 -0
  9. bam_masterdata-0.4.2/bam_masterdata/validation_rules/validation_rules.json +109 -0
  10. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata.egg-info/PKG-INFO +1 -1
  11. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata.egg-info/SOURCES.txt +1 -0
  12. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/excel/test_excel_to_entities.py +2 -104
  13. bam_masterdata-0.4.0/bam_masterdata/validation_rules/validation_rules.json +0 -0
  14. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/.coveragerc +0 -0
  15. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/.github/workflows/actions.yml +0 -0
  16. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/.github/workflows/coveralls.yml +0 -0
  17. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/.github/workflows/mkdocs-deploy.yml +0 -0
  18. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/.github/workflows/publish.yml +0 -0
  19. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/.gitignore +0 -0
  20. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/AUTHORS +0 -0
  21. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/LICENSE +0 -0
  22. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/README.md +0 -0
  23. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/__init__.py +0 -0
  24. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/checker/__init__.py +0 -0
  25. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/checker/source_loader.py +0 -0
  26. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/checker/validation_rules/all_validation_rules.json +0 -0
  27. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/checker/validation_rules/excel_validation_rules.json +0 -0
  28. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/checker/validation_rules/validation_rules.json +0 -0
  29. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/cli/__init__.py +0 -0
  30. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/cli/entities_to_excel.py +0 -0
  31. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/cli/entities_to_rdf.py +0 -0
  32. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/cli/fill_masterdata.py +0 -0
  33. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/datamodel/__init__.py +0 -0
  34. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/datamodel/collection_types.py +0 -0
  35. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/datamodel/dataset_types.py +0 -0
  36. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/datamodel/object_types.py +0 -0
  37. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/datamodel/vocabulary_types.py +0 -0
  38. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/excel/__init__.py +0 -0
  39. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/logger.py +0 -0
  40. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/metadata/__init__.py +0 -0
  41. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/metadata/_maps.py +0 -0
  42. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/metadata/definitions.py +0 -0
  43. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/metadata/entities.py +0 -0
  44. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/metadata/entities_dict.py +0 -0
  45. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/openbis/__init__.py +0 -0
  46. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/openbis/get_entities.py +0 -0
  47. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/openbis/login.py +0 -0
  48. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/utils/__init__.py +0 -0
  49. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/utils/paths.py +0 -0
  50. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/utils/utils.py +0 -0
  51. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata/validation_rules/excel_validation_rules.json +0 -0
  52. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata.egg-info/dependency_links.txt +0 -0
  53. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata.egg-info/entry_points.txt +0 -0
  54. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata.egg-info/requires.txt +0 -0
  55. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/bam_masterdata.egg-info/top_level.txt +0 -0
  56. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/bammasterdata_blue_transparent.png +0 -0
  57. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/bammasterdata_blue_transparent_text.png +0 -0
  58. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/bammasterdata_blue_transparent_text.svg +0 -0
  59. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/bammasterdata_blue_white.png +0 -0
  60. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/bammasterdata_blue_white_text.png +0 -0
  61. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/datastore-logo-white.png +0 -0
  62. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/datastore-logo.png +0 -0
  63. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/drawio/checker-structure.drawio +0 -0
  64. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/drawio/masterdata-workflow.drawio +0 -0
  65. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/drawio/masterdata-workflow.drawio.png +0 -0
  66. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/fonts/BAMKlavika-Light.ttf +0 -0
  67. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/fonts/BAMKlavika-LightItalic.ttf +0 -0
  68. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/fonts/BAMKlavika-Medium.ttf +0 -0
  69. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/assets/fonts/BAMKlavika-MediumItalic.ttf +0 -0
  70. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/explanations/data-store.md +0 -0
  71. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/explanations/openbis.md +0 -0
  72. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/explanations/pybis.md +0 -0
  73. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/overview.md +0 -0
  74. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/pybis/collections.md +0 -0
  75. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/pybis/datasets.md +0 -0
  76. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/pybis/objects.md +0 -0
  77. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/pybis/objects_props.md +0 -0
  78. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/pybis/parent_child.md +0 -0
  79. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/pybis/projects.md +0 -0
  80. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/pybis/searches.md +0 -0
  81. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/pybis/setup.md +0 -0
  82. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/howtos/pybis/spaces.md +0 -0
  83. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/index.md +0 -0
  84. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/references/collection.md +0 -0
  85. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/references/controlled-vocabulary.md +0 -0
  86. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/references/dataset.md +0 -0
  87. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/stylesheets/extra.css +0 -0
  88. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/tutorials/create-masterdata.md +0 -0
  89. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/docs/tutorials/pybis.md +0 -0
  90. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/mkdocs.yml +0 -0
  91. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/pyproject.toml +0 -0
  92. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/scripts/install_python_dependencies.sh +0 -0
  93. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/scripts/pkg_size.py +0 -0
  94. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/setup.cfg +0 -0
  95. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/setup.py +0 -0
  96. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/__init__.py +0 -0
  97. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/checker/test_source_loader.py +0 -0
  98. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/cli/test_entities_to_excel.py +0 -0
  99. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/cli/test_entities_to_rdf.py +0 -0
  100. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/conftest.py +0 -0
  101. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/datamodel_test/collection_types.py +0 -0
  102. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/datamodel_test/dataset_types.py +0 -0
  103. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/datamodel_test/object_types.py +0 -0
  104. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example01_codedoesnoteexists.xlsx +0 -0
  105. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example02_codeexists_proptype_datatypechanged.xlsx +0 -0
  106. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example03_codeexists_proptype_contvoccodechanged.xlsx +0 -0
  107. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example04_codeexists_proptype_objectcodechanged.xlsx +0 -0
  108. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example05_codeexists_proptype_warningdefschanged.xlsx +0 -0
  109. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example06_codeexists_proptype_vocobjcodemiss.xlsx +0 -0
  110. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example07_codeexists_objtype_warningdefschanged.xlsx +0 -0
  111. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example08_codeexists_objtype_assignprop_listcodeschanged_add.xlsx +0 -0
  112. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example09_codeexists_objtype_assignprop_listcodeschanged_del.xlsx +0 -0
  113. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example10_codeexists_objtype_assignprop_codedoesnotexists.xlsx +0 -0
  114. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example11_codeexists_objtype_assignprop_listcodeschanged_datatypechanged.xlsx +0 -0
  115. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example12_codeexists_objtype_assignprop_listcodeschanged_warningdefschanged.xlsx +0 -0
  116. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example13_codeexists_objtype_assignprop_coincide2objects.xlsx +0 -0
  117. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example_incoming_excel.xlsx +0 -0
  118. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example_incoming_python/collection_types.py +0 -0
  119. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example_incoming_python/dataset_types.py +0 -0
  120. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/example_incoming_python/object_types.py +0 -0
  121. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/masterdata_example.xlsx +0 -0
  122. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/masterdata_excel_output.json +0 -0
  123. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/checker/masterdata_python_output.json +0 -0
  124. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/utils/example_prop_types_1.py +0 -0
  125. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/data/utils/example_prop_types_2.py +0 -0
  126. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/metadata/test_definitions.py +0 -0
  127. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/metadata/test_entities.py +0 -0
  128. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/metadata/test_entities_dict.py +0 -0
  129. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/test_logger.py +0 -0
  130. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/utils/test_paths.py +0 -0
  131. {bam_masterdata-0.4.0 → bam_masterdata-0.4.2}/tests/utils/test_utils.py +0 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "python.defaultInterpreterPath": "~/Miniconda3/python.exe",
2
+ "python.defaultInterpreterPath": ".venv/bin/python",
3
3
  "python.terminal.activateEnvInCurrentTerminal": true,
4
4
  "editor.rulers": [90],
5
5
  "editor.renderWhitespace": "all",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bam-masterdata
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: The BAM Data Store utility tools and masterdata models wrapped in a Python package with a front-end web interface.
5
5
  Author-email: BAM Data Store <datastore@bam.de>
6
6
  Maintainer-email: "Jose M. Pizarro" <jose.pizarro-blanco@bam.de>
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.4.0'
21
- __version_tuple__ = version_tuple = (0, 4, 0)
20
+ __version__ = version = '0.4.2'
21
+ __version_tuple__ = version_tuple = (0, 4, 2)
@@ -61,7 +61,7 @@ class MasterdataChecker:
61
61
  mode in ["self", "validate", "compare", "all", "individual"]
62
62
  and self.current_model is None
63
63
  ):
64
- self.logger.info("Current model is missing. Loading now...")
64
+ self.logger.info("Current model is missing. Loading it from local files.")
65
65
  self.load_current_model()
66
66
 
67
67
  if (
@@ -35,7 +35,7 @@ class MasterdataValidator:
35
35
  Returns:
36
36
  dict: Validation results.
37
37
  """
38
- self.logger.info("Starting validation process...", mode=mode)
38
+ self.logger.debug("Starting validation process...", mode=mode)
39
39
 
40
40
  # Reset validation results before running checks
41
41
  self.validation_results = {
@@ -45,28 +45,28 @@ class MasterdataValidator:
45
45
  }
46
46
 
47
47
  if mode in ["self", "all", "validate"]:
48
- self.logger.info("Validating current model...")
48
+ self.logger.debug("Validating current model...")
49
49
  self._validate_model(self.current_model)
50
50
  self._extract_log_messages(
51
51
  self.current_model, self.validation_results["current_model"]
52
52
  )
53
53
 
54
54
  if mode in ["incoming", "all", "validate"]:
55
- self.logger.info("Validating new entities...")
55
+ self.logger.debug("Validating new entities...")
56
56
  self._validate_model(self.new_entities)
57
57
  self._extract_log_messages(
58
58
  self.new_entities, self.validation_results["incoming_model"]
59
59
  )
60
60
 
61
61
  if mode in ["compare", "all"]:
62
- self.logger.info("Comparing new entities with current model...")
62
+ self.logger.debug("Comparing new entities with current model...")
63
63
  self._compare_with_current_model(mode=mode)
64
64
  self._extract_log_messages(
65
65
  self.new_entities, self.validation_results["comparisons"]
66
66
  )
67
67
 
68
68
  if mode == "individual":
69
- self.logger.info(
69
+ self.logger.debug(
70
70
  "Validating new entities and comparing them with current model..."
71
71
  )
72
72
  self.validation_results = {
@@ -318,7 +318,7 @@ class MasterdataValidator:
318
318
  """
319
319
  Compare new entities against the current model using validation rules.
320
320
  """
321
- self.logger.info("Starting comparison with the current model...")
321
+ self.logger.debug("Starting comparison with the current model...")
322
322
 
323
323
  new_entity = False
324
324
 
@@ -11,7 +11,7 @@ from decouple import config as environ
11
11
  from openpyxl import Workbook
12
12
  from rdflib import Graph
13
13
 
14
- from bam_masterdata.checker import MasterdataChecker, no_validation_errors
14
+ from bam_masterdata.checker import MasterdataChecker
15
15
  from bam_masterdata.cli.entities_to_excel import entities_to_excel
16
16
  from bam_masterdata.cli.entities_to_rdf import entities_to_rdf
17
17
  from bam_masterdata.cli.fill_masterdata import MasterdataCodeGenerator
@@ -357,41 +357,22 @@ def export_to_rdf(force_delete, python_path, export_dir):
357
357
  )
358
358
 
359
359
 
360
- @cli.command(
361
- name="checker",
362
- help="Checks the files specified in the tag `--file-path` with respect to the ones specified in `--datamodel-path`.",
363
- )
364
- @click.option(
365
- "--file-path",
366
- "file_path", # alias
367
- type=click.Path(exists=True),
368
- required=True,
369
- help="""The path to the file or directory containing Python modules or the Excel file to be checked.""",
370
- )
371
- @click.option(
372
- "--mode",
373
- "mode", # alias
374
- type=click.Choice(
375
- ["self", "incoming", "validate", "compare", "all", "individual"],
376
- case_sensitive=False,
377
- ),
378
- default="all",
379
- help="""Specify the mode for the checker. Options are:
380
- "self" -> Validate only the current data model.
381
- "incoming" -> Validate only the new entity structure.
382
- "validate" -> Validate both the current model and new entities.
383
- "compare" -> Compare new entities against the current model.
384
- "all" -> Run all validations and comparison. (Default).
385
- "individual" -> Run individual repositories validations.""",
386
- )
387
- @click.option(
388
- "--datamodel-path",
389
- "datamodel_path", # alias
390
- type=click.Path(exists=True, dir_okay=True),
391
- default=DATAMODEL_DIR,
392
- help="""Path to the directory containing the Python modules defining the datamodel (defaults to './bam_masterdata/datamodel/').""",
393
- )
394
- def checker(file_path, mode, datamodel_path):
360
+ def run_checker(file_path: str, mode: str = "all", datamodel_path: str = DATAMODEL_DIR):
361
+ """
362
+
363
+ Run the masterdata checker on the specified file path and mode.
364
+
365
+ Args:
366
+ file_path (str): The path to the file or directory containing Python modules or the Excel file to be checked.
367
+ mode (str, optional): The mode for the checker. Defaults to "all". Options are:
368
+ "self" -> Validate only the current data model.
369
+ "incoming" -> Validate only the new entity structure.
370
+ "validate" -> Validate both the current model and new entities.
371
+ "compare" -> Compare new entities against the current model.
372
+ "all" -> Run all validations and comparison. (Default).
373
+ "individual" -> Run individual repositories validations.
374
+ datamodel_path (str, optional): Path to the directory containing the Python modules defining the datamodel. Defaults to DATAMODEL_DIR.
375
+ """
395
376
  # Instantiate the checker class and run validation
396
377
  checker = MasterdataChecker()
397
378
 
@@ -449,13 +430,43 @@ def checker(file_path, mode, datamodel_path):
449
430
  f"There are problems in the individual repositories when comparing them with respect to bam-masterdata for entity {entity} that need to be solved"
450
431
  )
451
432
 
452
- # Check if no problems were found
453
- if no_validation_errors(validation_results):
454
- click.echo("No problems found in the datamodel and incoming model.")
455
- else:
456
- raise click.ClickException(
457
- "Problems found in the datamodel. Please, check the logs."
458
- )
433
+
434
+ @cli.command(
435
+ name="checker",
436
+ help="Checks the files specified in the tag `--file-path` with respect to the ones specified in `--datamodel-path`.",
437
+ )
438
+ @click.option(
439
+ "--file-path",
440
+ "file_path", # alias
441
+ type=click.Path(exists=True),
442
+ required=True,
443
+ help="""The path to the file or directory containing Python modules or the Excel file to be checked.""",
444
+ )
445
+ @click.option(
446
+ "--mode",
447
+ "mode", # alias
448
+ type=click.Choice(
449
+ ["self", "incoming", "validate", "compare", "all", "individual"],
450
+ case_sensitive=False,
451
+ ),
452
+ default="all",
453
+ help="""Specify the mode for the checker. Options are:
454
+ "self" -> Validate only the current data model.
455
+ "incoming" -> Validate only the new entity structure.
456
+ "validate" -> Validate both the current model and new entities.
457
+ "compare" -> Compare new entities against the current model.
458
+ "all" -> Run all validations and comparison. (Default).
459
+ "individual" -> Run individual repositories validations.""",
460
+ )
461
+ @click.option(
462
+ "--datamodel-path",
463
+ "datamodel_path", # alias
464
+ type=click.Path(exists=True, dir_okay=True),
465
+ default=DATAMODEL_DIR,
466
+ help="""Path to the directory containing the Python modules defining the datamodel (defaults to './bam_masterdata/datamodel/').""",
467
+ )
468
+ def checker(file_path, mode, datamodel_path):
469
+ run_checker(file_path=file_path, mode=mode, datamodel_path=datamodel_path)
459
470
 
460
471
 
461
472
  @cli.command(
@@ -1,4 +1,3 @@
1
- import json
2
1
  import os
3
2
  import re
4
3
  from typing import TYPE_CHECKING, Any, Optional, Union
@@ -12,6 +11,7 @@ import openpyxl
12
11
 
13
12
  from bam_masterdata.logger import logger
14
13
  from bam_masterdata.metadata.definitions import DataType
14
+ from bam_masterdata.utils import VALIDATION_RULES_DIR
15
15
 
16
16
 
17
17
  class MasterdataExcelExtractor:
@@ -29,7 +29,7 @@ class MasterdataExcelExtractor:
29
29
  if not MasterdataExcelExtractor.VALIDATION_RULES:
30
30
  self.VALIDATION_RULES = load_validation_rules(
31
31
  self.logger,
32
- file_path="./bam_masterdata/checker/validation_rules/excel_validation_rules.json",
32
+ os.path.join(VALIDATION_RULES_DIR, "excel_validation_rules.json"),
33
33
  )
34
34
 
35
35
  def index_to_excel_column(self, index: int) -> str:
@@ -414,13 +414,21 @@ class MasterdataExcelExtractor:
414
414
  "Vocabulary code",
415
415
  "Metadata",
416
416
  "Dynamic script",
417
- "Unique",
418
- "Internal assignment",
417
+ # ! these are not used
418
+ # "Unique",
419
+ # "Internal assignment",
419
420
  ]
420
421
 
421
422
  # Determine the header row index
422
423
  header_index = start_index_row + 3
423
- row_headers = [cell.value for cell in sheet[header_index]]
424
+ row_headers = [(cell.value, cell.coordinate) for cell in sheet[header_index]]
425
+ # And store how many properties are for the entity
426
+ n_properties = last_non_empty_row - header_index
427
+ if n_properties < 0:
428
+ self.logger.error(
429
+ f"No properties found for the entity in sheet {sheet.title} starting at row {start_index_row}."
430
+ )
431
+ return property_dict
424
432
 
425
433
  # Initialize a dictionary to store extracted columns
426
434
  extracted_columns: dict[str, list] = {term: [] for term in expected_terms}
@@ -428,8 +436,8 @@ class MasterdataExcelExtractor:
428
436
  extracted_columns["row_location"] = []
429
437
 
430
438
  # Extract columns for each expected term
431
- for term in expected_terms:
432
- if term not in row_headers:
439
+ for i, (term, coordinate) in enumerate(row_headers):
440
+ if term not in expected_terms:
433
441
  log_func = (
434
442
  self.logger.warning
435
443
  if term
@@ -439,48 +447,55 @@ class MasterdataExcelExtractor:
439
447
  "Section",
440
448
  "Metadata",
441
449
  "Dynamic script",
442
- "Unique",
443
- "Internal assignment",
444
450
  "Vocabulary code",
451
+ # ! these are not used
452
+ # "Unique",
453
+ # "Internal assignment",
445
454
  )
446
455
  else self.logger.error
447
456
  )
448
457
  log_func(f"'{term}' not found in the properties headers.", term=term)
449
458
  continue
450
459
 
451
- # Get column index and Excel letter
452
- term_index = row_headers.index(term) + 1
453
- term_letter = self.index_to_excel_column(term_index)
460
+ # Excel column letter from the coordinate
461
+ term_letter = coordinate[0]
454
462
 
455
463
  # Extract values from the column
456
- for i in range(header_index + 1, last_non_empty_row + 1):
457
- cell = sheet[term_letter + str(i)]
464
+ for cell_property in sheet[term_letter][header_index:last_non_empty_row]:
458
465
  extracted_columns[term].append(
459
- self.process_term(term, cell.value, cell.coordinate, sheet.title)
466
+ self.process_term(
467
+ term, cell_property.value, cell_property.coordinate, sheet.title
468
+ )
460
469
  )
461
470
  if self.row_cell_info:
462
- extracted_columns["row_location"].append(term_letter + str(i))
463
- # for cell in sheet[term_letter][header_index:last_non_empty_row]:
464
- # extracted_columns[term].append(
465
- # self.process_term(term, cell.value, cell.coordinate, sheet.title)
466
- # )
471
+ extracted_columns["row_location"].append(cell_property.coordinate)
467
472
 
468
473
  # Combine extracted values into a dictionary
469
- for i in range(len(extracted_columns["Code"])):
470
- property_dict[extracted_columns["Code"][i]] = {
471
- "permId": extracted_columns["Code"][i],
472
- "code": extracted_columns["Code"][i],
473
- "description": extracted_columns["Description"][i],
474
- "section": extracted_columns["Section"][i],
475
- "mandatory": extracted_columns["Mandatory"][i],
476
- "show_in_edit_views": extracted_columns["Show in edit views"][i],
477
- "label": extracted_columns["Property label"][i],
478
- "dataType": extracted_columns["Data type"][i],
479
- "vocabularyCode": extracted_columns["Vocabulary code"][i],
480
- }
474
+ for i in range(n_properties):
475
+ code = extracted_columns.get("Code", [])
476
+ if not code:
477
+ self.logger.error(
478
+ f"'Code' not found in the properties headers for sheet {sheet.title}."
479
+ )
480
+ return property_dict
481
+ code = code[i]
482
+ property_dict[code] = {"permId": code, "code": code}
483
+ for key, pybis_val in {
484
+ "Description": "description",
485
+ "Section": "section",
486
+ "Mandatory": "mandatory",
487
+ "Show in edit views": "show_in_edit_views",
488
+ "Property label": "label",
489
+ "Data type": "dataType",
490
+ "Vocabulary code": "vocabularyCode",
491
+ }.items():
492
+ data_column = extracted_columns.get(key, [])
493
+ if not data_column:
494
+ continue
495
+ property_dict[code][pybis_val] = data_column[i]
481
496
  if self.row_cell_info:
482
- property_dict[extracted_columns["Code"][i]]["row_location"] = (
483
- extracted_columns["row_location"][i]
497
+ property_dict[code]["row_location"] = (
498
+ extracted_columns.get("row_location")[i],
484
499
  )
485
500
  # Only add optional fields if they exist in extracted_columns
486
501
  optional_fields = [
@@ -0,0 +1,76 @@
1
+ {
2
+ "code": {
3
+ "pattern": "^\\$?[A-Za-z0-9_.]+$"
4
+ },
5
+ "description": {
6
+ "pattern": ".*",
7
+ "is_description": true
8
+ },
9
+ "validation_script": {
10
+ "pattern": "^[A-Za-z0-9_\\.]+$",
11
+ "allow_empty": true
12
+ },
13
+ "auto_generated_codes": {
14
+ "is_bool": true
15
+ },
16
+ "main_dataset_pattern": {
17
+ "pattern": ".*",
18
+ "allow_empty": true
19
+ },
20
+ "main_dataset_path": {
21
+ "pattern": ".*",
22
+ "allow_empty": true
23
+ },
24
+ "property_label": {
25
+ "pattern": ".*"
26
+ },
27
+ "data_type": {
28
+ "is_data": true
29
+ },
30
+ "vocabulary_code": {
31
+ "pattern": "^\\$?[A-Za-z0-9_.]+$",
32
+ "allow_empty": true
33
+ },
34
+ "object_code": {
35
+ "pattern": "^\\$?[A-Za-z0-9_.]+$",
36
+ "allow_empty": true
37
+ },
38
+ "metadata": {
39
+ "pattern": ".*",
40
+ "allow_empty": true
41
+ },
42
+ "url_template": {
43
+ "pattern": "https?://(?:www\\.)?[a-zA-Z0-9-._~:/?#@!$&'()*+,;=%]+",
44
+ "is_url": true,
45
+ "allow_empty": true
46
+ },
47
+ "dynamic_script": {
48
+ "pattern": "^[A-Za-z0-9_\\.]+$",
49
+ "allow_empty": true
50
+ },
51
+ "mandatory": {
52
+ "is_bool": true
53
+ },
54
+ "show_in_edit_views": {
55
+ "is_bool": true
56
+ },
57
+ "section": {
58
+ "pattern": ".*"
59
+ },
60
+ "unique": {
61
+ "is_bool": true,
62
+ "allow_empty": true
63
+ },
64
+ "internal_assignment": {
65
+ "pattern": ".*",
66
+ "allow_empty": true
67
+ },
68
+ "generated_code_prefix": {
69
+ "pattern": ".*",
70
+ "extra_validation": "is_reduced_version"
71
+ },
72
+ "official": {
73
+ "is_bool": true,
74
+ "allow_empty": true
75
+ }
76
+ }
@@ -0,0 +1,109 @@
1
+ {
2
+ "defs_validation": {
3
+ "code": {
4
+ "pattern": "^\\$?[A-Za-z0-9_.-]+$"
5
+ },
6
+ "description": {
7
+ "pattern": ".*",
8
+ "allow_empty": true,
9
+ "is_description": true
10
+ },
11
+ "validation_script": {
12
+ "pattern": "^[A-Za-z0-9_\\.]+$",
13
+ "allow_empty": true
14
+ },
15
+ "generated_code_prefix": {
16
+ "pattern": ".*",
17
+ "extra_validation": "is_reduced_version"
18
+ },
19
+ "main_dataset_pattern": {
20
+ "pattern": ".*",
21
+ "allow_empty": true
22
+ },
23
+ "main_dataset_path": {
24
+ "pattern": ".*",
25
+ "allow_empty": true
26
+ },
27
+ "auto_generated_codes": {
28
+ "is_bool": true
29
+ },
30
+ "url_template": {
31
+ "pattern": "https?://(?:www\\.)?[a-zA-Z0-9-._~:/?#@!$&'()*+,;=%]+",
32
+ "is_url": true,
33
+ "allow_empty": true
34
+ }
35
+ },
36
+ "properties_validation": {
37
+ "code": {
38
+ "pattern": "^\\$?[A-Za-z0-9_.-]+$"
39
+ },
40
+ "description": {
41
+ "pattern": ".*",
42
+ "allow_empty": true,
43
+ "is_description": true
44
+ },
45
+ "property_label": {
46
+ "pattern": ".*"
47
+ },
48
+ "data_type": {
49
+ "is_data": true
50
+ },
51
+ "vocabulary_code": {
52
+ "pattern": "^\\$?[A-Za-z0-9_.]+$",
53
+ "allow_empty": true
54
+ },
55
+ "object_code": {
56
+ "pattern": "^\\$?[A-Za-z0-9_.]+$",
57
+ "allow_empty": true
58
+ },
59
+ "metadata": {
60
+ "pattern": ".*",
61
+ "allow_empty": true
62
+ },
63
+ "dynamic_script": {
64
+ "pattern": "^[A-Za-z0-9_\\.]+$",
65
+ "allow_empty": true
66
+ },
67
+ "mandatory": {
68
+ "is_bool": true
69
+ },
70
+ "show_in_edit_views": {
71
+ "is_bool": true
72
+ },
73
+ "section": {
74
+ "pattern": "^([A-Z][a-z]*|[A-Z]+)( ([A-Z][a-z]*|[A-Z]+))*$",
75
+ "is_section": true,
76
+ "allow_empty": true
77
+ },
78
+ "unique": {
79
+ "is_bool": true,
80
+ "allow_empty": true
81
+ },
82
+ "internal_assignment": {
83
+ "pattern": ".*",
84
+ "allow_empty": true
85
+ }
86
+ },
87
+ "terms_validation": {
88
+ "code": {
89
+ "pattern": "^\\$?[A-Za-z0-9_.-]+$"
90
+ },
91
+ "description": {
92
+ "pattern": ".*",
93
+ "is_description": true,
94
+ "allow_empty": true
95
+ },
96
+ "url_template": {
97
+ "pattern": "https?://(?:www\\.)?[a-zA-Z0-9-._~:/?#@!$&'()*+,;=%]+",
98
+ "is_url": true,
99
+ "allow_empty": true
100
+ },
101
+ "label": {
102
+ "pattern": ".*"
103
+ },
104
+ "official": {
105
+ "is_bool": true,
106
+ "allow_empty": true
107
+ }
108
+ }
109
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bam-masterdata
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: The BAM Data Store utility tools and masterdata models wrapped in a Python package with a front-end web interface.
5
5
  Author-email: BAM Data Store <datastore@bam.de>
6
6
  Maintainer-email: "Jose M. Pizarro" <jose.pizarro-blanco@bam.de>
@@ -50,6 +50,7 @@ bam_masterdata/openbis/login.py
50
50
  bam_masterdata/utils/__init__.py
51
51
  bam_masterdata/utils/paths.py
52
52
  bam_masterdata/utils/utils.py
53
+ bam_masterdata/validation_rules/all_validation_rules.json
53
54
  bam_masterdata/validation_rules/excel_validation_rules.json
54
55
  bam_masterdata/validation_rules/validation_rules.json
55
56
  docs/index.md
@@ -711,8 +711,6 @@ def test_process_entity(
711
711
  "Vocabulary code",
712
712
  "Metadata",
713
713
  "Dynamic script",
714
- "Unique",
715
- "Internal assignment",
716
714
  ],
717
715
  [
718
716
  [
@@ -726,8 +724,6 @@ def test_process_entity(
726
724
  "VOCAB_ABC",
727
725
  "Meta info",
728
726
  "Script example",
729
- "True",
730
- "Internal logic",
731
727
  ],
732
728
  [
733
729
  "PROP_002",
@@ -740,8 +736,6 @@ def test_process_entity(
740
736
  "VOCAB_DEF",
741
737
  None, # Metadata not provided
742
738
  None, # Dynamic script not provided
743
- None, # Unique
744
- None, # Internal assignment not provided
745
739
  ],
746
740
  ],
747
741
  6,
@@ -758,8 +752,6 @@ def test_process_entity(
758
752
  "vocabularyCode": "VOCAB_ABC",
759
753
  "metadata": "Meta info",
760
754
  "dynamic_script": "Script example",
761
- "unique": "True",
762
- "internal_assignment": "Internal logic",
763
755
  },
764
756
  "PROP_002": {
765
757
  "permId": "PROP_002",
@@ -773,101 +765,11 @@ def test_process_entity(
773
765
  "vocabularyCode": "VOCAB_DEF",
774
766
  "metadata": None,
775
767
  "dynamic_script": None,
776
- "unique": None,
777
- "internal_assignment": None,
778
768
  },
779
769
  },
780
770
  None,
781
771
  None,
782
772
  ),
783
- # Missing Header: "Data type"
784
- (
785
- [
786
- "Code",
787
- "Description",
788
- "Mandatory",
789
- "Show in edit views",
790
- "Section",
791
- "Property label",
792
- "Vocabulary code",
793
- "Metadata",
794
- "Dynamic script",
795
- "Unique",
796
- "Internal assignment",
797
- ], # Missing "Data type"
798
- [
799
- [
800
- "PROP_001",
801
- "Sample description",
802
- "True",
803
- "False",
804
- "General",
805
- "Property Label",
806
- "VOCAB_ABC",
807
- "Meta info",
808
- "Script example",
809
- "True",
810
- "Internal logic",
811
- ]
812
- ],
813
- 4,
814
- {},
815
- "'Data type' not found in the properties headers.",
816
- "error",
817
- ),
818
- # Invalid Data Type
819
- (
820
- [
821
- "Code",
822
- "Description",
823
- "Mandatory",
824
- "Show in edit views",
825
- "Section",
826
- "Property label",
827
- "Data type",
828
- "Vocabulary code",
829
- "Metadata",
830
- "Dynamic script",
831
- "Unique",
832
- "Internal assignment",
833
- ],
834
- [
835
- [
836
- "PROP_003",
837
- "Description",
838
- "True",
839
- "False",
840
- "General",
841
- "Property Label",
842
- "INVALID_TYPE",
843
- "VOCAB_ABC",
844
- "Meta info",
845
- "Script example",
846
- "True",
847
- "Internal logic",
848
- ]
849
- ],
850
- 5,
851
- {
852
- "PROP_003": {
853
- "permId": "PROP_003",
854
- "code": "PROP_003",
855
- "description": "Description",
856
- "section": "General",
857
- "mandatory": True,
858
- "show_in_edit_views": False,
859
- "label": "Property Label",
860
- "dataType": "INVALID_TYPE",
861
- "vocabularyCode": "VOCAB_ABC",
862
- "metadata": "Meta info",
863
- "dynamic_script": "Script example",
864
- "unique": "True",
865
- "internal_assignment": "Internal logic",
866
- }
867
- },
868
- f"Invalid data type value found in the Data type column at position G5 in TestSheet.The Data Type should be one of the following: {[dt.value for dt in DataType]}",
869
- "error",
870
- ),
871
773
  # Missing Code (Should be ignored)
872
774
  (
873
775
  [
@@ -880,8 +782,6 @@ def test_process_entity(
880
782
  "Vocabulary code",
881
783
  "Metadata",
882
784
  "Dynamic script",
883
- "Unique",
884
- "Internal assignment",
885
785
  ], # Missing "Code"
886
786
  [
887
787
  [
@@ -894,13 +794,11 @@ def test_process_entity(
894
794
  "VOCAB_ABC",
895
795
  "Meta info",
896
796
  "Script example",
897
- "True",
898
- "Internal logic",
899
797
  ]
900
798
  ],
901
- 4,
799
+ 5,
902
800
  {},
903
- "'Code' not found in the properties headers.",
801
+ "'Code' not found in the properties headers for sheet TestSheet.",
904
802
  "error",
905
803
  ),
906
804
  ],
File without changes
File without changes
File without changes
File without changes
File without changes