nmdc-schema 11.12.0rc1__py3-none-any.whl → 11.12.1__py3-none-any.whl

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.
@@ -0,0 +1,103 @@
1
+ from typing import Any, Optional, Iterator, Union
2
+
3
+ from linkml.validator.plugins import ValidationPlugin
4
+ from linkml.validator.report import ValidationResult, Severity
5
+ from linkml.validator.validation_context import ValidationContext
6
+ from linkml_runtime import SchemaView
7
+
8
+
9
+ def _yield_quantity_value_objects(data: Any, path: Optional[list[Union[str, int]]] = None):
10
+ """Recursively yield QuantityValue objects from data."""
11
+ if path is None:
12
+ path = []
13
+ if isinstance(data, dict):
14
+ if data.get("type") == "nmdc:QuantityValue":
15
+ yield path, data
16
+ else:
17
+ # Recursively search nested dictionaries
18
+ for key, value in data.items():
19
+ yield from _yield_quantity_value_objects(value, path + [key])
20
+ elif isinstance(data, list):
21
+ # Handle lists of objects
22
+ for i, item in enumerate(data):
23
+ yield from _yield_quantity_value_objects(item, path + [i])
24
+
25
+
26
+ class NmdcSchemaValidationPlugin(ValidationPlugin):
27
+ """A validation plugin which validates instances using NMDC-specific validation logic.
28
+
29
+ This plugin is designed to be used as a part of LinkML's validation framework and in conjunction
30
+ with the `JsonSchemaValidationPlugin` provided by LinkML. This plugin performs the following
31
+ additional checks:
32
+
33
+ 1. Ensure that values for slots with range `QuantityValue` have a `unit` property that is in
34
+ agreement with the `storage_unit` annotation on the slot
35
+ """
36
+
37
+ def __init__(self, *args, **kwargs) -> None:
38
+ super().__init__(*args, **kwargs)
39
+ self._slot_storage_units_cache = {}
40
+
41
+ def _slot_storage_units(self, schema_view: SchemaView, slot_name: str) -> Optional[list[str]]:
42
+ """Get allowed storage_units for a slot."""
43
+ if slot_name in self._slot_storage_units_cache:
44
+ return self._slot_storage_units_cache[slot_name]
45
+
46
+ slot = schema_view.get_slot(slot_name)
47
+ if not slot or not slot.annotations:
48
+ self._slot_storage_units_cache[slot_name] = None
49
+ return None
50
+
51
+ storage_units = None
52
+ if "storage_units" in slot.annotations:
53
+ annotation_obj = slot.annotations["storage_units"]
54
+ if annotation_obj and hasattr(annotation_obj, "value"):
55
+ # Split on pipes for multiple units
56
+ storage_units = str(annotation_obj.value).split("|")
57
+
58
+ self._slot_storage_units_cache[slot_name] = storage_units
59
+ return storage_units
60
+
61
+ def process(self, instance: Any, context: ValidationContext) -> Iterator[ValidationResult]:
62
+ """Perform NMDC-specific schema validation on the provided instance
63
+
64
+ :param instance: The instance to validate
65
+ :param context: The validation context which provides a SchemaView artifact
66
+ :return: Iterator over validation results
67
+ :rtype: Iterator[ValidationResult]
68
+ """
69
+ for data_path, quantity_value in _yield_quantity_value_objects(instance):
70
+ # Get the `has_unit` property from the QuantityValue instance. If it is missing, yield a
71
+ # validation error and continue. This is slightly redundant with JSON Schema validation,
72
+ # but it ensures that we do not attempt further validation on the instance.
73
+ unit = quantity_value.get("has_unit")
74
+ str_data_path = '/'.join(str(p) for p in data_path)
75
+ if unit is None:
76
+ yield ValidationResult(
77
+ type="nmdc-schema validation",
78
+ severity=Severity.ERROR,
79
+ instance=instance,
80
+ instantiates=context.target_class,
81
+ message=f"QuantityValue at /{str_data_path} is missing required 'has_unit' property",
82
+ )
83
+ continue
84
+
85
+ # Find the slot name by looking for the last string in the data path. If one cannot be
86
+ # found, skip further validation because we cannot determine the relevant slot.
87
+ try:
88
+ slot_name = next(key for key in reversed(data_path) if isinstance(key, str))
89
+ except StopIteration:
90
+ continue
91
+
92
+ storage_units = self._slot_storage_units(context.schema_view, slot_name)
93
+ if storage_units and unit not in storage_units:
94
+ yield ValidationResult(
95
+ type="nmdc-schema validation",
96
+ severity=Severity.ERROR,
97
+ instance=instance,
98
+ instantiates=context.target_class,
99
+ message=(
100
+ f"QuantityValue at /{str_data_path} has unit '{unit}' which is not allowed for "
101
+ f"slot '{slot_name}' (allowed: {', '.join(storage_units)})"
102
+ )
103
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nmdc_schema
3
- Version: 11.12.0rc1
3
+ Version: 11.12.1
4
4
  Summary: Schema resources for the National Microbiome Data Collaborative (NMDC)
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -1,12 +1,12 @@
1
1
  nmdc_schema/README.md,sha256=qU69vQY5IA0bOj2ZvGhIl7B4edI_yCJ_OwM1yXcAvuw,404
2
- nmdc_schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ nmdc_schema/__init__.py,sha256=yVS2Kd54IPIFKj6vJidUZELtajC4XPDioDoKnOsqrW8,111
3
3
  nmdc_schema/anyuri_strings_to_iris.py,sha256=c09sGU6JbaWwJP3oYAIGEAx7aQZO5j2X1dK78RGX3oc,3352
4
4
  nmdc_schema/dump_single_modality.py,sha256=DEdlmDr6phClUslR1AKlVy70Xy9kRx4RM754AsDbYNE,14063
5
5
  nmdc_schema/get_json_schema.py,sha256=5TFl1GCImyR5GHLK2hOz1MqqEyoRqhbukEs4x4AMYeM,320
6
6
  nmdc_schema/get_nmdc_view.py,sha256=AwaPqb3H75ekL0hEV3SAhrUhFXVGFr1yFxQvBjPuRnY,401
7
7
  nmdc_schema/gold-to-mixs.sssom.tsv,sha256=gSo2vLjyNPfQPqZHeRKqS9uCe1XfGzzS-1_cTWxInJs,16935
8
8
  nmdc_schema/id_helpers.py,sha256=sX6skceaLBLTLBsSeOz-OwVkde4GvI5k5X1tnDVfhrY,3380
9
- nmdc_schema/migration_recursion.py,sha256=Tj1sfrJrZglwVC6fwaG4xvnFOt0P9AuBc9R4OHDD1Z0,5178
9
+ nmdc_schema/migration_recursion.py,sha256=SuYl-z-ZmOhvD52VM_9BZgOtf5oDH09IES1JNoRqYFM,5302
10
10
  nmdc_schema/migrators/.docker/.env.example,sha256=eEgP5AMi0BRNdwkZ9gMYaGTg8_8vaZRv9sdmQpcmsKo,479
11
11
  nmdc_schema/migrators/.docker/docker-compose.yaml,sha256=5uzWYsBbtXzMwdQYQUEMVBDcJ0-gM7FxazSah-_QVIs,925
12
12
  nmdc_schema/migrators/.docker/mongoKeyFile,sha256=OmlML9o_bZVcVXQBCySb8IZoNmNxwqSP8lFHUBc-R4w,12
@@ -27,8 +27,8 @@ nmdc_schema/migrators/cli/README.md,sha256=DXoNj2Yhytl60_cpCJKP53p0yz2ygkPOQ_3HM
27
27
  nmdc_schema/migrators/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  nmdc_schema/migrators/cli/create_migrator.py,sha256=gdey2oclbFvywazGMvfHkf2G-J3Bc3Lz8bnG3UHLajw,4491
29
29
  nmdc_schema/migrators/cli/migrator.py.template,sha256=7C-Ela_NrhkmgGY_Dz28ICF-xrT4ooolQ4kzmroJ9wc,369
30
- nmdc_schema/migrators/cli/run_migrator.py,sha256=LHl2S5XZCsC8aqRM4zcBADue8DneCR3eC7LhLXcgKJ8,4508
31
- nmdc_schema/migrators/helpers.py,sha256=AxmFh2zGBmJD7ndmVYJvRcEQjcCyNwZmDjDoFMdlf2o,4820
30
+ nmdc_schema/migrators/cli/run_migrator.py,sha256=tICbb6TADAzkglqi87eGT6mlSNZXhMx1HW2CD1j4oe4,4362
31
+ nmdc_schema/migrators/helpers.py,sha256=87w3O7meGeGV61_1Iy-UAik2FR4ERTmzSea7BygDcAY,5924
32
32
  nmdc_schema/migrators/migration_reporter.py,sha256=LV04b_Eu8UfTu3ZvKJi0Azyd1DHFauSR0918SyB9u-s,12284
33
33
  nmdc_schema/migrators/migrator_base.py,sha256=6GQ0uVQ27dQ3HseWHaTiTYf6QiWQFzcb6YRYVtBCyuw,3634
34
34
  nmdc_schema/migrators/migrator_from_10_0_0_to_10_1_2.py,sha256=aRKxRs5GrBin5oFrYaVSRQct90E3dsmXuTEZ6KO2oYY,2603
@@ -41,6 +41,7 @@ nmdc_schema/migrators/migrator_from_10_5_6_to_10_6_0.py,sha256=_oeQz_mXVC-vyyfUs
41
41
  nmdc_schema/migrators/migrator_from_10_6_0_to_10_7_0.py,sha256=-FduiWWIioYFQ2eST35NINok6cy6FoPuJ7-UXJPAi_E,450
42
42
  nmdc_schema/migrators/migrator_from_11_0_3_to_11_1_0.py,sha256=3hHXGts_sfre4KuIpGCUNyRMgI92_lXm_U2UStU-fdw,1184
43
43
  nmdc_schema/migrators/migrator_from_11_10_0_to_11_11_0.py,sha256=R4nUrhxRznukwKgkMQy8uuPzn-fE9AaQYNLLNsVOfTk,1354
44
+ nmdc_schema/migrators/migrator_from_11_11_0_to_11_12_0.py,sha256=0lFUiE8SU2fhqlyN9lBg6-AuRiIw9qmOmg8IIhPmryM,1353
44
45
  nmdc_schema/migrators/migrator_from_11_1_0_to_11_2_0.py,sha256=xGaG0oilg0Xvq-P6YOZea3EPQU8fyfcKo-KZl4BhgoM,1183
45
46
  nmdc_schema/migrators/migrator_from_11_3_0_to_11_4_0.py,sha256=XDRsT9KrKlZTOGHQekESZ2XSYD2UDydF1PWTRIeqOVE,1985
46
47
  nmdc_schema/migrators/migrator_from_11_4_0_to_11_5_0.py,sha256=uiFi5USF23lpuAbkDhVufnXxLsM-Aixrj4nw7GY-XO4,357
@@ -83,6 +84,9 @@ nmdc_schema/migrators/partials/migrator_from_11_0_3_to_11_1_0/migrator_from_11_0
83
84
  nmdc_schema/migrators/partials/migrator_from_11_10_0_to_11_11_0/__init__.py,sha256=0Vyyg3SaqNsV426IFeWw1xgEDFAol5J57ggk7bDAAf4,1001
84
85
  nmdc_schema/migrators/partials/migrator_from_11_10_0_to_11_11_0/migrator_from_11_10_0_to_11_11_0_part_1.py,sha256=JTjgjW8GhpDuNQajNN2EBoDzm6OFJg9E42pR7HDqIiE,3595
85
86
  nmdc_schema/migrators/partials/migrator_from_11_10_0_to_11_11_0/migrator_from_11_10_0_to_11_11_0_part_2.py,sha256=cNgxp1XBVKSiQAAhUfLXWvEK8UyJTnveO_c_BqvlCVo,1986
87
+ nmdc_schema/migrators/partials/migrator_from_11_11_0_to_11_12_0/__init__.py,sha256=MQg_WO1szHMiaDN7e6wEY_eo2o_BE1htJ7bF-mcfvIw,1001
88
+ nmdc_schema/migrators/partials/migrator_from_11_11_0_to_11_12_0/migrator_from_11_11_0_to_11_12_0_part_1.py,sha256=ydGOhXXpsj6OkvLMz88w2Yzj9ibB1JinRWy-1jjSJYE,8668
89
+ nmdc_schema/migrators/partials/migrator_from_11_11_0_to_11_12_0/migrator_from_11_11_0_to_11_12_0_part_2.py,sha256=CvVPOWuLJEyen7pFN86VDTFZ9KdEnEhoE011e2L9e10,4851
86
90
  nmdc_schema/migrators/partials/migrator_from_11_1_0_to_11_2_0/__init__.py,sha256=e-neqgmL6Zsy6h5PGmWPj9qIqrTm3yvNgo2l2i7Sduc,990
87
91
  nmdc_schema/migrators/partials/migrator_from_11_1_0_to_11_2_0/migrator_from_11_1_0_to_11_2_0_part_1.py,sha256=4nN_2iZqML84R9EgznIcj7FjIlRHSSM8XqLerUgMYbI,13230
88
92
  nmdc_schema/migrators/partials/migrator_from_11_1_0_to_11_2_0/migrator_from_11_1_0_to_11_2_0_part_2.py,sha256=HLGoX3KQZglHPODDO5FFHu2gjFjyBx8oGJ3D9PAkhNI,1628
@@ -102,17 +106,18 @@ nmdc_schema/migrators/partials/migrator_from_11_9_1_to_11_10_0/__init__.py,sha25
102
106
  nmdc_schema/migrators/partials/migrator_from_11_9_1_to_11_10_0/migrator_from_11_9_1_to_11_10_0_part_1.py,sha256=6MYmrB9yfJ3XFb2QabTcJeycK2tyVO3MtSItns2s9Zg,35421
103
107
  nmdc_schema/migrators/partials/migrator_from_11_9_1_to_11_10_0/migrator_from_11_9_1_to_11_10_0_part_2.py,sha256=wzard2sUTeRS7voVTfPt3_OtafTffnv0o0OyE1OBzA0,2987
104
108
  nmdc_schema/migrators/partials/migrator_from_11_9_1_to_11_10_0/migrator_from_11_9_1_to_11_10_0_part_3.py,sha256=crm2NEmn0xepEMKWHvCSkfX3G6hRn377f38rq24XlO8,3710
105
- nmdc_schema/nmdc-pydantic.py,sha256=7rGCbO4xQpgqInSoBApx08kdVjKyUrtA41HDEuK1nqE,1450732
106
- nmdc_schema/nmdc.py,sha256=gxIblQcUMgP0W7S2cSqfjyC-nq8Vf65kMRqWen1itAM,721703
107
- nmdc_schema/nmdc.schema.json,sha256=ynUBZIkZFtpBOAgyqXWz7C3RI3TgYOMQEPriYuD-nCk,623206
109
+ nmdc_schema/nmdc-pydantic.py,sha256=jCJl_A_HbE_sa1YrajAyx3yxh7D9FicGtch-GhsTcDc,1462437
110
+ nmdc_schema/nmdc.py,sha256=kphp1Npu66qGCs9EaJqQvOfiwI8ydTu1_Z6Xotjjlqc,730020
111
+ nmdc_schema/nmdc.schema.json,sha256=7KHr5AMe-DveFSEv8i2E8hL6JiCdRzHZJsMIAjCd0LI,629145
108
112
  nmdc_schema/nmdc_data.py,sha256=_wNKi5NDxuvvRsJEim2ialX7VJkDBJLRpiTOPpFHBm8,9608
109
- nmdc_schema/nmdc_materialized_patterns.json,sha256=GpFAWtE6bAASgR02OWNjplxV2-Fi2kKkEb34mcZfUPI,929940
110
- nmdc_schema/nmdc_materialized_patterns.schema.json,sha256=IEFMQ-znm2aLih5OxIujNk1VzvZFYj-NrDjh5QZ_j3c,631489
111
- nmdc_schema/nmdc_materialized_patterns.yaml,sha256=KYek6PnKYhzNITIGA26KhQ54sTJdvx1zzg1PMKN-F54,719115
113
+ nmdc_schema/nmdc_materialized_patterns.json,sha256=--Ldf1ZEL6VF0gfTPCydlBfGHts8dwEujfWdBp4qQxg,937613
114
+ nmdc_schema/nmdc_materialized_patterns.schema.json,sha256=3sGnS8aXLND6empjNu-YlQddbFuoLSneSgZpSVyQrL8,637428
115
+ nmdc_schema/nmdc_materialized_patterns.yaml,sha256=uTJa9P_Ng3LSV905jTWzM4Vy535hNel8IA83ecFj5I0,725518
116
+ nmdc_schema/nmdc_schema_validation_plugin.py,sha256=rjtn1tYhngGyc1AV8vcT8BJ9a_MmHbcK3hRUf9dzPtA,4799
112
117
  nmdc_schema/nmdc_version.py,sha256=DsfEKnmN3LHR831WWELxyfZY6rnP9U8tfygamkrsaHY,2305
113
118
  nmdc_schema/validate_nmdc_json.py,sha256=PVJV2O1qQXMi206HaUKqRNLiLc164OpNYKPURSKN8_E,3148
114
- nmdc_schema-11.12.0rc1.dist-info/METADATA,sha256=9ItBgZOyFJal6ydpy2taCEwF6U3dC8ILPizsIgD68R8,5902
115
- nmdc_schema-11.12.0rc1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
116
- nmdc_schema-11.12.0rc1.dist-info/entry_points.txt,sha256=Z_cdWpUrV7DjGkjfuNG5VIjevU2JzxpoWlRADmmkBxs,2150
117
- nmdc_schema-11.12.0rc1.dist-info/licenses/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
118
- nmdc_schema-11.12.0rc1.dist-info/RECORD,,
119
+ nmdc_schema-11.12.1.dist-info/METADATA,sha256=wtKrUSPP6n3T3xgVvzlBtd59Ku-ELL6PXqG6LHlFHZ0,5899
120
+ nmdc_schema-11.12.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
121
+ nmdc_schema-11.12.1.dist-info/entry_points.txt,sha256=-UOl7vTEjS6eaJreIu_UenULpuKAYz8JiLeuKbEqPB8,2079
122
+ nmdc_schema-11.12.1.dist-info/licenses/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
123
+ nmdc_schema-11.12.1.dist-info/RECORD,,
@@ -23,7 +23,6 @@ schema-view-relation-graph=src.scripts.schema_view_relation_graph:cli
23
23
  scrutinize-elements=src.scripts.scrutinize_elements:process_schema_elements
24
24
  slot-range-type-reporter=src.scripts.slot_range_type_reporter:cli
25
25
  units-mongodb-analyze=units.scripts.mongodb_analyze_units:main
26
- units-production-validate=units.scripts.production_validate_units:main
27
26
  units-schema-convert=units.scripts.schema_convert_to_ucum:main
28
27
  units-schema-extract=units.scripts.schema_extract_preferred_units:main
29
28
  units-schema-extract-slot-unit-pairs=units.scripts.schema_expand_storage_units:main