linkml 1.8.1__py3-none-any.whl → 1.8.3__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/cli/__init__.py +0 -0
- linkml/cli/__main__.py +4 -0
- linkml/cli/main.py +130 -0
- linkml/generators/common/build.py +105 -0
- linkml/generators/common/ifabsent_processor.py +286 -0
- linkml/generators/common/lifecycle.py +124 -0
- linkml/generators/common/template.py +89 -0
- linkml/generators/csvgen.py +1 -1
- linkml/generators/docgen/slot.md.jinja2 +4 -0
- linkml/generators/docgen.py +1 -1
- linkml/generators/dotgen.py +1 -1
- linkml/generators/erdiagramgen.py +1 -1
- linkml/generators/excelgen.py +1 -1
- linkml/generators/golanggen.py +1 -1
- linkml/generators/golrgen.py +1 -1
- linkml/generators/graphqlgen.py +1 -1
- linkml/generators/javagen.py +1 -1
- linkml/generators/jsonldcontextgen.py +4 -5
- linkml/generators/jsonldgen.py +1 -1
- linkml/generators/jsonschemagen.py +69 -22
- linkml/generators/linkmlgen.py +1 -1
- linkml/generators/markdowngen.py +1 -1
- linkml/generators/namespacegen.py +1 -1
- linkml/generators/oocodegen.py +2 -1
- linkml/generators/owlgen.py +1 -1
- linkml/generators/plantumlgen.py +1 -1
- linkml/generators/prefixmapgen.py +1 -1
- linkml/generators/projectgen.py +1 -1
- linkml/generators/protogen.py +1 -1
- linkml/generators/pydanticgen/__init__.py +8 -3
- linkml/generators/pydanticgen/array.py +114 -194
- linkml/generators/pydanticgen/build.py +64 -25
- linkml/generators/pydanticgen/includes.py +1 -31
- linkml/generators/pydanticgen/pydanticgen.py +621 -276
- linkml/generators/pydanticgen/template.py +152 -184
- linkml/generators/pydanticgen/templates/attribute.py.jinja +9 -7
- linkml/generators/pydanticgen/templates/base_model.py.jinja +0 -13
- linkml/generators/pydanticgen/templates/class.py.jinja +2 -2
- linkml/generators/pydanticgen/templates/footer.py.jinja +2 -10
- linkml/generators/pydanticgen/templates/module.py.jinja +2 -2
- linkml/generators/pydanticgen/templates/validator.py.jinja +0 -4
- linkml/generators/python/__init__.py +1 -0
- linkml/generators/python/python_ifabsent_processor.py +92 -0
- linkml/generators/pythongen.py +19 -23
- linkml/generators/rdfgen.py +1 -1
- linkml/generators/shacl/__init__.py +1 -3
- linkml/generators/shacl/shacl_data_type.py +1 -1
- linkml/generators/shacl/shacl_ifabsent_processor.py +89 -0
- linkml/generators/shaclgen.py +11 -5
- linkml/generators/shexgen.py +1 -1
- linkml/generators/sparqlgen.py +1 -1
- linkml/generators/sqlalchemygen.py +1 -1
- linkml/generators/sqltablegen.py +1 -1
- linkml/generators/sssomgen.py +1 -1
- linkml/generators/summarygen.py +1 -1
- linkml/generators/terminusdbgen.py +7 -4
- linkml/generators/typescriptgen.py +1 -1
- linkml/generators/yamlgen.py +1 -1
- linkml/generators/yumlgen.py +1 -1
- linkml/linter/cli.py +1 -1
- linkml/transformers/logical_model_transformer.py +117 -18
- linkml/utils/converter.py +1 -1
- linkml/utils/execute_tutorial.py +2 -0
- linkml/utils/logictools.py +142 -29
- linkml/utils/schema_builder.py +7 -6
- linkml/utils/schema_fixer.py +1 -1
- linkml/utils/sqlutils.py +1 -1
- linkml/validator/cli.py +4 -1
- linkml/validators/jsonschemavalidator.py +1 -1
- linkml/validators/sparqlvalidator.py +1 -1
- linkml/workspaces/example_runner.py +1 -1
- {linkml-1.8.1.dist-info → linkml-1.8.3.dist-info}/METADATA +2 -2
- {linkml-1.8.1.dist-info → linkml-1.8.3.dist-info}/RECORD +76 -68
- {linkml-1.8.1.dist-info → linkml-1.8.3.dist-info}/entry_points.txt +1 -1
- linkml/generators/shacl/ifabsent_processor.py +0 -59
- linkml/utils/ifabsent_functions.py +0 -138
- {linkml-1.8.1.dist-info → linkml-1.8.3.dist-info}/LICENSE +0 -0
- {linkml-1.8.1.dist-info → linkml-1.8.3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
from linkml_runtime.linkml_model import (
|
2
|
+
ClassDefinition,
|
3
|
+
EnumDefinitionName,
|
4
|
+
SlotDefinition,
|
5
|
+
)
|
6
|
+
|
7
|
+
from linkml.generators.common.ifabsent_processor import IfAbsentProcessor
|
8
|
+
|
9
|
+
|
10
|
+
class PythonIfAbsentProcessor(IfAbsentProcessor):
|
11
|
+
UNIMPLEMENTED_DEFAULT_VALUES = ["class_curie", "class_uri", "slot_uri", "slot_curie", "default_range", "default_ns"]
|
12
|
+
|
13
|
+
def map_custom_default_values(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition) -> (bool, str):
|
14
|
+
if default_value in self.UNIMPLEMENTED_DEFAULT_VALUES:
|
15
|
+
return True, None
|
16
|
+
|
17
|
+
if default_value == "bnode":
|
18
|
+
return True, "bnode()"
|
19
|
+
|
20
|
+
return False, None
|
21
|
+
|
22
|
+
def map_string_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
23
|
+
return self._strval(default_value)
|
24
|
+
|
25
|
+
def map_boolean_true_default_value(self, slot: SlotDefinition, cls: ClassDefinition):
|
26
|
+
return "True"
|
27
|
+
|
28
|
+
def map_boolean_false_default_value(self, slot: SlotDefinition, cls: ClassDefinition):
|
29
|
+
return "False"
|
30
|
+
|
31
|
+
def map_integer_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
32
|
+
return default_value
|
33
|
+
|
34
|
+
def map_float_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
35
|
+
return default_value
|
36
|
+
|
37
|
+
def map_double_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
38
|
+
return default_value
|
39
|
+
|
40
|
+
def map_decimal_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
41
|
+
return default_value
|
42
|
+
|
43
|
+
def map_time_default_value(self, hour: str, minutes: str, seconds: str, slot: SlotDefinition, cls: ClassDefinition):
|
44
|
+
return f"time({int(hour)}, {int(minutes)}, {int(seconds)})"
|
45
|
+
|
46
|
+
def map_date_default_value(self, year: str, month: str, day: str, slot: SlotDefinition, cls: ClassDefinition):
|
47
|
+
return f"date({int(year)}, {int(month)}, {int(day)})"
|
48
|
+
|
49
|
+
def map_datetime_default_value(
|
50
|
+
self,
|
51
|
+
year: str,
|
52
|
+
month: str,
|
53
|
+
day: str,
|
54
|
+
hour: str,
|
55
|
+
minutes: str,
|
56
|
+
seconds: str,
|
57
|
+
slot: SlotDefinition,
|
58
|
+
cls: ClassDefinition,
|
59
|
+
):
|
60
|
+
return f"datetime({int(year)}, {int(month)}, {int(day)}, " f"{int(hour)}, {int(minutes)}, {int(seconds)})"
|
61
|
+
|
62
|
+
def map_uri_or_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
63
|
+
return self._uri_for(default_value)
|
64
|
+
|
65
|
+
def map_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
66
|
+
return self._uri_for(default_value)
|
67
|
+
|
68
|
+
def map_uri_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
69
|
+
return self._uri_for(default_value)
|
70
|
+
|
71
|
+
def map_enum_default_value(
|
72
|
+
self, enum_name: EnumDefinitionName, permissible_value_name: str, slot: SlotDefinition, cls: ClassDefinition
|
73
|
+
):
|
74
|
+
return f"{enum_name}.{permissible_value_name}"
|
75
|
+
|
76
|
+
def map_nc_name_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
77
|
+
raise NotImplementedError()
|
78
|
+
|
79
|
+
def map_object_identifier_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
80
|
+
raise NotImplementedError()
|
81
|
+
|
82
|
+
def map_node_identifier_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
83
|
+
raise NotImplementedError()
|
84
|
+
|
85
|
+
def map_json_pointer_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
86
|
+
raise NotImplementedError()
|
87
|
+
|
88
|
+
def map_json_path_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
89
|
+
raise NotImplementedError()
|
90
|
+
|
91
|
+
def map_sparql_path_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
92
|
+
raise NotImplementedError()
|
linkml/generators/pythongen.py
CHANGED
@@ -29,8 +29,8 @@ from rdflib import URIRef
|
|
29
29
|
|
30
30
|
import linkml
|
31
31
|
from linkml._version import __version__
|
32
|
+
from linkml.generators.python.python_ifabsent_processor import PythonIfAbsentProcessor
|
32
33
|
from linkml.utils.generator import Generator, shared_arguments
|
33
|
-
from linkml.utils.ifabsent_functions import ifabsent_postinit_declaration, ifabsent_value_declaration
|
34
34
|
|
35
35
|
|
36
36
|
@dataclass
|
@@ -54,12 +54,23 @@ class PythonGenerator(Generator):
|
|
54
54
|
gen_slots: bool = True
|
55
55
|
genmeta: bool = False
|
56
56
|
emit_metadata: bool = True
|
57
|
+
dataclass_repr: bool = False
|
58
|
+
"""
|
59
|
+
Whether generated dataclasses should also generate a default __repr__ method.
|
60
|
+
|
61
|
+
Default ``False`` so that the parent :class:`linkml_runtime.utils.yamlutils.YAMLRoot` 's
|
62
|
+
``__repr__`` method is inherited for model pretty printing.
|
63
|
+
|
64
|
+
References:
|
65
|
+
- https://docs.python.org/3/library/dataclasses.html#dataclasses.dataclass
|
66
|
+
"""
|
57
67
|
|
58
68
|
def __post_init__(self) -> None:
|
59
69
|
if isinstance(self.schema, Path):
|
60
70
|
self.schema = str(self.schema)
|
61
71
|
self.sourcefile = self.schema
|
62
72
|
self.schemaview = SchemaView(self.schema, base_dir=self.base_dir)
|
73
|
+
self.ifabsent_processor = PythonIfAbsentProcessor(self.schemaview)
|
63
74
|
super().__post_init__()
|
64
75
|
if self.format is None:
|
65
76
|
self.format = self.valid_formats[0]
|
@@ -143,7 +154,7 @@ import re
|
|
143
154
|
from jsonasobj2 import JsonObj, as_dict
|
144
155
|
from typing import Optional, List, Union, Dict, ClassVar, Any
|
145
156
|
from dataclasses import dataclass
|
146
|
-
from datetime import date, datetime
|
157
|
+
from datetime import date, datetime, time
|
147
158
|
{enumimports}
|
148
159
|
from linkml_runtime.utils.slot import Slot
|
149
160
|
from linkml_runtime.utils.metamodelcore import empty_list, empty_dict, bnode
|
@@ -388,7 +399,7 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
388
399
|
return f"\n{self.class_or_type_name(cls.name)} = Any"
|
389
400
|
|
390
401
|
cd_str = (
|
391
|
-
("\n@dataclass" if slotdefs else "")
|
402
|
+
(f"\n@dataclass(repr={self.dataclass_repr})" if slotdefs else "")
|
392
403
|
+ f"\nclass {self.class_or_type_name(cls.name)}{parentref}:{wrapped_description}"
|
393
404
|
+ f"{self.gen_inherited_slots(cls)}"
|
394
405
|
+ f"{self.gen_class_meta(cls)}"
|
@@ -505,7 +516,7 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
505
516
|
|
506
517
|
return "\n\t".join(initializers)
|
507
518
|
|
508
|
-
def gen_class_variable(self, cls: ClassDefinition, slot: SlotDefinition, can_be_positional: bool) -> str:
|
519
|
+
def gen_class_variable(self, cls: ClassDefinition, slot: SlotDefinition, can_be_positional: bool = False) -> str:
|
509
520
|
"""
|
510
521
|
Generate a class variable declaration for the supplied slot. Note: the can_be_positional attribute works,
|
511
522
|
but it makes tag/value lists unduly complex, as you can't load them with tag=..., value=... -- you HAVE
|
@@ -517,12 +528,9 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
517
528
|
:param can_be_positional: True means that positional parameters are allowed.
|
518
529
|
:return: Initializer string
|
519
530
|
"""
|
520
|
-
can_be_positional = False # Force everything to be tag values
|
521
531
|
slotname = self.slot_name(slot.name)
|
522
532
|
slot_range, default_val = self.range_cardinality(slot, cls, can_be_positional)
|
523
|
-
ifabsent_text = (
|
524
|
-
ifabsent_value_declaration(slot.ifabsent, self, cls, slot) if slot.ifabsent is not None else None
|
525
|
-
)
|
533
|
+
ifabsent_text = self.ifabsent_processor.process_slot(slot, cls) if slot.ifabsent is not None else None
|
526
534
|
if ifabsent_text is not None:
|
527
535
|
default = f"= {ifabsent_text}"
|
528
536
|
else:
|
@@ -627,15 +635,6 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
627
635
|
|
628
636
|
def gen_postinits(self, cls: ClassDefinition) -> str:
|
629
637
|
"""Generate all the typing and existence checks post initialize"""
|
630
|
-
post_inits_pre_super = []
|
631
|
-
for slot in self.domain_slots(cls):
|
632
|
-
if slot.ifabsent:
|
633
|
-
dflt = ifabsent_postinit_declaration(slot.ifabsent, self, cls, slot)
|
634
|
-
|
635
|
-
if dflt and dflt != "None":
|
636
|
-
post_inits_pre_super.append(f"if self.{self.slot_name(slot.name)} is None:")
|
637
|
-
post_inits_pre_super.append(f"\tself.{self.slot_name(slot.name)} = {dflt}")
|
638
|
-
|
639
638
|
post_inits = []
|
640
639
|
if not (cls.mixin or cls.abstract):
|
641
640
|
pkeys = self.primary_keys_for(cls)
|
@@ -666,20 +665,17 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
666
665
|
if slot.name not in domain_slot_names and slot.designates_type:
|
667
666
|
post_inits_designators.append(self.gen_postinit(cls, slot))
|
668
667
|
|
669
|
-
post_inits_pre_super_line = "\n\t\t".join([p for p in post_inits_pre_super if p]) + (
|
670
|
-
"\n\t\t" if post_inits_pre_super else ""
|
671
|
-
)
|
672
668
|
post_inits_post_super_line = "\n\t\t".join(post_inits_designators)
|
673
669
|
post_inits_line = "\n\t\t".join([p for p in post_inits if p])
|
674
670
|
return (
|
675
671
|
(
|
676
672
|
f"""
|
677
673
|
def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
|
678
|
-
{
|
674
|
+
{post_inits_line}
|
679
675
|
super().__post_init__(**kwargs)
|
680
676
|
{post_inits_post_super_line}"""
|
681
677
|
)
|
682
|
-
if post_inits_line or
|
678
|
+
if post_inits_line or post_inits_post_super_line
|
683
679
|
else ""
|
684
680
|
)
|
685
681
|
|
@@ -1171,7 +1167,7 @@ class {enum_name}(EnumDefinitionImpl):
|
|
1171
1167
|
|
1172
1168
|
|
1173
1169
|
@shared_arguments(PythonGenerator)
|
1174
|
-
@click.command()
|
1170
|
+
@click.command(name="python")
|
1175
1171
|
@click.option("--head/--no-head", default=True, show_default=True, help="Emit metadata heading")
|
1176
1172
|
@click.option(
|
1177
1173
|
"--genmeta/--no-genmeta",
|
linkml/generators/rdfgen.py
CHANGED
@@ -20,7 +20,7 @@ class ShaclDataType(DataType, Enum):
|
|
20
20
|
FLOAT = ("float", URIRef("http://www.w3.org/2001/XMLSchema#float"))
|
21
21
|
DOUBLE = ("double", URIRef("http://www.w3.org/2001/XMLSchema#double"))
|
22
22
|
URI = ("uri", URIRef("http://www.w3.org/2001/XMLSchema#anyURI"))
|
23
|
-
|
23
|
+
CURIE = ("curi", URIRef("http://www.w3.org/2001/XMLSchema#string"))
|
24
24
|
NCNAME = ("ncname", URIRef("http://www.w3.org/2001/XMLSchema#string"))
|
25
25
|
OBJECT_IDENTIFIER = ("objectidentifier", URIRef("http://www.w3.org/ns/shex#iri"))
|
26
26
|
NODE_IDENTIFIER = ("nodeidentifier", URIRef("http://www.w3.org/ns/shex#nonLiteral"))
|
@@ -0,0 +1,89 @@
|
|
1
|
+
from linkml_runtime.linkml_model import ClassDefinition, EnumDefinitionName, SlotDefinition
|
2
|
+
from rdflib import Literal, URIRef
|
3
|
+
|
4
|
+
from linkml.generators.common.ifabsent_processor import IfAbsentProcessor
|
5
|
+
from linkml.generators.shacl.shacl_data_type import ShaclDataType
|
6
|
+
|
7
|
+
|
8
|
+
class ShaclIfAbsentProcessor(IfAbsentProcessor):
|
9
|
+
|
10
|
+
def map_custom_default_values(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition) -> (bool, str):
|
11
|
+
if default_value == "class_curie":
|
12
|
+
class_uri = self.schema_view.get_uri(cls, expand=True)
|
13
|
+
if class_uri:
|
14
|
+
return True, URIRef(class_uri)
|
15
|
+
return True, ""
|
16
|
+
|
17
|
+
return False, None
|
18
|
+
|
19
|
+
def map_enum_default_value(
|
20
|
+
self, enum_name: EnumDefinitionName, permissible_value_name: str, slot: SlotDefinition, cls: ClassDefinition
|
21
|
+
):
|
22
|
+
return Literal(permissible_value_name)
|
23
|
+
|
24
|
+
def map_string_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
25
|
+
return Literal(default_value, datatype=ShaclDataType.STRING.uri_ref)
|
26
|
+
|
27
|
+
def map_integer_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
28
|
+
return Literal(default_value, datatype=ShaclDataType.INTEGER.uri_ref)
|
29
|
+
|
30
|
+
def map_boolean_true_default_value(self, slot: SlotDefinition, cls: ClassDefinition):
|
31
|
+
return Literal(True, datatype=ShaclDataType.BOOLEAN.uri_ref)
|
32
|
+
|
33
|
+
def map_boolean_false_default_value(self, slot: SlotDefinition, cls: ClassDefinition):
|
34
|
+
return Literal(False, datatype=ShaclDataType.BOOLEAN.uri_ref)
|
35
|
+
|
36
|
+
def map_float_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
37
|
+
return Literal(default_value, datatype=ShaclDataType.FLOAT.uri_ref)
|
38
|
+
|
39
|
+
def map_double_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
40
|
+
return Literal(default_value, datatype=ShaclDataType.DOUBLE.uri_ref)
|
41
|
+
|
42
|
+
def map_decimal_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
43
|
+
return Literal(default_value, datatype=ShaclDataType.DECIMAL.uri_ref)
|
44
|
+
|
45
|
+
def map_time_default_value(self, hour: str, minutes: str, seconds: str, slot: SlotDefinition, cls: ClassDefinition):
|
46
|
+
return Literal(f"{hour}:{minutes}:{seconds}", datatype=ShaclDataType.TIME.uri_ref)
|
47
|
+
|
48
|
+
def map_date_default_value(self, year: str, month: str, day: str, slot: SlotDefinition, cls: ClassDefinition):
|
49
|
+
return Literal(f"{year}-{month}-{day}", datatype=ShaclDataType.DATE.uri_ref)
|
50
|
+
|
51
|
+
def map_datetime_default_value(
|
52
|
+
self,
|
53
|
+
year: str,
|
54
|
+
month: str,
|
55
|
+
day: str,
|
56
|
+
hour: str,
|
57
|
+
minutes: str,
|
58
|
+
seconds: str,
|
59
|
+
slot: SlotDefinition,
|
60
|
+
cls: ClassDefinition,
|
61
|
+
):
|
62
|
+
return Literal(f"{year}-{month}-{day}T{hour}:{minutes}:{seconds}", datatype=ShaclDataType.DATETIME.uri_ref)
|
63
|
+
|
64
|
+
def map_uri_or_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
65
|
+
raise NotImplementedError()
|
66
|
+
|
67
|
+
def map_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
68
|
+
return Literal(default_value, datatype=ShaclDataType.CURIE.uri_ref)
|
69
|
+
|
70
|
+
def map_uri_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
71
|
+
return Literal(default_value, datatype=ShaclDataType.URI.uri_ref)
|
72
|
+
|
73
|
+
def map_nc_name_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
74
|
+
raise NotImplementedError()
|
75
|
+
|
76
|
+
def map_object_identifier_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
77
|
+
raise NotImplementedError()
|
78
|
+
|
79
|
+
def map_node_identifier_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
80
|
+
raise NotImplementedError()
|
81
|
+
|
82
|
+
def map_json_pointer_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
83
|
+
raise NotImplementedError()
|
84
|
+
|
85
|
+
def map_json_path_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
86
|
+
raise NotImplementedError()
|
87
|
+
|
88
|
+
def map_sparql_path_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
89
|
+
raise NotImplementedError()
|
linkml/generators/shaclgen.py
CHANGED
@@ -11,11 +11,11 @@ from linkml_runtime.utils.schemaview import SchemaView
|
|
11
11
|
from linkml_runtime.utils.yamlutils import TypedNode, extended_float, extended_int, extended_str
|
12
12
|
from rdflib import BNode, Graph, Literal, URIRef
|
13
13
|
from rdflib.collection import Collection
|
14
|
-
from rdflib.namespace import RDF, SH, XSD
|
14
|
+
from rdflib.namespace import RDF, RDFS, SH, XSD
|
15
15
|
|
16
16
|
from linkml._version import __version__
|
17
|
-
from linkml.generators.shacl.ifabsent_processor import IfAbsentProcessor
|
18
17
|
from linkml.generators.shacl.shacl_data_type import ShaclDataType
|
18
|
+
from linkml.generators.shacl.shacl_ifabsent_processor import ShaclIfAbsentProcessor
|
19
19
|
from linkml.utils.generator import Generator, shared_arguments
|
20
20
|
|
21
21
|
|
@@ -56,7 +56,7 @@ class ShaclGenerator(Generator):
|
|
56
56
|
g = Graph()
|
57
57
|
g.bind("sh", SH)
|
58
58
|
|
59
|
-
ifabsent_processor =
|
59
|
+
ifabsent_processor = ShaclIfAbsentProcessor(sv)
|
60
60
|
|
61
61
|
for pfx in self.schema.prefixes.values():
|
62
62
|
g.bind(str(pfx.prefix_prefix), pfx.prefix_reference)
|
@@ -73,6 +73,10 @@ class ShaclGenerator(Generator):
|
|
73
73
|
class_uri_with_suffix += self.suffix
|
74
74
|
shape_pv(RDF.type, SH.NodeShape)
|
75
75
|
shape_pv(SH.targetClass, class_uri) # TODO
|
76
|
+
|
77
|
+
if c.is_a:
|
78
|
+
shape_pv(RDFS.subClassOf, URIRef(sv.get_uri(c.is_a, expand=True)))
|
79
|
+
|
76
80
|
if self.closed:
|
77
81
|
if c.mixin or c.abstract:
|
78
82
|
shape_pv(SH.closed, Literal(False))
|
@@ -204,7 +208,9 @@ class ShaclGenerator(Generator):
|
|
204
208
|
# Map equal_string and equal_string_in to sh:in
|
205
209
|
self._and_equals_string(g, prop_pv, s.equals_string_in)
|
206
210
|
|
207
|
-
ifabsent_processor.process_slot(
|
211
|
+
default_value = ifabsent_processor.process_slot(s, c)
|
212
|
+
if default_value:
|
213
|
+
prop_pv(SH.defaultValue, default_value)
|
208
214
|
|
209
215
|
return g
|
210
216
|
|
@@ -303,7 +309,7 @@ def add_simple_data_type(func: Callable, r: ElementName) -> None:
|
|
303
309
|
|
304
310
|
|
305
311
|
@shared_arguments(ShaclGenerator)
|
306
|
-
@click.command()
|
312
|
+
@click.command(name="shacl")
|
307
313
|
@click.option(
|
308
314
|
"--closed/--non-closed",
|
309
315
|
default=True,
|
linkml/generators/shexgen.py
CHANGED
@@ -223,7 +223,7 @@ class ShExGenerator(Generator):
|
|
223
223
|
|
224
224
|
|
225
225
|
@shared_arguments(ShExGenerator)
|
226
|
-
@click.command()
|
226
|
+
@click.command(name="shex")
|
227
227
|
@click.option("-o", "--output", help="Output file name")
|
228
228
|
@click.version_option(__version__, "-V", "--version")
|
229
229
|
def cli(yamlfile, **args):
|
linkml/generators/sparqlgen.py
CHANGED
@@ -188,7 +188,7 @@ class SparqlGenerator(Generator):
|
|
188
188
|
|
189
189
|
|
190
190
|
@shared_arguments(SparqlGenerator)
|
191
|
-
@click.command()
|
191
|
+
@click.command(name="sparql")
|
192
192
|
@click.option("--dir", "-d", help="Directory in which queries will be deposited")
|
193
193
|
@click.version_option(__version__, "-V", "--version")
|
194
194
|
def cli(yamlfile, dir, **kwargs):
|
@@ -216,7 +216,7 @@ class SQLAlchemyGenerator(Generator):
|
|
216
216
|
help="Emit FK declarations",
|
217
217
|
)
|
218
218
|
@click.version_option(__version__, "-V", "--version")
|
219
|
-
@click.command()
|
219
|
+
@click.command(name="sqla")
|
220
220
|
def cli(yamlfile, declarative, generate_classes, pydantic, use_foreign_keys=True, **args):
|
221
221
|
"""Generate SQL DDL representation"""
|
222
222
|
if pydantic:
|
linkml/generators/sqltablegen.py
CHANGED
linkml/generators/sssomgen.py
CHANGED
@@ -180,7 +180,7 @@ class SSSOMGenerator(Generator):
|
|
180
180
|
|
181
181
|
|
182
182
|
@shared_arguments(SSSOMGenerator)
|
183
|
-
@click.command()
|
183
|
+
@click.command(name="sssom")
|
184
184
|
@click.option("-o", "--output", help="Output file name")
|
185
185
|
@click.version_option(__version__, "-V", "--version")
|
186
186
|
def cli(yamlfile, **kwargs):
|
linkml/generators/summarygen.py
CHANGED
@@ -88,7 +88,7 @@ class SummaryGenerator(Generator):
|
|
88
88
|
|
89
89
|
@shared_arguments(SummaryGenerator)
|
90
90
|
@click.version_option(__version__, "-V", "--version")
|
91
|
-
@click.command()
|
91
|
+
@click.command(name="summary")
|
92
92
|
def cli(yamlfile, **args):
|
93
93
|
"""Generate TSV summary files for viewing in Excel and the like"""
|
94
94
|
print(SummaryGenerator(yamlfile, **args).serialize(**args))
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import json
|
2
2
|
import os
|
3
|
+
import warnings
|
3
4
|
from dataclasses import dataclass
|
4
5
|
from typing import List
|
5
6
|
|
@@ -10,9 +11,7 @@ from linkml_runtime.utils.formatutils import be, camelcase, underscore
|
|
10
11
|
try:
|
11
12
|
from terminusdb_client.woqlquery import WOQLQuery as WQ
|
12
13
|
except ImportError:
|
13
|
-
|
14
|
-
|
15
|
-
warnings.warn("terminusdb_client is not a requirement of this package, please install it separately")
|
14
|
+
WQ = None
|
16
15
|
|
17
16
|
from linkml._version import __version__
|
18
17
|
from linkml.utils.generator import Generator, shared_arguments
|
@@ -67,6 +66,10 @@ class TerminusdbGenerator(Generator):
|
|
67
66
|
raw_additions: List = None
|
68
67
|
clswq: str = None
|
69
68
|
|
69
|
+
def __post_init__(self):
|
70
|
+
if WQ is None:
|
71
|
+
warnings.warn("terminusdb_client is not a requirement of this package, please install it separately")
|
72
|
+
|
70
73
|
def visit_schema(self, inline: bool = False, **kwargs) -> None:
|
71
74
|
self.classes = []
|
72
75
|
self.raw_additions = []
|
@@ -134,7 +137,7 @@ class TerminusdbGenerator(Generator):
|
|
134
137
|
|
135
138
|
@shared_arguments(TerminusdbGenerator)
|
136
139
|
@click.version_option(__version__, "-V", "--version")
|
137
|
-
@click.command()
|
140
|
+
@click.command(name="terminusdb")
|
138
141
|
def cli(yamlfile, **args):
|
139
142
|
"""Generate graphql representation of a LinkML model"""
|
140
143
|
print(TerminusdbGenerator(yamlfile, **args).serialize(**args))
|
@@ -264,7 +264,7 @@ class TypescriptGenerator(OOCodeGenerator):
|
|
264
264
|
@click.version_option(__version__, "-V", "--version")
|
265
265
|
@click.option("--gen-type-utils/", "-u", help="Generate Type checking utils", is_flag=True)
|
266
266
|
@click.option("--include-induced-slots/", help="Generate slots induced through inheritance", is_flag=True)
|
267
|
-
@click.command()
|
267
|
+
@click.command(name="typescript")
|
268
268
|
def cli(yamlfile, gen_type_utils=False, include_induced_slots=False, **args):
|
269
269
|
"""Generate typescript interfaces and types
|
270
270
|
|
linkml/generators/yamlgen.py
CHANGED
linkml/generators/yumlgen.py
CHANGED
linkml/linter/cli.py
CHANGED
@@ -33,7 +33,7 @@ def get_yaml_files(root: Path, accept_dot_files: bool) -> Iterable[str]:
|
|
33
33
|
yield str(path)
|
34
34
|
|
35
35
|
|
36
|
-
@click.command()
|
36
|
+
@click.command(name="lint")
|
37
37
|
@click.argument(
|
38
38
|
"schema",
|
39
39
|
type=click.Path(exists=True, dir_okay=True, file_okay=True, resolve_path=True, path_type=Path),
|