linkml 1.6.5__py3-none-any.whl → 1.6.6__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.
- linkml/generators/owlgen.py +44 -14
- linkml/generators/projectgen.py +3 -2
- linkml/generators/pydanticgen.py +35 -7
- linkml/generators/pythongen.py +5 -0
- linkml/utils/cli_utils.py +25 -0
- linkml/utils/generator.py +5 -32
- linkml/utils/schema_fixer.py +38 -3
- linkml/validator/validator.py +6 -1
- linkml/workspaces/example_runner.py +9 -6
- {linkml-1.6.5.dist-info → linkml-1.6.6.dist-info}/METADATA +1 -1
- {linkml-1.6.5.dist-info → linkml-1.6.6.dist-info}/RECORD +14 -13
- {linkml-1.6.5.dist-info → linkml-1.6.6.dist-info}/LICENSE +0 -0
- {linkml-1.6.5.dist-info → linkml-1.6.6.dist-info}/WHEEL +0 -0
- {linkml-1.6.5.dist-info → linkml-1.6.6.dist-info}/entry_points.txt +0 -0
linkml/generators/owlgen.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
import logging
|
3
3
|
import os
|
4
4
|
from collections import defaultdict
|
5
|
+
from copy import copy
|
5
6
|
from dataclasses import dataclass, field
|
6
7
|
from enum import Enum, unique
|
7
8
|
from typing import Any, List, Mapping, Optional, Set, Tuple, Union
|
@@ -403,6 +404,48 @@ class OwlSchemaGenerator(Generator):
|
|
403
404
|
else:
|
404
405
|
self.graph.add((subject_expr, RDFS.subClassOf, superclass_expr))
|
405
406
|
|
407
|
+
def get_own_slots(self, cls: Union[ClassDefinition, AnonymousClassExpression]) -> List[SlotDefinition]:
|
408
|
+
"""
|
409
|
+
Get the slots that are defined on a class, excluding those that are inherited.
|
410
|
+
|
411
|
+
:param cls:
|
412
|
+
:return:
|
413
|
+
"""
|
414
|
+
sv = self.schemaview
|
415
|
+
if isinstance(cls, ClassDefinition):
|
416
|
+
own_slots = (
|
417
|
+
list(cls.slot_usage.values()) + list(cls.attributes.values()) + list(cls.slot_conditions.values())
|
418
|
+
)
|
419
|
+
for slot_name in cls.slots:
|
420
|
+
# if slot_name not in cls.slot_usage:
|
421
|
+
slot = sv.get_slot(slot_name)
|
422
|
+
if slot:
|
423
|
+
own_slots.append(slot)
|
424
|
+
else:
|
425
|
+
logging.warning(f"Unknown top-level slot {slot_name}")
|
426
|
+
else:
|
427
|
+
own_slots = []
|
428
|
+
own_slots.extend(cls.slot_conditions.values())
|
429
|
+
# merge slots with the same name
|
430
|
+
slot_map = {}
|
431
|
+
for slot in own_slots:
|
432
|
+
if slot.name in slot_map:
|
433
|
+
for k, v in slot.__dict__.items():
|
434
|
+
curr = slot_map[slot.name].get(k, None)
|
435
|
+
# print(f"MERGE={slot.name}.{k} = {v} // CURR={curr}")
|
436
|
+
if v and not curr:
|
437
|
+
slot_map[slot.name][k] = v
|
438
|
+
# print(f"OVERRIDE={slot.name}, k={k}, v={v}")
|
439
|
+
else:
|
440
|
+
slot_map[slot.name] = copy(slot.__dict__)
|
441
|
+
# print(f"INIT={slot.name}, vals={slot_map[slot.name]}")
|
442
|
+
|
443
|
+
# print(f"SN={slot.name}, vals={slot_map[slot.name]}")
|
444
|
+
own_slots = [SlotDefinition(**v) for v in slot_map.values()]
|
445
|
+
# sort by name
|
446
|
+
own_slots.sort(key=lambda x: x.name)
|
447
|
+
return own_slots
|
448
|
+
|
406
449
|
def transform_class_expression(
|
407
450
|
self,
|
408
451
|
cls: Union[ClassDefinition, AnonymousClassExpression],
|
@@ -420,20 +463,7 @@ class OwlSchemaGenerator(Generator):
|
|
420
463
|
"""
|
421
464
|
graph = self.graph
|
422
465
|
sv = self.schemaview
|
423
|
-
|
424
|
-
own_slots = (
|
425
|
-
list(cls.slot_usage.values()) + list(cls.attributes.values()) + list(cls.slot_conditions.values())
|
426
|
-
)
|
427
|
-
for slot_name in cls.slots:
|
428
|
-
if slot_name not in cls.slot_usage:
|
429
|
-
slot = sv.get_slot(slot_name)
|
430
|
-
if slot:
|
431
|
-
own_slots.append(slot)
|
432
|
-
else:
|
433
|
-
own_slots = []
|
434
|
-
own_slots.extend(cls.slot_conditions.values())
|
435
|
-
# sort by name
|
436
|
-
own_slots.sort(key=lambda x: x.name)
|
466
|
+
own_slots = self.get_own_slots(cls)
|
437
467
|
owl_exprs = []
|
438
468
|
if cls.any_of:
|
439
469
|
owl_exprs.append(self._union_of([self.transform_class_expression(x) for x in cls.any_of]))
|
linkml/generators/projectgen.py
CHANGED
@@ -23,6 +23,7 @@ from linkml.generators.pythongen import PythonGenerator
|
|
23
23
|
from linkml.generators.shaclgen import ShaclGenerator
|
24
24
|
from linkml.generators.shexgen import ShExGenerator
|
25
25
|
from linkml.generators.sqlddlgen import SQLDDLGenerator
|
26
|
+
from linkml.utils.cli_utils import log_level_option
|
26
27
|
from linkml.utils.generator import Generator
|
27
28
|
|
28
29
|
PATH_FSTRING = str
|
@@ -103,7 +104,7 @@ class ProjectGenerator:
|
|
103
104
|
all_schemas = [schema_path]
|
104
105
|
else:
|
105
106
|
all_schemas = get_local_imports(schema_path, os.path.dirname(schema_path))
|
106
|
-
|
107
|
+
logging.debug(f"ALL_SCHEMAS = {all_schemas}")
|
107
108
|
for gen_name, (gen_cls, gen_path_fmt, default_gen_args) in GEN_MAP.items():
|
108
109
|
if config.includes is not None and config.includes != [] and gen_name not in config.includes:
|
109
110
|
logging.info(f"Skipping {gen_name} as not in inclusion list: {config.includes}")
|
@@ -178,6 +179,7 @@ class ProjectGenerator:
|
|
178
179
|
show_default=True,
|
179
180
|
help="Merge imports into source file",
|
180
181
|
)
|
182
|
+
@log_level_option
|
181
183
|
@click.argument("yamlfile")
|
182
184
|
@click.version_option(__version__, "-V", "--version")
|
183
185
|
def cli(
|
@@ -221,7 +223,6 @@ def cli(
|
|
221
223
|
top_class: Container
|
222
224
|
|
223
225
|
"""
|
224
|
-
logging.basicConfig(level=logging.INFO)
|
225
226
|
project_config = ProjectConfiguration()
|
226
227
|
if config_file is not None:
|
227
228
|
for k, v in yaml.safe_load(config_file).items():
|
linkml/generators/pydanticgen.py
CHANGED
@@ -44,14 +44,14 @@ from __future__ import annotations
|
|
44
44
|
from datetime import datetime, date
|
45
45
|
from enum import Enum
|
46
46
|
from typing import List, Dict, Optional, Any, Union"""
|
47
|
-
if pydantic_ver == 1:
|
47
|
+
if pydantic_ver == "1":
|
48
48
|
template += """
|
49
|
-
from pydantic import BaseModel as BaseModel, Field"""
|
50
|
-
|
49
|
+
from pydantic import BaseModel as BaseModel, Field, validator"""
|
50
|
+
elif pydantic_ver == "2":
|
51
51
|
template += """
|
52
|
-
from pydantic import BaseModel as BaseModel, ConfigDict,
|
53
|
-
|
52
|
+
from pydantic import BaseModel as BaseModel, ConfigDict, Field, field_validator"""
|
54
53
|
template += """
|
54
|
+
import re
|
55
55
|
import sys
|
56
56
|
if sys.version_info >= (3, 8):
|
57
57
|
from typing import Literal
|
@@ -134,7 +134,6 @@ class {{ c.name }}
|
|
134
134
|
{%- endif -%}
|
135
135
|
{%- if attr.title != None %}, title="{{attr.title}}"{% endif -%}
|
136
136
|
{%- if attr.description %}, description=\"\"\"{{attr.description}}\"\"\"{% endif -%}
|
137
|
-
{%- if attr.pattern %}, regex=\"{{attr.pattern}}\"{% endif -%}
|
138
137
|
{%- if attr.equals_number != None %}, le={{attr.equals_number}}, ge={{attr.equals_number}}
|
139
138
|
{%- else -%}
|
140
139
|
{%- if attr.minimum_value != None %}, ge={{attr.minimum_value}}{% endif -%}
|
@@ -144,6 +143,21 @@ class {{ c.name }}
|
|
144
143
|
{% else -%}
|
145
144
|
None
|
146
145
|
{% endfor %}
|
146
|
+
{% for attr in c.attributes.values() if c.attributes -%}
|
147
|
+
{%- if attr.pattern %}
|
148
|
+
@validator('{{attr.name}}', allow_reuse=True)
|
149
|
+
def pattern_{{attr.name}}(cls, v):
|
150
|
+
pattern=re.compile(r"{{attr.pattern}}")
|
151
|
+
if isinstance(v,list):
|
152
|
+
for element in v:
|
153
|
+
if not pattern.match(element):
|
154
|
+
raise ValueError(f"Invalid {{attr.name}} format: {element}")
|
155
|
+
elif isinstance(v,str):
|
156
|
+
if not pattern.match(v):
|
157
|
+
raise ValueError(f"Invalid {{attr.name}} format: {v}")
|
158
|
+
return v
|
159
|
+
{% endif -%}
|
160
|
+
{% endfor %}
|
147
161
|
{% endfor %}
|
148
162
|
"""
|
149
163
|
elif pydantic_ver == "2":
|
@@ -172,7 +186,6 @@ class {{ c.name }}
|
|
172
186
|
{%- endif -%}
|
173
187
|
{%- if attr.title != None %}, title="{{attr.title}}"{% endif -%}
|
174
188
|
{%- if attr.description %}, description=\"\"\"{{attr.description}}\"\"\"{% endif -%}
|
175
|
-
{%- if attr.pattern %}, pattern=\"{{attr.pattern}}\"{% endif -%}
|
176
189
|
{%- if attr.equals_number != None %}, le={{attr.equals_number}}, ge={{attr.equals_number}}
|
177
190
|
{%- else -%}
|
178
191
|
{%- if attr.minimum_value != None %}, ge={{attr.minimum_value}}{% endif -%}
|
@@ -182,6 +195,21 @@ class {{ c.name }}
|
|
182
195
|
{% else -%}
|
183
196
|
None
|
184
197
|
{% endfor %}
|
198
|
+
{% for attr in c.attributes.values() if c.attributes -%}
|
199
|
+
{%- if attr.pattern %}
|
200
|
+
@field_validator('{{attr.name}}')
|
201
|
+
def pattern_{{attr.name}}(cls, v):
|
202
|
+
pattern=re.compile(r"{{attr.pattern}}")
|
203
|
+
if isinstance(v,list):
|
204
|
+
for element in v:
|
205
|
+
if not pattern.match(element):
|
206
|
+
raise ValueError(f"Invalid {{attr.name}} format: {element}")
|
207
|
+
elif isinstance(v,str):
|
208
|
+
if not pattern.match(v):
|
209
|
+
raise ValueError(f"Invalid {{attr.name}} format: {v}")
|
210
|
+
return v
|
211
|
+
{% endif -%}
|
212
|
+
{% endfor %}
|
185
213
|
{% endfor %}
|
186
214
|
"""
|
187
215
|
|
linkml/generators/pythongen.py
CHANGED
@@ -802,6 +802,11 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
802
802
|
if self.is_class_unconstrained(self.schema.classes[slot.range]):
|
803
803
|
return ""
|
804
804
|
|
805
|
+
if slot.range in self.schema.enums:
|
806
|
+
# Open enum
|
807
|
+
if not self.schema.enums[slot.range].permissible_values:
|
808
|
+
return ""
|
809
|
+
|
805
810
|
aliased_slot_name = self.slot_name(slot.name) # Mangled name by which the slot is known in python
|
806
811
|
_, _, base_type_name = self.class_reference_type(slot, cls)
|
807
812
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
import click
|
4
|
+
|
5
|
+
LOG_LEVEL_STRINGS = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]
|
6
|
+
DEFAULT_LOG_LEVEL: str = "WARNING"
|
7
|
+
DEFAULT_LOG_LEVEL_INT: int = logging.WARNING
|
8
|
+
|
9
|
+
|
10
|
+
def log_level_option(fn):
|
11
|
+
def callback(ctx, param, value):
|
12
|
+
log_level_string = value.upper()
|
13
|
+
log_level_int = getattr(logging, log_level_string, None)
|
14
|
+
if not isinstance(log_level_int, int):
|
15
|
+
raise ValueError(f"Invalid log level: {log_level_string}")
|
16
|
+
logging.basicConfig(level=log_level_int)
|
17
|
+
|
18
|
+
return click.option(
|
19
|
+
"--log_level",
|
20
|
+
type=click.Choice(LOG_LEVEL_STRINGS),
|
21
|
+
help="Logging level",
|
22
|
+
default=DEFAULT_LOG_LEVEL,
|
23
|
+
show_default=True,
|
24
|
+
callback=callback,
|
25
|
+
)(fn)
|
linkml/utils/generator.py
CHANGED
@@ -51,13 +51,11 @@ from linkml_runtime.utils.formatutils import camelcase, underscore
|
|
51
51
|
from linkml_runtime.utils.namespaces import Namespaces
|
52
52
|
|
53
53
|
from linkml import LOCAL_METAMODEL_YAML_FILE
|
54
|
+
from linkml.utils.cli_utils import DEFAULT_LOG_LEVEL_INT, log_level_option
|
54
55
|
from linkml.utils.mergeutils import alias_root
|
55
56
|
from linkml.utils.schemaloader import SchemaLoader
|
56
57
|
from linkml.utils.typereferences import References
|
57
58
|
|
58
|
-
DEFAULT_LOG_LEVEL: str = "WARNING"
|
59
|
-
DEFAULT_LOG_LEVEL_INT: int = logging.WARNING
|
60
|
-
|
61
59
|
|
62
60
|
@lru_cache
|
63
61
|
def _resolved_metamodel(mergeimports):
|
@@ -872,32 +870,16 @@ class Generator(metaclass=abc.ABCMeta):
|
|
872
870
|
|
873
871
|
|
874
872
|
def shared_arguments(g: Type[Generator]) -> Callable[[Command], Command]:
|
875
|
-
_LOG_LEVEL_STRINGS = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]
|
876
|
-
|
877
|
-
def _log_level_string_to_int(log_level_string: str) -> int:
|
878
|
-
log_level_string = log_level_string.upper()
|
879
|
-
level = [e for e in log_level_string if e.startswith(log_level_string)]
|
880
|
-
if not level:
|
881
|
-
pass
|
882
|
-
log_level_int = getattr(logging, log_level_string[0], logging.INFO)
|
883
|
-
assert isinstance(log_level_int, int)
|
884
|
-
return log_level_int
|
885
|
-
|
886
873
|
def verbosity_callback(ctx, param, verbose):
|
887
874
|
if verbose >= 2:
|
888
|
-
logging.basicConfig(level=logging.DEBUG)
|
875
|
+
logging.basicConfig(level=logging.DEBUG, force=True)
|
889
876
|
elif verbose == 1:
|
890
|
-
logging.basicConfig(level=logging.INFO)
|
891
|
-
else:
|
892
|
-
logging.basicConfig(level=logging.WARNING)
|
877
|
+
logging.basicConfig(level=logging.INFO, force=True)
|
893
878
|
|
894
879
|
def stacktrace_callback(ctx, param, stacktrace):
|
895
880
|
if not stacktrace:
|
896
881
|
sys.tracebacklimit = 0
|
897
882
|
|
898
|
-
def log_level_callback(ctx, param, value):
|
899
|
-
logging.basicConfig(level=_log_level_string_to_int(value))
|
900
|
-
|
901
883
|
def decorator(f: Command) -> Command:
|
902
884
|
f.params.append(Argument(("yamlfile",), type=click.Path(exists=True, dir_okay=False)))
|
903
885
|
f.params.append(
|
@@ -926,21 +908,12 @@ def shared_arguments(g: Type[Generator]) -> Callable[[Command], Command]:
|
|
926
908
|
)
|
927
909
|
)
|
928
910
|
f.params.append(Option(("--importmap", "-im"), type=click.File(), help="Import mapping file"))
|
929
|
-
f
|
930
|
-
Option(
|
931
|
-
("--log_level",),
|
932
|
-
type=click.Choice(_LOG_LEVEL_STRINGS),
|
933
|
-
help="Logging level",
|
934
|
-
default=DEFAULT_LOG_LEVEL,
|
935
|
-
show_default=True,
|
936
|
-
callback=log_level_callback,
|
937
|
-
)
|
938
|
-
)
|
911
|
+
log_level_option(f)
|
939
912
|
f.params.append(
|
940
913
|
Option(
|
941
914
|
("--verbose", "-v"),
|
942
915
|
count=True,
|
943
|
-
help="
|
916
|
+
help="Verbosity. Takes precedence over --log_level.",
|
944
917
|
callback=verbosity_callback,
|
945
918
|
)
|
946
919
|
)
|
linkml/utils/schema_fixer.py
CHANGED
@@ -3,7 +3,7 @@ import re
|
|
3
3
|
from collections import defaultdict
|
4
4
|
from copy import copy
|
5
5
|
from dataclasses import dataclass
|
6
|
-
from typing import Any, Callable, Dict, List, Union
|
6
|
+
from typing import Any, Callable, Dict, List, Optional, Union
|
7
7
|
|
8
8
|
import click
|
9
9
|
import yaml
|
@@ -319,15 +319,16 @@ class SchemaFixer:
|
|
319
319
|
schema_dict: Dict[str, Any] = None,
|
320
320
|
rules: Dict[str, Callable] = None,
|
321
321
|
imports=False,
|
322
|
+
preserve_original_using: Optional[str] = None,
|
322
323
|
) -> Union[YAMLRoot, Dict]:
|
323
324
|
"""
|
324
325
|
Changes element names to conform to naming conventions.
|
325
326
|
|
326
|
-
|
327
327
|
:param schema: input schema
|
328
328
|
:param schema_dict: if specified, the transformation will happen on this dictionary object
|
329
329
|
:param rules: mappings between index slots and functions that normalize names
|
330
330
|
:param imports: if True, all that imported modules are also fixed
|
331
|
+
:param preserve_original_using: if specified, the original name will be preserved in this slot
|
331
332
|
:return:
|
332
333
|
"""
|
333
334
|
if rules is None:
|
@@ -339,6 +340,7 @@ class SchemaFixer:
|
|
339
340
|
}
|
340
341
|
fixes = {}
|
341
342
|
sv = SchemaView(schema)
|
343
|
+
preserved = []
|
342
344
|
for n, e in sv.all_elements(imports=imports).items():
|
343
345
|
if e.from_schema == "https://w3id.org/linkml/types":
|
344
346
|
continue
|
@@ -348,9 +350,35 @@ class SchemaFixer:
|
|
348
350
|
normalized = func(n)
|
349
351
|
if normalized != n:
|
350
352
|
fixes[n] = normalized
|
353
|
+
if preserve_original_using is not None:
|
354
|
+
preserved.append((typ, normalized, n))
|
355
|
+
# if preserve_original_using is not None:
|
356
|
+
# setattr(e, preserve_original_using, n)
|
357
|
+
# print(f"SETTING {typ} {e.name}.{preserve_original_using} = {n}")
|
351
358
|
if schema_dict is not None:
|
352
359
|
schema = schema_dict
|
353
|
-
|
360
|
+
schema = yaml_rewrite(schema, fixes)
|
361
|
+
for typ, normalized, original in preserved:
|
362
|
+
pathmap = {
|
363
|
+
ClassDefinition.__name__: "classes",
|
364
|
+
TypeDefinition.__name__: "types",
|
365
|
+
SlotDefinition.__name__: "slots",
|
366
|
+
EnumDefinition.__name__: "enums",
|
367
|
+
}
|
368
|
+
if isinstance(schema, dict):
|
369
|
+
path = schema[pathmap[typ]]
|
370
|
+
if normalized not in path:
|
371
|
+
logger.warning(f"Cannot find {typ} {normalized} in {pathmap[typ]}")
|
372
|
+
continue
|
373
|
+
e = path[normalized]
|
374
|
+
if preserve_original_using not in e:
|
375
|
+
path[normalized][preserve_original_using] = original
|
376
|
+
else:
|
377
|
+
path = getattr(schema, pathmap[typ])
|
378
|
+
e = path[normalized]
|
379
|
+
if not getattr(e, preserve_original_using, None):
|
380
|
+
setattr(e, preserve_original_using, original)
|
381
|
+
return schema
|
354
382
|
|
355
383
|
|
356
384
|
@click.group()
|
@@ -376,6 +404,13 @@ def main(verbose: int, quiet: bool):
|
|
376
404
|
show_default=True,
|
377
405
|
help="Apply fix to referenced elements from modules",
|
378
406
|
)
|
407
|
+
@click.option(
|
408
|
+
"--preserve-original-using",
|
409
|
+
"-P",
|
410
|
+
default=None,
|
411
|
+
show_default=True,
|
412
|
+
help="If specified, original name will be preserved in this slot (e.g. title)",
|
413
|
+
)
|
379
414
|
def fix_names(input_schema, **kwargs):
|
380
415
|
"""Fix element names to conform to naming conventions"""
|
381
416
|
with open(input_schema) as f:
|
linkml/validator/validator.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from functools import lru_cache
|
1
2
|
from pathlib import Path
|
2
3
|
from typing import Any, Iterator, List, Optional, TextIO, Union
|
3
4
|
|
@@ -95,7 +96,7 @@ class Validator:
|
|
95
96
|
if not self._validation_plugins:
|
96
97
|
return []
|
97
98
|
|
98
|
-
context =
|
99
|
+
context = self._context(target_class)
|
99
100
|
|
100
101
|
for plugin in self._validation_plugins:
|
101
102
|
plugin.pre_process(context)
|
@@ -117,3 +118,7 @@ class Validator:
|
|
117
118
|
|
118
119
|
for plugin in self._validation_plugins:
|
119
120
|
plugin.post_process(context)
|
121
|
+
|
122
|
+
@lru_cache
|
123
|
+
def _context(self, target_class: Optional[str] = None) -> ValidationContext:
|
124
|
+
return ValidationContext(self._schema, target_class)
|
@@ -20,8 +20,7 @@ from linkml_runtime.linkml_model import ElementName
|
|
20
20
|
from linkml_runtime.utils.formatutils import camelcase
|
21
21
|
|
22
22
|
from linkml.generators.pythongen import PythonGenerator
|
23
|
-
from linkml.
|
24
|
-
from linkml.validators import JsonSchemaDataValidator
|
23
|
+
from linkml.validator import Validator, _get_default_validator
|
25
24
|
|
26
25
|
|
27
26
|
@dataclass
|
@@ -77,7 +76,7 @@ class ExampleRunner:
|
|
77
76
|
prefix_map: Optional[Mapping[str, str]] = None
|
78
77
|
"""Custom prefix map, for emitting RDF/turtle."""
|
79
78
|
|
80
|
-
_validator: Optional[
|
79
|
+
_validator: Optional[Validator] = None
|
81
80
|
|
82
81
|
expand_dicts: bool = None
|
83
82
|
"""If true, then expand all dicts prior to validation."""
|
@@ -101,14 +100,14 @@ class ExampleRunner:
|
|
101
100
|
return self._python_module
|
102
101
|
|
103
102
|
@property
|
104
|
-
def validator(self) ->
|
103
|
+
def validator(self) -> Validator:
|
105
104
|
"""
|
106
105
|
Get the current validator
|
107
106
|
|
108
107
|
:return:
|
109
108
|
"""
|
110
109
|
if self._validator is None:
|
111
|
-
self._validator =
|
110
|
+
self._validator = _get_default_validator(self.schemaview.schema)
|
112
111
|
return self._validator
|
113
112
|
|
114
113
|
def process_examples(self):
|
@@ -179,7 +178,11 @@ class ExampleRunner:
|
|
179
178
|
summary.add(f"## {stem}", "### Input", "```yaml", f"{yaml.dump(input_dict)}", "```")
|
180
179
|
success = True
|
181
180
|
try:
|
182
|
-
validator.
|
181
|
+
report = validator.validate(input_dict, tc)
|
182
|
+
if report.results:
|
183
|
+
raise Exception(
|
184
|
+
"\n".join(f"[{result.severity.value}] {result.message}" for result in report.results)
|
185
|
+
)
|
183
186
|
# json validation is incomplete: also try object instantiation
|
184
187
|
self._load_from_dict(input_dict, target_class=tc)
|
185
188
|
except Exception as e:
|
@@ -34,13 +34,13 @@ linkml/generators/linkmlgen.py,sha256=QhIPA1v2g_g5fien3ZKN-L6TkDk3t7puVFrcoEnwkw
|
|
34
34
|
linkml/generators/markdowngen.py,sha256=ZPLahEPjWsrAsKq4CHbVDXeVd0n1NO-2STs068-g0Ac,32948
|
35
35
|
linkml/generators/namespacegen.py,sha256=vVcIyM0zlKd7XRvtdzwTwHjG4Pg49801gy4FUmjJlqQ,6450
|
36
36
|
linkml/generators/oocodegen.py,sha256=l-5zck_NNAUxJiApJrnDPkqxCv3b6v5s4hC_smelszU,7620
|
37
|
-
linkml/generators/owlgen.py,sha256=
|
37
|
+
linkml/generators/owlgen.py,sha256=omOfL5oKHeQs-JARbGbTvydZ6DX4Bzyv5pukgW02kds,52419
|
38
38
|
linkml/generators/plantumlgen.py,sha256=Vs__5x9ioiT4IBTbvZUpgT8MsYJ0amfBL64MB_nmQPc,14870
|
39
39
|
linkml/generators/prefixmapgen.py,sha256=JJ7hgzuqKVfFZrbDV76Dk8dR2NHsmpp-eNUAspXkfwA,4626
|
40
|
-
linkml/generators/projectgen.py,sha256=
|
40
|
+
linkml/generators/projectgen.py,sha256=g3JR2oXPM_QXhWUGukP9ts1P7tqxIeABaRdv130gbo4,9578
|
41
41
|
linkml/generators/protogen.py,sha256=9YfxBZkQdBWwsUbstxEUR4xRWNuAKSfz9zXPhgIYePU,2328
|
42
|
-
linkml/generators/pydanticgen.py,sha256=
|
43
|
-
linkml/generators/pythongen.py,sha256=
|
42
|
+
linkml/generators/pydanticgen.py,sha256=RoFgX3-_8cx70Q3sUmSrZc0zTHbS0d55HgQp45U7fb4,24872
|
43
|
+
linkml/generators/pythongen.py,sha256=yGYlRJ4rNm2QQLFDjyuUnqCyKlzz-b3eSOhkSu8aCwI,52491
|
44
44
|
linkml/generators/rdfgen.py,sha256=LxzYBaFEkV7rlf54nWv_6H6AGcWMRXwkaeVXq9VYEc8,2693
|
45
45
|
linkml/generators/shaclgen.py,sha256=KxNmDZW2ciCuSqUhJ65TxLTjF8jME1FmN5SaWJCuW9k,8662
|
46
46
|
linkml/generators/shexgen.py,sha256=Awtn5SyjS-TUcVCwMdT0F7hNO4K8VcSCYBaFru45Mwg,8994
|
@@ -82,18 +82,19 @@ linkml/transformers/model_transformer.py,sha256=tK_MpRDI-q2qfe8KHT6qJHP8ZruKjYx1
|
|
82
82
|
linkml/transformers/relmodel_transformer.py,sha256=hRUVtH4gylDssOXoWvVxTetF9ESbITrAZOFu53b_Eg0,17836
|
83
83
|
linkml/transformers/schema_renamer.py,sha256=Cr18TyktX64b5iFh5V6R_ILPVzXjbDYVDDZQyqFiAv8,5271
|
84
84
|
linkml/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
85
|
+
linkml/utils/cli_utils.py,sha256=MdVbox1qr6kDUHUCWAmFhV-D6ebs_nn8vVwB8KDQfew,742
|
85
86
|
linkml/utils/converter.py,sha256=rdhCI7Tsjddr3o1rVBfMq5gQubk_GE6fqlBBmyxI5_M,6270
|
86
87
|
linkml/utils/datautils.py,sha256=2XWM9LBSVp8v3SwIZECrX3SjDUYzdnP-syjp6YdL89E,3734
|
87
88
|
linkml/utils/datavalidator.py,sha256=kBdWaVi8IZT1bOwEJgJYx-wZAb_PTBObB9nHpYORfKA,472
|
88
89
|
linkml/utils/execute_tutorial.py,sha256=T4kHTSyz3ItJGEUZxVjR-3yLVKnOr5Ix4NMGE47-IuE,6912
|
89
|
-
linkml/utils/generator.py,sha256=
|
90
|
+
linkml/utils/generator.py,sha256=WAlP_gfZfAZYNklsh8l4GtiWZ338kjLg7xpQAANgUNg,38217
|
90
91
|
linkml/utils/helpers.py,sha256=yR8n4zFA5wPcYC7xzRuNF3wO16vG80v6j7DM3qTNmIc,447
|
91
92
|
linkml/utils/ifabsent_functions.py,sha256=FZwceqwlq81lMPDsdNfSHhtzDXSf8F4cbbhRdnDzjss,5765
|
92
93
|
linkml/utils/logictools.py,sha256=GSmBiobC49TcQjE08RtXEE3JwJEOV7eEREio25uJiFs,21184
|
93
94
|
linkml/utils/mergeutils.py,sha256=QVm2iQB4v_L2rSvPBsPe9C865R03BgV3TzlPoTTTwWQ,9044
|
94
95
|
linkml/utils/rawloader.py,sha256=QB7Rdvy4o4ZJEWBWa2_2xzz2TOh_6Oe4slvUn8IBVIc,4329
|
95
96
|
linkml/utils/schema_builder.py,sha256=WLSit3J4lTifaFLLWTwjqIRiTru1pqvTIUuC1TrxS6Y,9902
|
96
|
-
linkml/utils/schema_fixer.py,sha256=
|
97
|
+
linkml/utils/schema_fixer.py,sha256=ajsxpwD4yMjDk1iDtoKJTsa34SIqGshWxlnSNXVZ52w,16745
|
97
98
|
linkml/utils/schemaloader.py,sha256=bBSTqimMDTFH2FcKtRz99dKNJzV_myPsZSkIFp_6-A0,46421
|
98
99
|
linkml/utils/schemasynopsis.py,sha256=6NKa89bkZfZQE9QM0St-6xQcrsHPkYmBgnnWnlgAcQ4,18455
|
99
100
|
linkml/utils/sqlutils.py,sha256=86XeEbfY0Dk-EObw4q5-dxyzSeBtmIhjqqyDcR8ALS0,16591
|
@@ -114,7 +115,7 @@ linkml/validator/plugins/recommended_slots_plugin.py,sha256=kOdoYQyye47nLA7BjorV
|
|
114
115
|
linkml/validator/plugins/validation_plugin.py,sha256=9SMHF8b2bgG9-8351e8bY676e0A4aEBJSXvMjMF5kXg,1548
|
115
116
|
linkml/validator/report.py,sha256=kkkuh-IZF9--cO-2wGjwP3PDLvOcjjvC8AOlxXUIOAM,870
|
116
117
|
linkml/validator/validation_context.py,sha256=MmOwLk4cF_Cy7fPdFK61Eti3c3dgzKSIu6r_PmkkoZs,2388
|
117
|
-
linkml/validator/validator.py,sha256=
|
118
|
+
linkml/validator/validator.py,sha256=sdWbAOlnNYQWnZSEIuLpGQqH3W4cNq_8M_CdLtsNMH0,5648
|
118
119
|
linkml/validators/__init__.py,sha256=43W3J5NPKhwa3ZFHLRYsJMocwQKWGYCF9Ki9r0ccGbc,202
|
119
120
|
linkml/validators/jsonschemavalidator.py,sha256=_v0finzU2RGPC5xo0CylYge9XkY7oAigcly2SKLwFuI,7865
|
120
121
|
linkml/validators/sparqlvalidator.py,sha256=JowuZ5KxmWkldgWIXAb8DJi7YCPm8x3it0QkgM4lSi0,4612
|
@@ -122,9 +123,9 @@ linkml/workspaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
122
123
|
linkml/workspaces/datamodel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
123
124
|
linkml/workspaces/datamodel/workspaces.py,sha256=4HdkqweGNfMPqnB1_Onc9DcTfkhoagTRcqruh08nRoI,14905
|
124
125
|
linkml/workspaces/datamodel/workspaces.yaml,sha256=EjVrwPpeRZqJRjuGyyDRxxFzuv55SiLIXPBRUG6HStU,4233
|
125
|
-
linkml/workspaces/example_runner.py,sha256=
|
126
|
-
linkml-1.6.
|
127
|
-
linkml-1.6.
|
128
|
-
linkml-1.6.
|
129
|
-
linkml-1.6.
|
130
|
-
linkml-1.6.
|
126
|
+
linkml/workspaces/example_runner.py,sha256=uumXyPZ7xUJSZyRtjDP4TCCxgKSSOfebpufXc0_l0jY,11610
|
127
|
+
linkml-1.6.6.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
|
128
|
+
linkml-1.6.6.dist-info/LICENSE,sha256=kORMoywK6j9_iy0UvLR-a80P1Rvc9AOM4gsKlUNZABg,535
|
129
|
+
linkml-1.6.6.dist-info/entry_points.txt,sha256=za8r49Z5gcz3rAYTZLbxw5EPZr1rGuxSe1uiRUpf8R0,2143
|
130
|
+
linkml-1.6.6.dist-info/METADATA,sha256=TztvtOceZ4FBx8MPbnRdKJT2xLuWbBb_GOoA7hXLJsY,3496
|
131
|
+
linkml-1.6.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|