nmdc-schema 11.12.0rc2__py3-none-any.whl → 11.13.0__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,19 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nmdc_schema
3
- Version: 11.12.0rc2
3
+ Version: 11.13.0
4
4
  Summary: Schema resources for the National Microbiome Data Collaborative (NMDC)
5
5
  License: MIT
6
6
  License-File: LICENSE
7
7
  Keywords: NMDC,schema,metadata,microbiome
8
8
  Author: Bill Duncan
9
9
  Author-email: wdduncan@gmail.com
10
- Requires-Python: >=3.9,<4.0
10
+ Requires-Python: >=3.10,<4.0
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Intended Audience :: Science/Research
14
14
  Classifier: License :: OSI Approved :: MIT License
15
15
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.9
17
16
  Classifier: Programming Language :: Python :: 3.10
18
17
  Classifier: Programming Language :: Python :: 3.11
19
18
  Classifier: Programming Language :: Python :: 3.12
@@ -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_13_0.py,sha256=p0giuWeWOvxLe22T0QXNWxjzWWqgzJ1ZetpdVCz86IY,1354
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,10 @@ 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_13_0/__init__.py,sha256=qWAsZAOL3cOMM67gNVahlcPs9pqkGU8moo4nLJOo_wU,1102
88
+ nmdc_schema/migrators/partials/migrator_from_11_11_0_to_11_13_0/migrator_from_11_11_0_to_11_13_0_part_1.py,sha256=ajPhHPDK1loTL7j_3hzBZo_EfT5gtoXlsNFmpDZCgPs,8668
89
+ nmdc_schema/migrators/partials/migrator_from_11_11_0_to_11_13_0/migrator_from_11_11_0_to_11_13_0_part_2.py,sha256=sW5JhlO2DaGh9kvI9qWJQ85eYyUo9976sBurPdZ69Kk,4858
90
+ nmdc_schema/migrators/partials/migrator_from_11_11_0_to_11_13_0/migrator_from_11_11_0_to_11_13_0_part_3.py,sha256=XKrq0jBLn6v4O96j045WkJsGubwP6ikLNyglEKH1_jE,1920
86
91
  nmdc_schema/migrators/partials/migrator_from_11_1_0_to_11_2_0/__init__.py,sha256=e-neqgmL6Zsy6h5PGmWPj9qIqrTm3yvNgo2l2i7Sduc,990
87
92
  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
93
  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 +107,18 @@ nmdc_schema/migrators/partials/migrator_from_11_9_1_to_11_10_0/__init__.py,sha25
102
107
  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
108
  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
109
  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=FMxYUGNAHHMdHY4CfRLssDF_HXydPaSgrVpibqRnUeo,1448954
106
- nmdc_schema/nmdc.py,sha256=GLanuOlLeVgIOXGLlsLPtiPTzEQAXWEAtxrkbm3fTPU,721345
107
- nmdc_schema/nmdc.schema.json,sha256=3951j1KYEfvLee7swsehE6qLQA0To0jijBQtwIdZnFM,623227
110
+ nmdc_schema/nmdc-pydantic.py,sha256=dQoo1bJBuS5Ty3XzQtY3R2ncdAXw5oG2R5hNsUlD65k,1450830
111
+ nmdc_schema/nmdc.py,sha256=2TJmzEsPmqlCmu5nDeuNp3V2CeylaoPlCPSyU1MssEc,737930
112
+ nmdc_schema/nmdc.schema.json,sha256=16LurO8g4cN9XlbNmj4gGxN3b0xoAgIA1_ZZ2ISiUhQ,630117
108
113
  nmdc_schema/nmdc_data.py,sha256=_wNKi5NDxuvvRsJEim2ialX7VJkDBJLRpiTOPpFHBm8,9608
109
- nmdc_schema/nmdc_materialized_patterns.json,sha256=6evRGXhA5Jzos-lroYwgZeXGwK5RN8Ow_tac9_0YaHM,928167
110
- nmdc_schema/nmdc_materialized_patterns.schema.json,sha256=00ORKaiyMqx-6wm98ubsCVxmcsPkDdmF1h5KS5h6z20,631510
111
- nmdc_schema/nmdc_materialized_patterns.yaml,sha256=5oLEubpb9qXkGc7f7pwAJEQ9q_V3Q6EXzG_JK6yDQK0,717666
114
+ nmdc_schema/nmdc_materialized_patterns.json,sha256=isiIXZdo0gq6mPmUY12DNL-TqkwPxPuzfHwgimPKbr4,913170
115
+ nmdc_schema/nmdc_materialized_patterns.schema.json,sha256=1eVg49IoSY3ejgEehY0KXPSA2zr_diGz2b-SdvrPPbI,639442
116
+ nmdc_schema/nmdc_materialized_patterns.yaml,sha256=c5C03aM1Vqbt5BdXe105YONT5ghe679AhVo3NDow2B8,709694
117
+ nmdc_schema/nmdc_schema_validation_plugin.py,sha256=rjtn1tYhngGyc1AV8vcT8BJ9a_MmHbcK3hRUf9dzPtA,4799
112
118
  nmdc_schema/nmdc_version.py,sha256=DsfEKnmN3LHR831WWELxyfZY6rnP9U8tfygamkrsaHY,2305
113
119
  nmdc_schema/validate_nmdc_json.py,sha256=PVJV2O1qQXMi206HaUKqRNLiLc164OpNYKPURSKN8_E,3148
114
- nmdc_schema-11.12.0rc2.dist-info/METADATA,sha256=qz4LRY0H0V-YTIETaOU9YHRdr2Ov05Znr7LvK5Vx5Jo,5902
115
- nmdc_schema-11.12.0rc2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
116
- nmdc_schema-11.12.0rc2.dist-info/entry_points.txt,sha256=Z_cdWpUrV7DjGkjfuNG5VIjevU2JzxpoWlRADmmkBxs,2150
117
- nmdc_schema-11.12.0rc2.dist-info/licenses/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
118
- nmdc_schema-11.12.0rc2.dist-info/RECORD,,
120
+ nmdc_schema-11.13.0.dist-info/METADATA,sha256=zR2pMlG9SDIDlHH3i4ptpC6QYbC2JyK3hApj3rEOaRc,5850
121
+ nmdc_schema-11.13.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
122
+ nmdc_schema-11.13.0.dist-info/entry_points.txt,sha256=-UOl7vTEjS6eaJreIu_UenULpuKAYz8JiLeuKbEqPB8,2079
123
+ nmdc_schema-11.13.0.dist-info/licenses/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
124
+ nmdc_schema-11.13.0.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