nmdc-schema 11.11.1__py3-none-any.whl → 11.12.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.
- nmdc_schema/migration_recursion.py +2 -0
- nmdc_schema/migrators/cli/run_migrator.py +10 -14
- nmdc_schema/migrators/helpers.py +24 -0
- nmdc_schema/migrators/migrator_from_11_11_0_to_11_12_0.py +35 -0
- nmdc_schema/migrators/partials/migrator_from_11_11_0_to_11_12_0/__init__.py +28 -0
- 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 +187 -0
- 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 +113 -0
- nmdc_schema/nmdc-pydantic.py +901 -346
- nmdc_schema/nmdc.py +283 -50
- nmdc_schema/nmdc.schema.json +185 -17
- nmdc_schema/nmdc_materialized_patterns.json +1487 -244
- nmdc_schema/nmdc_materialized_patterns.schema.json +185 -17
- nmdc_schema/nmdc_materialized_patterns.yaml +1194 -210
- nmdc_schema/nmdc_schema_validation_plugin.py +103 -0
- {nmdc_schema-11.11.1.dist-info → nmdc_schema-11.12.0.dist-info}/METADATA +1 -1
- {nmdc_schema-11.11.1.dist-info → nmdc_schema-11.12.0.dist-info}/RECORD +19 -14
- {nmdc_schema-11.11.1.dist-info → nmdc_schema-11.12.0.dist-info}/WHEEL +1 -1
- {nmdc_schema-11.11.1.dist-info → nmdc_schema-11.12.0.dist-info}/entry_points.txt +8 -0
- {nmdc_schema-11.11.1.dist-info → nmdc_schema-11.12.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -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
|
+
)
|
|
@@ -6,7 +6,7 @@ nmdc_schema/get_json_schema.py,sha256=5TFl1GCImyR5GHLK2hOz1MqqEyoRqhbukEs4x4AMYe
|
|
|
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=
|
|
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=
|
|
31
|
-
nmdc_schema/migrators/helpers.py,sha256=
|
|
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=l3CyePWflufFzSjteMv60iKpnpsaYNQIae5ICAtKZAs,4869
|
|
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=
|
|
106
|
-
nmdc_schema/nmdc.py,sha256=
|
|
107
|
-
nmdc_schema/nmdc.schema.json,sha256=
|
|
109
|
+
nmdc_schema/nmdc-pydantic.py,sha256=LHTNY4CkkQ5TDWY_BpfZ43BXjjs6bF61gKvB-5pnAck,1462437
|
|
110
|
+
nmdc_schema/nmdc.py,sha256=QERSBlgEWWwk307GS-r_eDL7Nbu2aGHHxd9Jqdhc4G8,730020
|
|
111
|
+
nmdc_schema/nmdc.schema.json,sha256=52TH3f0S0faJn5_oUH0epmdIWgQe4qpjCJNmaw3ki6c,629145
|
|
108
112
|
nmdc_schema/nmdc_data.py,sha256=_wNKi5NDxuvvRsJEim2ialX7VJkDBJLRpiTOPpFHBm8,9608
|
|
109
|
-
nmdc_schema/nmdc_materialized_patterns.json,sha256=
|
|
110
|
-
nmdc_schema/nmdc_materialized_patterns.schema.json,sha256=
|
|
111
|
-
nmdc_schema/nmdc_materialized_patterns.yaml,sha256=
|
|
113
|
+
nmdc_schema/nmdc_materialized_patterns.json,sha256=7imCTMdsoo7qNwqz-bb-0IZMCsDVYlKxRJR9yMZ8yF8,937613
|
|
114
|
+
nmdc_schema/nmdc_materialized_patterns.schema.json,sha256=aIl-4K7JczII1x64MZJnPJB0tyM_kBZHRtJeKYwMiE0,637428
|
|
115
|
+
nmdc_schema/nmdc_materialized_patterns.yaml,sha256=VrQgI0MlWoyEY4wyIoxgVDiIASS9V6o5RLk17OSsT4Q,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.
|
|
115
|
-
nmdc_schema-11.
|
|
116
|
-
nmdc_schema-11.
|
|
117
|
-
nmdc_schema-11.
|
|
118
|
-
nmdc_schema-11.
|
|
119
|
+
nmdc_schema-11.12.0.dist-info/METADATA,sha256=3vl1EW8QvikZ0zNAKPjaQBmbi3lkRfqCgDFDvHVNES8,5899
|
|
120
|
+
nmdc_schema-11.12.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
121
|
+
nmdc_schema-11.12.0.dist-info/entry_points.txt,sha256=-UOl7vTEjS6eaJreIu_UenULpuKAYz8JiLeuKbEqPB8,2079
|
|
122
|
+
nmdc_schema-11.12.0.dist-info/licenses/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
|
|
123
|
+
nmdc_schema-11.12.0.dist-info/RECORD,,
|
|
@@ -22,4 +22,12 @@ schema-pattern-linting=src.scripts.schema_pattern_linting:main
|
|
|
22
22
|
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
|
+
units-mongodb-analyze=units.scripts.mongodb_analyze_units:main
|
|
26
|
+
units-schema-convert=units.scripts.schema_convert_to_ucum:main
|
|
27
|
+
units-schema-extract=units.scripts.schema_extract_preferred_units:main
|
|
28
|
+
units-schema-extract-slot-unit-pairs=units.scripts.schema_expand_storage_units:main
|
|
29
|
+
units-schema-generate=units.scripts.schema_generate_yq_commands:main
|
|
30
|
+
units-testdata-check=units.scripts.testdata_check_has_unit:main
|
|
31
|
+
units-testdata-extract=units.scripts.testdata_extract_quantity_values:main
|
|
32
|
+
units-ucum-validate=units.scripts.ucum_validate_units:main
|
|
25
33
|
|
|
File without changes
|