linkml 1.8.7__py3-none-any.whl → 1.9.1rc2__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/common/build.py +1 -7
- linkml/generators/common/ifabsent_processor.py +20 -20
- linkml/generators/common/lifecycle.py +2 -1
- linkml/generators/common/naming.py +1 -1
- linkml/generators/common/template.py +5 -5
- linkml/generators/common/type_designators.py +1 -3
- linkml/generators/csvgen.py +3 -3
- linkml/generators/docgen/class.md.jinja2 +1 -1
- linkml/generators/docgen/enum.md.jinja2 +1 -1
- linkml/generators/docgen/schema.md.jinja2 +1 -1
- linkml/generators/docgen/slot.md.jinja2 +4 -1
- linkml/generators/docgen/subset.md.jinja2 +1 -1
- linkml/generators/docgen/type.md.jinja2 +1 -1
- linkml/generators/docgen.py +20 -25
- linkml/generators/dotgen.py +4 -4
- linkml/generators/erdiagramgen.py +7 -7
- linkml/generators/excelgen.py +2 -3
- linkml/generators/golanggen.py +2 -2
- linkml/generators/golrgen.py +3 -3
- linkml/generators/jsonldcontextgen.py +4 -4
- linkml/generators/jsonschemagen.py +5 -5
- linkml/generators/linkmlgen.py +10 -2
- linkml/generators/markdowngen.py +8 -10
- linkml/generators/mermaidclassdiagramgen.py +2 -2
- linkml/generators/oocodegen.py +10 -10
- linkml/generators/owlgen.py +19 -18
- linkml/generators/plantumlgen.py +15 -15
- linkml/generators/prefixmapgen.py +5 -5
- linkml/generators/projectgen.py +10 -10
- linkml/generators/pydanticgen/array.py +15 -21
- linkml/generators/pydanticgen/build.py +4 -4
- linkml/generators/pydanticgen/includes.py +1 -1
- linkml/generators/pydanticgen/pydanticgen.py +24 -28
- linkml/generators/pydanticgen/template.py +36 -36
- linkml/generators/pythongen.py +21 -29
- linkml/generators/rdfgen.py +2 -2
- linkml/generators/shaclgen.py +19 -10
- linkml/generators/shexgen.py +3 -3
- linkml/generators/sparqlgen.py +3 -3
- linkml/generators/sqlalchemygen.py +2 -2
- linkml/generators/terminusdbgen.py +2 -3
- linkml/generators/typescriptgen.py +3 -3
- linkml/generators/yumlgen.py +13 -13
- linkml/linter/cli.py +1 -1
- linkml/linter/config/datamodel/config.py +207 -213
- linkml/linter/config/datamodel/config.yaml +51 -3
- linkml/linter/config/default.yaml +3 -0
- linkml/linter/formatters/markdown_formatter.py +2 -2
- linkml/linter/linter.py +4 -3
- linkml/linter/rules.py +38 -19
- linkml/reporting/model.py +11 -15
- linkml/transformers/logical_model_transformer.py +9 -8
- linkml/transformers/relmodel_transformer.py +6 -6
- linkml/transformers/schema_renamer.py +2 -2
- linkml/utils/converter.py +1 -1
- linkml/utils/deprecation.py +3 -3
- linkml/utils/execute_tutorial.py +5 -6
- linkml/utils/generator.py +17 -16
- linkml/utils/helpers.py +2 -2
- linkml/utils/logictools.py +5 -4
- linkml/utils/mergeutils.py +51 -5
- linkml/utils/schema_builder.py +8 -8
- linkml/utils/schema_fixer.py +8 -8
- linkml/utils/schemaloader.py +16 -15
- linkml/utils/schemasynopsis.py +29 -29
- linkml/utils/sqlutils.py +5 -5
- linkml/utils/typereferences.py +5 -6
- linkml/utils/validation.py +2 -2
- linkml/validator/cli.py +7 -6
- linkml/validator/loaders/delimited_file_loader.py +2 -1
- linkml/validator/loaders/json_loader.py +2 -1
- linkml/validator/loaders/loader.py +2 -1
- linkml/validator/loaders/passthrough_loader.py +2 -1
- linkml/validator/loaders/yaml_loader.py +2 -1
- linkml/validator/plugins/jsonschema_validation_plugin.py +2 -1
- linkml/validator/plugins/pydantic_validation_plugin.py +2 -1
- linkml/validator/plugins/recommended_slots_plugin.py +3 -2
- linkml/validator/plugins/shacl_validation_plugin.py +2 -1
- linkml/validator/plugins/validation_plugin.py +1 -1
- linkml/validator/report.py +3 -3
- linkml/validator/validator.py +3 -2
- linkml/validators/jsonschemavalidator.py +6 -5
- linkml/workspaces/datamodel/workspaces.py +21 -26
- linkml/workspaces/example_runner.py +7 -6
- {linkml-1.8.7.dist-info → linkml-1.9.1rc2.dist-info}/METADATA +6 -9
- linkml-1.9.1rc2.dist-info/RECORD +162 -0
- {linkml-1.8.7.dist-info → linkml-1.9.1rc2.dist-info}/WHEEL +1 -1
- linkml-1.8.7.dist-info/RECORD +0 -162
- {linkml-1.8.7.dist-info → linkml-1.9.1rc2.dist-info}/LICENSE +0 -0
- {linkml-1.8.7.dist-info → linkml-1.9.1rc2.dist-info}/entry_points.txt +0 -0
linkml/generators/shaclgen.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import Callable
|
4
|
+
from typing import Callable
|
5
5
|
|
6
6
|
import click
|
7
7
|
from jsonasobj2 import JsonObj, as_dict
|
@@ -30,6 +30,8 @@ class ShaclGenerator(Generator):
|
|
30
30
|
"""parameterized suffix to be appended. No suffix per default."""
|
31
31
|
include_annotations: bool = False
|
32
32
|
"""True means include all class / slot / type annotations in generated Node or Property shapes"""
|
33
|
+
exclude_imports: bool = False
|
34
|
+
"""If True, elements from imported ontologies won't be included in the generator's output"""
|
33
35
|
generatorname = os.path.basename(__file__)
|
34
36
|
generatorversion = "0.0.1"
|
35
37
|
valid_formats = ["ttl"]
|
@@ -63,7 +65,7 @@ class ShaclGenerator(Generator):
|
|
63
65
|
for pfx in self.schema.prefixes.values():
|
64
66
|
g.bind(str(pfx.prefix_prefix), pfx.prefix_reference)
|
65
67
|
|
66
|
-
for c in sv.all_classes().values():
|
68
|
+
for c in sv.all_classes(imports=not self.exclude_imports).values():
|
67
69
|
|
68
70
|
def shape_pv(p, v):
|
69
71
|
if v is not None:
|
@@ -256,7 +258,7 @@ class ShaclGenerator(Generator):
|
|
256
258
|
else:
|
257
259
|
logger.error(f"No URI for type {rt.name}")
|
258
260
|
|
259
|
-
def _and_equals_string(self, g: Graph, func: Callable, values:
|
261
|
+
def _and_equals_string(self, g: Graph, func: Callable, values: list) -> None:
|
260
262
|
pv_node = BNode()
|
261
263
|
Collection(
|
262
264
|
g,
|
@@ -271,7 +273,7 @@ class ShaclGenerator(Generator):
|
|
271
273
|
annotations = item.annotations
|
272
274
|
# item could be a class, slot or type
|
273
275
|
# annotation type could be dict (on types) or JsonObj (on slots)
|
274
|
-
if type(annotations)
|
276
|
+
if type(annotations) is JsonObj:
|
275
277
|
annotations = as_dict(annotations)
|
276
278
|
for a in annotations.values():
|
277
279
|
# If ':' is in the tag, treat it as a CURIE, otherwise string Literal
|
@@ -281,7 +283,7 @@ class ShaclGenerator(Generator):
|
|
281
283
|
N_predicate = Literal(a["tag"], datatype=XSD.string)
|
282
284
|
# If the value is a string and ':' is in the value, treat it as a CURIE,
|
283
285
|
# otherwise treat as Literal with derived XSD datatype
|
284
|
-
if type(a["value"])
|
286
|
+
if type(a["value"]) is extended_str and ":" in a["value"]:
|
285
287
|
N_object = URIRef(sv.expand_curie(a["value"]))
|
286
288
|
else:
|
287
289
|
N_object = Literal(a["value"], datatype=self._getXSDtype(a["value"]))
|
@@ -290,19 +292,19 @@ class ShaclGenerator(Generator):
|
|
290
292
|
|
291
293
|
def _getXSDtype(self, value):
|
292
294
|
value_type = type(value)
|
293
|
-
if value_type
|
295
|
+
if value_type is bool:
|
294
296
|
return XSD.boolean
|
295
|
-
elif value_type
|
297
|
+
elif value_type is extended_str:
|
296
298
|
return XSD.string
|
297
|
-
elif value_type
|
299
|
+
elif value_type is extended_int:
|
298
300
|
return XSD.integer
|
299
|
-
elif value_type
|
301
|
+
elif value_type is extended_float:
|
300
302
|
# TODO: distinguish between xsd:decimal and xsd:double?
|
301
303
|
return XSD.decimal
|
302
304
|
else:
|
303
305
|
return None
|
304
306
|
|
305
|
-
def _and_equals_string(self, g: Graph, func: Callable, values:
|
307
|
+
def _and_equals_string(self, g: Graph, func: Callable, values: list) -> None:
|
306
308
|
pv_node = BNode()
|
307
309
|
Collection(
|
308
310
|
g,
|
@@ -364,6 +366,13 @@ def add_simple_data_type(func: Callable, r: ElementName) -> None:
|
|
364
366
|
show_default=True,
|
365
367
|
help="Use --include-annotations to include annotations of slots, types, and classes in the generated SHACL shapes.",
|
366
368
|
)
|
369
|
+
@click.option(
|
370
|
+
"--exclude-imports/--include-imports",
|
371
|
+
default=False,
|
372
|
+
show_default=True,
|
373
|
+
help="Use --exclude-imports to exclude imported elements from the generated SHACL shapes. This is useful when "
|
374
|
+
"extending a substantial ontology to avoid large output files.",
|
375
|
+
)
|
367
376
|
@click.version_option(__version__, "-V", "--version")
|
368
377
|
def cli(yamlfile, **args):
|
369
378
|
"""Generate SHACL turtle from a LinkML model"""
|
linkml/generators/shexgen.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
import os
|
4
4
|
import urllib.parse as urlparse
|
5
5
|
from dataclasses import dataclass, field
|
6
|
-
from typing import
|
6
|
+
from typing import Optional, Union
|
7
7
|
|
8
8
|
import click
|
9
9
|
from jsonasobj import as_json as as_json_1
|
@@ -40,9 +40,9 @@ class ShExGenerator(Generator):
|
|
40
40
|
|
41
41
|
# ObjectVars
|
42
42
|
shex: Schema = field(default_factory=lambda: Schema()) # ShEx Schema being generated
|
43
|
-
shapes:
|
43
|
+
shapes: list = field(default_factory=lambda: [])
|
44
44
|
shape: Optional[Shape] = None # Current shape being defined
|
45
|
-
list_shapes:
|
45
|
+
list_shapes: list[IRIREF] = field(default_factory=lambda: []) # Shapes that have been defined as lists
|
46
46
|
|
47
47
|
def __post_init__(self):
|
48
48
|
super().__post_init__()
|
linkml/generators/sparqlgen.py
CHANGED
@@ -3,7 +3,7 @@ import os
|
|
3
3
|
from collections import defaultdict
|
4
4
|
from dataclasses import dataclass
|
5
5
|
from pathlib import Path
|
6
|
-
from typing import
|
6
|
+
from typing import Optional
|
7
7
|
|
8
8
|
import click
|
9
9
|
from jinja2 import Template
|
@@ -137,7 +137,7 @@ class SparqlGenerator(Generator):
|
|
137
137
|
uses_schemaloader = False
|
138
138
|
|
139
139
|
# ObjectVars
|
140
|
-
named_graphs: Optional[
|
140
|
+
named_graphs: Optional[list[str]] = None
|
141
141
|
limit: Optional[int] = None
|
142
142
|
sparql: Optional[str] = None
|
143
143
|
|
@@ -172,7 +172,7 @@ class SparqlGenerator(Generator):
|
|
172
172
|
return self.sparql
|
173
173
|
|
174
174
|
@staticmethod
|
175
|
-
def split_sparql(sparql: str) ->
|
175
|
+
def split_sparql(sparql: str) -> dict[str, str]:
|
176
176
|
lines = sparql.split("\n")
|
177
177
|
prolog = ""
|
178
178
|
queries = defaultdict(str)
|
@@ -3,7 +3,7 @@ import os
|
|
3
3
|
from collections import defaultdict
|
4
4
|
from dataclasses import dataclass
|
5
5
|
from types import ModuleType
|
6
|
-
from typing import
|
6
|
+
from typing import Optional, Union
|
7
7
|
|
8
8
|
import click
|
9
9
|
from jinja2 import Template
|
@@ -180,7 +180,7 @@ class SQLAlchemyGenerator(Generator):
|
|
180
180
|
|
181
181
|
# TODO: move this
|
182
182
|
@staticmethod
|
183
|
-
def order_classes_by_hierarchy(sv: SchemaView) ->
|
183
|
+
def order_classes_by_hierarchy(sv: SchemaView) -> list[ClassDefinitionName]:
|
184
184
|
olist = sv.class_roots()
|
185
185
|
unprocessed = [cn for cn in sv.all_classes() if cn not in olist]
|
186
186
|
while len(unprocessed) > 0:
|
@@ -2,7 +2,6 @@ import json
|
|
2
2
|
import os
|
3
3
|
import warnings
|
4
4
|
from dataclasses import dataclass
|
5
|
-
from typing import List
|
6
5
|
|
7
6
|
import click
|
8
7
|
from linkml_runtime.linkml_model.meta import ClassDefinition, SlotDefinition
|
@@ -62,8 +61,8 @@ class TerminusdbGenerator(Generator):
|
|
62
61
|
uses_schemaloader = True
|
63
62
|
|
64
63
|
# ObjectVars
|
65
|
-
classes:
|
66
|
-
raw_additions:
|
64
|
+
classes: list = None
|
65
|
+
raw_additions: list = None
|
67
66
|
clswq: str = None
|
68
67
|
|
69
68
|
def __post_init__(self):
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import
|
4
|
+
from typing import Optional
|
5
5
|
|
6
6
|
import click
|
7
7
|
from jinja2 import Template
|
@@ -252,7 +252,7 @@ class TypescriptGenerator(OOCodeGenerator):
|
|
252
252
|
return "null"
|
253
253
|
|
254
254
|
@staticmethod
|
255
|
-
def parents(cls: ClassDefinition) ->
|
255
|
+
def parents(cls: ClassDefinition) -> list[ClassDefinitionName]:
|
256
256
|
if cls.is_a:
|
257
257
|
parents = [cls.is_a]
|
258
258
|
else:
|
@@ -262,7 +262,7 @@ class TypescriptGenerator(OOCodeGenerator):
|
|
262
262
|
def default_value_for_type(self, typ: str) -> str:
|
263
263
|
pass
|
264
264
|
|
265
|
-
def required_slots(self, cls: ClassDefinition) ->
|
265
|
+
def required_slots(self, cls: ClassDefinition) -> list[SlotDefinitionName]:
|
266
266
|
return [s for s in self.schemaview.class_slots(cls.name) if self.schemaview.induced_slot(s, cls.name).required]
|
267
267
|
|
268
268
|
|
linkml/generators/yumlgen.py
CHANGED
@@ -6,7 +6,7 @@ https://yuml.me/diagram/scruffy/class/samples
|
|
6
6
|
|
7
7
|
import os
|
8
8
|
from dataclasses import dataclass
|
9
|
-
from typing import Callable,
|
9
|
+
from typing import Callable, Optional, cast
|
10
10
|
|
11
11
|
import click
|
12
12
|
import requests
|
@@ -39,22 +39,22 @@ class YumlGenerator(Generator):
|
|
39
39
|
valid_formats = ["yuml", "png", "pdf", "jpg", "json", "svg"]
|
40
40
|
visit_all_class_slots = False
|
41
41
|
|
42
|
-
referenced: Optional[
|
43
|
-
generated: Optional[
|
44
|
-
box_generated: Optional[
|
45
|
-
associations_generated: Optional[
|
46
|
-
focus_classes: Optional[
|
47
|
-
gen_classes: Optional[
|
42
|
+
referenced: Optional[set[ClassDefinitionName]] = None # List of classes that have to be emitted
|
43
|
+
generated: Optional[set[ClassDefinitionName]] = None # List of classes that have been emitted
|
44
|
+
box_generated: Optional[set[ClassDefinitionName]] = None # Class boxes that have been emitted
|
45
|
+
associations_generated: Optional[set[ClassDefinitionName]] = None # Classes with associations generated
|
46
|
+
focus_classes: Optional[set[ClassDefinitionName]] = None # Classes to be completely filled
|
47
|
+
gen_classes: Optional[set[ClassDefinitionName]] = None # Classes to be generated
|
48
48
|
output_file_name: Optional[str] = None # Location of output file if directory used
|
49
49
|
|
50
|
-
classes:
|
50
|
+
classes: set[ClassDefinitionName] = None
|
51
51
|
directory: Optional[str] = None
|
52
52
|
diagram_name: Optional[str] = None
|
53
53
|
load_image: bool = True
|
54
54
|
|
55
55
|
def visit_schema(
|
56
56
|
self,
|
57
|
-
classes:
|
57
|
+
classes: set[ClassDefinitionName] = None,
|
58
58
|
directory: Optional[str] = None,
|
59
59
|
diagram_name: Optional[str] = None,
|
60
60
|
load_image: bool = True,
|
@@ -75,7 +75,7 @@ class YumlGenerator(Generator):
|
|
75
75
|
self.gen_classes = self.synopsis.roots.classrefs
|
76
76
|
self.referenced = self.gen_classes
|
77
77
|
self.generated = set()
|
78
|
-
yumlclassdef:
|
78
|
+
yumlclassdef: list[str] = []
|
79
79
|
while self.referenced.difference(self.generated):
|
80
80
|
cn = sorted(list(self.referenced.difference(self.generated)), reverse=True)[0]
|
81
81
|
self.generated.add(cn)
|
@@ -115,7 +115,7 @@ class YumlGenerator(Generator):
|
|
115
115
|
@param cn:
|
116
116
|
@return:
|
117
117
|
"""
|
118
|
-
slot_defs:
|
118
|
+
slot_defs: list[str] = []
|
119
119
|
if cn not in self.box_generated and (not self.focus_classes or cn in self.focus_classes):
|
120
120
|
cls = self.schema.classes[cn]
|
121
121
|
for slot in self.filtered_cls_slots(cn, all_slots=True, filtr=lambda s: s.range not in self.schema.classes):
|
@@ -142,7 +142,7 @@ class YumlGenerator(Generator):
|
|
142
142
|
|
143
143
|
# NOTE: YUML diagrams draw in the opposite order in which they are created, so we work from bottom to top and
|
144
144
|
# from right to left
|
145
|
-
assocs:
|
145
|
+
assocs: list[str] = []
|
146
146
|
if cn not in self.associations_generated and (not self.focus_classes or cn in self.focus_classes):
|
147
147
|
cls = self.schema.classes[cn]
|
148
148
|
|
@@ -222,7 +222,7 @@ class YumlGenerator(Generator):
|
|
222
222
|
cn: ClassDefinitionName,
|
223
223
|
all_slots: bool = True,
|
224
224
|
filtr: Callable[[SlotDefinition], bool] = lambda: True,
|
225
|
-
) ->
|
225
|
+
) -> list[SlotDefinition]:
|
226
226
|
"""Return the set of slots associated with the class that meet the filter criteria. Slots will be returned
|
227
227
|
in defining order, with class slots returned last
|
228
228
|
|