From a3a81a0c798c6c20275057b4201dec37e9c1f42a Mon Sep 17 00:00:00 2001 From: Isaac To Date: Sun, 6 Oct 2024 18:52:36 -0700 Subject: [PATCH 1/3] Rename `DANDI_LINKML_SCHEMA` to `_DANDI_LINKML_SCHEMA` --- src/dandisets_linkml_status_tools/cli/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dandisets_linkml_status_tools/cli/tools.py b/src/dandisets_linkml_status_tools/cli/tools.py index be3a8b9..9c1a1dc 100644 --- a/src/dandisets_linkml_status_tools/cli/tools.py +++ b/src/dandisets_linkml_status_tools/cli/tools.py @@ -39,7 +39,7 @@ DANDI_MODULE_NAMES = ["dandischema.models"] # The LinkML schema produced by the pydantic2linkml translator for DANDI models -DANDI_LINKML_SCHEMA = translate_defs(DANDI_MODULE_NAMES) +_DANDI_LINKML_SCHEMA = translate_defs(DANDI_MODULE_NAMES) # A callable that sorts a given iterable of strings in a case-insensitive manner isorted = partial(sorted, key=str.casefold) @@ -84,7 +84,7 @@ def __init__(self, validation_plugins: Optional[list[ValidationPlugin]] = None): validation_plugins = [JsonschemaValidationPlugin(closed=True)] self._inner_validator = Validator( - DANDI_LINKML_SCHEMA, + _DANDI_LINKML_SCHEMA, validation_plugins=validation_plugins, ) From 42c196e0b7b92ef5dd6cbd99a270f1293b01183c Mon Sep 17 00:00:00 2001 From: Isaac To Date: Sun, 6 Oct 2024 19:05:08 -0700 Subject: [PATCH 2/3] Define `get_dandi_linkml_schema()` to produce the LinkML schema for Dandi models This way, the translation of dandi models to LinkML is only done on a needed basis --- .../cli/tools.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/dandisets_linkml_status_tools/cli/tools.py b/src/dandisets_linkml_status_tools/cli/tools.py index 9c1a1dc..7c2b1cf 100644 --- a/src/dandisets_linkml_status_tools/cli/tools.py +++ b/src/dandisets_linkml_status_tools/cli/tools.py @@ -13,6 +13,7 @@ from linkml.validator import Validator from linkml.validator.plugins import JsonschemaValidationPlugin, ValidationPlugin from linkml.validator.report import ValidationResult +from linkml_runtime.linkml_model import SchemaDefinition from pydantic import TypeAdapter, ValidationError from pydantic2linkml.gen_linkml import translate_defs from yaml import dump as yaml_dump @@ -39,12 +40,26 @@ DANDI_MODULE_NAMES = ["dandischema.models"] # The LinkML schema produced by the pydantic2linkml translator for DANDI models -_DANDI_LINKML_SCHEMA = translate_defs(DANDI_MODULE_NAMES) +_DANDI_LINKML_SCHEMA: Optional[SchemaDefinition] = None # A callable that sorts a given iterable of strings in a case-insensitive manner isorted = partial(sorted, key=str.casefold) +def get_dandi_linkml_schema() -> SchemaDefinition: + """ + Get the LinkML schema produced by the pydantic2linkml translator for DANDI models + + :return: The LinkML schema + """ + global _DANDI_LINKML_SCHEMA + + if _DANDI_LINKML_SCHEMA is None: + _DANDI_LINKML_SCHEMA = translate_defs(DANDI_MODULE_NAMES) + + return _DANDI_LINKML_SCHEMA + + def pydantic_validate(dandiset_metadata: dict[str, Any]) -> str: """ Validate the given dandiset metadata against the Pydantic dandiset metadata model @@ -84,7 +99,7 @@ def __init__(self, validation_plugins: Optional[list[ValidationPlugin]] = None): validation_plugins = [JsonschemaValidationPlugin(closed=True)] self._inner_validator = Validator( - _DANDI_LINKML_SCHEMA, + get_dandi_linkml_schema(), validation_plugins=validation_plugins, ) From 507b933531d77f62d0def13ea7570cfbb0d97c67 Mon Sep 17 00:00:00 2001 From: Isaac To Date: Sun, 6 Oct 2024 20:41:19 -0700 Subject: [PATCH 3/3] Move `get_dandi_linkml_schema()` into `DandisetLinkmlValidator` as a class method This eliminates the use of a private global variable keep the schema --- .../cli/tools.py | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/dandisets_linkml_status_tools/cli/tools.py b/src/dandisets_linkml_status_tools/cli/tools.py index 7c2b1cf..08286ea 100644 --- a/src/dandisets_linkml_status_tools/cli/tools.py +++ b/src/dandisets_linkml_status_tools/cli/tools.py @@ -39,27 +39,10 @@ # The names of the collection of modules in which the DANDI models are defined DANDI_MODULE_NAMES = ["dandischema.models"] -# The LinkML schema produced by the pydantic2linkml translator for DANDI models -_DANDI_LINKML_SCHEMA: Optional[SchemaDefinition] = None - # A callable that sorts a given iterable of strings in a case-insensitive manner isorted = partial(sorted, key=str.casefold) -def get_dandi_linkml_schema() -> SchemaDefinition: - """ - Get the LinkML schema produced by the pydantic2linkml translator for DANDI models - - :return: The LinkML schema - """ - global _DANDI_LINKML_SCHEMA - - if _DANDI_LINKML_SCHEMA is None: - _DANDI_LINKML_SCHEMA = translate_defs(DANDI_MODULE_NAMES) - - return _DANDI_LINKML_SCHEMA - - def pydantic_validate(dandiset_metadata: dict[str, Any]) -> str: """ Validate the given dandiset metadata against the Pydantic dandiset metadata model @@ -85,6 +68,9 @@ class DandisetLinkmlValidator: expressed in Pydantic """ + # The LinkML schema produced by the pydantic2linkml translator for DANDI models + _dandi_linkml_schema: Optional[SchemaDefinition] = None + def __init__(self, validation_plugins: Optional[list[ValidationPlugin]] = None): """ Initialize a `DandisetLinkmlValidator` instance that wraps a LinkML validator @@ -99,10 +85,22 @@ def __init__(self, validation_plugins: Optional[list[ValidationPlugin]] = None): validation_plugins = [JsonschemaValidationPlugin(closed=True)] self._inner_validator = Validator( - get_dandi_linkml_schema(), + self.get_dandi_linkml_schema(), validation_plugins=validation_plugins, ) + @classmethod + def get_dandi_linkml_schema(cls) -> SchemaDefinition: + """ + Get the LinkML schema produced by the pydantic2linkml translator for DANDI models + + :return: The LinkML schema + """ + if cls._dandi_linkml_schema is None: + cls._dandi_linkml_schema = translate_defs(DANDI_MODULE_NAMES) + + return cls._dandi_linkml_schema + def validate(self, dandiset_metadata: dict[str, Any]) -> list[ValidationResult]: """ Validate the given dandiset metadata against the dandiset metadata model in