linkml 1.5.6__py3-none-any.whl → 1.5.7__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/__init__.py +2 -6
- linkml/_version.py +1 -1
- linkml/generators/__init__.py +26 -5
- linkml/generators/common/type_designators.py +27 -22
- linkml/generators/csvgen.py +4 -10
- linkml/generators/docgen/class.md.jinja2 +7 -0
- linkml/generators/docgen/class_diagram.md.jinja2 +0 -6
- linkml/generators/docgen/subset.md.jinja2 +54 -13
- linkml/generators/docgen.py +92 -90
- linkml/generators/dotgen.py +5 -9
- linkml/generators/erdiagramgen.py +56 -51
- linkml/generators/excelgen.py +10 -16
- linkml/generators/golanggen.py +11 -21
- linkml/generators/golrgen.py +4 -13
- linkml/generators/graphqlgen.py +3 -11
- linkml/generators/javagen.py +8 -15
- linkml/generators/jsonldcontextgen.py +7 -36
- linkml/generators/jsonldgen.py +14 -12
- linkml/generators/jsonschemagen.py +177 -133
- linkml/generators/markdowngen.py +40 -89
- linkml/generators/namespacegen.py +1 -2
- linkml/generators/oocodegen.py +22 -25
- linkml/generators/owlgen.py +34 -49
- linkml/generators/prefixmapgen.py +5 -13
- linkml/generators/projectgen.py +7 -14
- linkml/generators/protogen.py +3 -5
- linkml/generators/pydanticgen.py +85 -73
- linkml/generators/pythongen.py +86 -154
- linkml/generators/rdfgen.py +5 -11
- linkml/generators/shaclgen.py +32 -18
- linkml/generators/shexgen.py +19 -24
- linkml/generators/sparqlgen.py +4 -12
- linkml/generators/sqlalchemy/__init__.py +3 -2
- linkml/generators/sqlalchemy/sqlalchemy_declarative_template.py +7 -7
- linkml/generators/sqlalchemy/sqlalchemy_imperative_template.py +3 -3
- linkml/generators/sqlalchemygen.py +29 -27
- linkml/generators/sqlddlgen.py +34 -26
- linkml/generators/sqltablegen.py +21 -21
- linkml/generators/sssomgen.py +11 -13
- linkml/generators/summarygen.py +2 -4
- linkml/generators/terminusdbgen.py +7 -19
- linkml/generators/typescriptgen.py +10 -18
- linkml/generators/yamlgen.py +0 -2
- linkml/generators/yumlgen.py +23 -71
- linkml/linter/cli.py +4 -11
- linkml/linter/config/datamodel/config.py +17 -47
- linkml/linter/linter.py +2 -4
- linkml/linter/rules.py +34 -48
- linkml/reporting/__init__.py +2 -0
- linkml/reporting/model.py +9 -24
- linkml/transformers/relmodel_transformer.py +20 -33
- linkml/transformers/schema_renamer.py +14 -10
- linkml/utils/converter.py +15 -13
- linkml/utils/datautils.py +6 -22
- linkml/utils/datavalidator.py +2 -2
- linkml/utils/execute_tutorial.py +10 -12
- linkml/utils/generator.py +73 -91
- linkml/utils/helpers.py +4 -2
- linkml/utils/ifabsent_functions.py +23 -15
- linkml/utils/mergeutils.py +19 -35
- linkml/utils/rawloader.py +2 -6
- linkml/utils/schema_builder.py +31 -19
- linkml/utils/schema_fixer.py +28 -18
- linkml/utils/schemaloader.py +44 -89
- linkml/utils/schemasynopsis.py +49 -72
- linkml/utils/sqlutils.py +40 -30
- linkml/utils/typereferences.py +9 -6
- linkml/utils/validation.py +4 -5
- linkml/validators/__init__.py +2 -0
- linkml/validators/jsonschemavalidator.py +28 -18
- linkml/validators/sparqlvalidator.py +5 -15
- linkml/workspaces/datamodel/workspaces.py +13 -30
- linkml/workspaces/example_runner.py +74 -67
- {linkml-1.5.6.dist-info → linkml-1.5.7.dist-info}/METADATA +1 -1
- linkml-1.5.7.dist-info/RECORD +109 -0
- linkml-1.5.6.dist-info/RECORD +0 -109
- {linkml-1.5.6.dist-info → linkml-1.5.7.dist-info}/LICENSE +0 -0
- {linkml-1.5.6.dist-info → linkml-1.5.7.dist-info}/WHEEL +0 -0
- {linkml-1.5.6.dist-info → linkml-1.5.7.dist-info}/entry_points.txt +0 -0
linkml/__init__.py
CHANGED
@@ -20,9 +20,7 @@ MODULE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
|
20
20
|
LOCAL_METAMODEL_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.META, Format.YAML)
|
21
21
|
LOCAL_TYPES_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.TYPES, Format.YAML)
|
22
22
|
LOCAL_MAPPINGS_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.MAPPINGS, Format.YAML)
|
23
|
-
LOCAL_ANNOTATIONS_YAML_FILE = linkml_files.LOCAL_PATH_FOR(
|
24
|
-
Source.ANNOTATIONS, Format.YAML
|
25
|
-
)
|
23
|
+
LOCAL_ANNOTATIONS_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.ANNOTATIONS, Format.YAML)
|
26
24
|
LOCAL_EXTENSIONS_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.EXTENSIONS, Format.YAML)
|
27
25
|
|
28
26
|
# Local location of jsonld and context.jsonld files
|
@@ -30,9 +28,7 @@ LOCAL_METAMODEL_LDCONTEXT_FILE = linkml_files.LOCAL_PATH_FOR(Source.META, Format
|
|
30
28
|
LOCAL_METAMODEL_JSONLD_FILE = linkml_files.LOCAL_PATH_FOR(Source.META, Format.JSON)
|
31
29
|
LOCAL_TYPES_LDCONTEXT_FILE = linkml_files.LOCAL_PATH_FOR(Source.TYPES, Format.JSONLD)
|
32
30
|
LOCAL_TYPES_JSONLD_FILE = linkml_files.LOCAL_PATH_FOR(Source.TYPES, Format.JSON)
|
33
|
-
LOCAL_MAPPINGS_LDCONTEXT_FILE = linkml_files.LOCAL_PATH_FOR(
|
34
|
-
Source.MAPPINGS, Format.JSONLD
|
35
|
-
)
|
31
|
+
LOCAL_MAPPINGS_LDCONTEXT_FILE = linkml_files.LOCAL_PATH_FOR(Source.MAPPINGS, Format.JSONLD)
|
36
32
|
LOCAL_MAPPINGS_JSONLD_FILE = linkml_files.LOCAL_PATH_FOR(Source.MAPPINGS, Format.JSON)
|
37
33
|
|
38
34
|
# Local location of metamodel shex file
|
linkml/_version.py
CHANGED
linkml/generators/__init__.py
CHANGED
@@ -2,7 +2,17 @@
|
|
2
2
|
Generators translate between a SchemaDefinition and an alternative
|
3
3
|
representation such as JsonSchema
|
4
4
|
"""
|
5
|
-
|
5
|
+
|
6
|
+
from linkml.generators.javagen import JavaGenerator
|
7
|
+
from linkml.generators.jsonschemagen import JsonSchemaGenerator
|
8
|
+
from linkml.generators.owlgen import OwlSchemaGenerator
|
9
|
+
from linkml.generators.pydanticgen import PydanticGenerator
|
10
|
+
from linkml.generators.pythongen import PythonGenerator
|
11
|
+
from linkml.generators.shaclgen import ShaclGenerator
|
12
|
+
from linkml.generators.shexgen import ShExGenerator
|
13
|
+
from linkml.generators.sqlalchemygen import SQLAlchemyGenerator
|
14
|
+
from linkml.generators.sqltablegen import SQLTableGenerator
|
15
|
+
|
6
16
|
__all__ = [
|
7
17
|
"csvgen",
|
8
18
|
"dotgen",
|
@@ -18,15 +28,26 @@ __all__ = [
|
|
18
28
|
"owlgen",
|
19
29
|
"protogen",
|
20
30
|
"pythongen",
|
31
|
+
"pydanticgen",
|
21
32
|
"rdfgen",
|
22
33
|
"shexgen",
|
34
|
+
"shaclgen",
|
23
35
|
"sssomgen",
|
24
36
|
"summarygen",
|
25
37
|
"yamlgen",
|
26
38
|
"yumlgen",
|
27
|
-
"
|
39
|
+
"OwlSchemaGenerator",
|
40
|
+
"PydanticGenerator",
|
41
|
+
"PythonGenerator",
|
42
|
+
"JavaGenerator",
|
43
|
+
"JsonSchemaGenerator",
|
44
|
+
"ShaclGenerator",
|
45
|
+
"ShExGenerator",
|
46
|
+
"SQLAlchemyGenerator",
|
47
|
+
"SQLTableGenerator",
|
28
48
|
]
|
29
|
-
GENERATOR_BASE = "0.9"
|
30
49
|
|
31
|
-
|
32
|
-
|
50
|
+
# TODO: deprecate usage of these
|
51
|
+
# GENERATOR_BASE = "0.9"
|
52
|
+
|
53
|
+
# PYTHON_GEN_VERSION = GENERATOR_BASE + ".0"
|
@@ -1,44 +1,49 @@
|
|
1
|
-
from
|
1
|
+
from typing import List
|
2
|
+
|
3
|
+
from linkml_runtime.linkml_model.meta import ClassDefinition, SlotDefinition
|
2
4
|
from linkml_runtime.utils.schemaview import SchemaView
|
3
|
-
from linkml_runtime.utils.formatutils import camelcase
|
4
|
-
from typing import List, Tuple
|
5
5
|
|
6
|
-
|
6
|
+
|
7
|
+
def get_type_designator_value(
|
8
|
+
sv: SchemaView, type_designator_slot: SlotDefinition, class_def: ClassDefinition
|
9
|
+
) -> str:
|
7
10
|
"""
|
8
|
-
|
9
|
-
|
11
|
+
returns the correct value for a type designator field for a given class, depending on its range
|
12
|
+
this implements the logic described in https://github.com/linkml/linkml/issues/945:
|
10
13
|
"""
|
11
14
|
slot_types = set(sv.type_ancestors(type_designator_slot.range))
|
12
|
-
if
|
13
|
-
return sv.get_uri(class_def,expand=True,native=False)
|
14
|
-
elif
|
15
|
-
return sv.get_uri(class_def,expand=False, native=False)
|
16
|
-
elif
|
15
|
+
if "uri" in slot_types:
|
16
|
+
return sv.get_uri(class_def, expand=True, native=False)
|
17
|
+
elif "uriorcurie" in slot_types:
|
18
|
+
return sv.get_uri(class_def, expand=False, native=False)
|
19
|
+
elif "string" in slot_types:
|
17
20
|
return class_def.name
|
18
21
|
else:
|
19
|
-
return sv.get_uri(class_def,expand=False, native=False)
|
22
|
+
return sv.get_uri(class_def, expand=False, native=False)
|
20
23
|
|
21
24
|
|
22
|
-
def get_accepted_type_designator_values(
|
25
|
+
def get_accepted_type_designator_values(
|
26
|
+
sv: SchemaView, type_designator_slot: SlotDefinition, class_def: ClassDefinition
|
27
|
+
) -> List[str]:
|
23
28
|
"""
|
24
|
-
|
25
|
-
|
29
|
+
returns the accepted values for a type designator field for a given class, depending on its range
|
30
|
+
this implements the logic described in https://github.com/linkml/linkml/issues/945:
|
26
31
|
"""
|
27
32
|
accepted_uri_values = [
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
sv.get_uri(class_def, expand=True, native=True),
|
34
|
+
sv.get_uri(class_def, expand=True, native=False),
|
35
|
+
sv.get_uri(class_def, expand=False, native=True),
|
36
|
+
sv.get_uri(class_def, expand=False, native=False),
|
37
|
+
]
|
33
38
|
# unique, but with order preserved (https://stackoverflow.com/a/17016257)
|
34
39
|
accepted_uri_values = list(dict.fromkeys(accepted_uri_values))
|
35
40
|
|
36
41
|
slot_types = set(sv.type_ancestors(type_designator_slot.range))
|
37
|
-
uri_types = [
|
42
|
+
uri_types = ["uri", "uriorcurie"]
|
38
43
|
|
39
44
|
if slot_types.intersection(uri_types):
|
40
45
|
return accepted_uri_values
|
41
|
-
elif type_designator_slot.range ==
|
46
|
+
elif type_designator_slot.range == "string":
|
42
47
|
return [class_def.name]
|
43
48
|
else:
|
44
49
|
return accepted_uri_values
|
linkml/generators/csvgen.py
CHANGED
@@ -5,12 +5,10 @@ import os
|
|
5
5
|
import sys
|
6
6
|
from csv import DictWriter
|
7
7
|
from dataclasses import dataclass
|
8
|
-
from typing import List, Optional, Set
|
8
|
+
from typing import List, Optional, Set
|
9
9
|
|
10
10
|
import click
|
11
|
-
from linkml_runtime.linkml_model.meta import
|
12
|
-
ClassDefinitionName,
|
13
|
-
SchemaDefinition)
|
11
|
+
from linkml_runtime.linkml_model.meta import ClassDefinition, ClassDefinitionName
|
14
12
|
from linkml_runtime.utils.formatutils import be, underscore
|
15
13
|
|
16
14
|
from linkml._version import __version__
|
@@ -37,9 +35,7 @@ class CsvGenerator(Generator):
|
|
37
35
|
sep: Optional[str] = None
|
38
36
|
"""Separator for columns"""
|
39
37
|
|
40
|
-
closure: Optional[
|
41
|
-
Set[ClassDefinitionName]
|
42
|
-
] = None
|
38
|
+
closure: Optional[Set[ClassDefinitionName]] = None
|
43
39
|
"""List of classes to include in output"""
|
44
40
|
|
45
41
|
writer: Optional[DictWriter] = None
|
@@ -69,9 +65,7 @@ class CsvGenerator(Generator):
|
|
69
65
|
self.closure.update(self.ancestors(self.schema.classes[clsname]))
|
70
66
|
|
71
67
|
dialect: str = "excel" if self.format == "csv" else "excel-tab"
|
72
|
-
self.writer = DictWriter(
|
73
|
-
sys.stdout, ["id", "mappings", "description"], dialect=dialect
|
74
|
-
)
|
68
|
+
self.writer = DictWriter(sys.stdout, ["id", "mappings", "description"], dialect=dialect)
|
75
69
|
self.writer.writeheader()
|
76
70
|
|
77
71
|
def visit_class(self, cls: ClassDefinition) -> bool:
|
@@ -18,7 +18,14 @@ _{{ element_description_line }}_
|
|
18
18
|
|
19
19
|
URI: {{ gen.uri_link(element) }}
|
20
20
|
|
21
|
+
|
22
|
+
{% if diagram_type == "er_diagram" %}
|
23
|
+
```{{ gen.mermaid_directive() }}
|
24
|
+
{{ gen.mermaid_diagram([element.name]) }}
|
25
|
+
```
|
26
|
+
{% else %}
|
21
27
|
{% include "class_diagram.md.jinja2" %}
|
28
|
+
{% endif %}
|
22
29
|
|
23
30
|
{% if schemaview.class_parents(element.name) or schemaview.class_children(element.name, mixins=False) %}
|
24
31
|
|
@@ -1,8 +1,3 @@
|
|
1
|
-
{% if diagram_type == "er_diagram" %}
|
2
|
-
```{{ gen.mermaid_directive() }}
|
3
|
-
{{ gen.mermaid_diagram([element.name]) }}
|
4
|
-
```
|
5
|
-
{% else %}
|
6
1
|
{% if schemaview.class_parents(element.name) and schemaview.class_children(element.name) %}
|
7
2
|
```{{ gen.mermaid_directive() }}
|
8
3
|
classDiagram
|
@@ -61,5 +56,4 @@
|
|
61
56
|
{% endif %}
|
62
57
|
{% endfor %}
|
63
58
|
```
|
64
|
-
{% endif %}
|
65
59
|
{% endif %}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Subset: {{ gen.name(element) }}
|
2
2
|
|
3
3
|
{%- if header -%}
|
4
|
-
{{header}}
|
4
|
+
{{ header }}
|
5
5
|
{%- endif -%}
|
6
6
|
|
7
7
|
{% if element.description %}
|
@@ -13,9 +13,32 @@ _{{ element_description_line }}_
|
|
13
13
|
|
14
14
|
URI: {{ gen.uri_link(element) }}
|
15
15
|
|
16
|
-
|
17
16
|
{% include "common_metadata.md.jinja2" %}
|
18
17
|
|
18
|
+
{% set classes_in_subset = [] %}
|
19
|
+
{% set slots_in_subset = [] %}
|
20
|
+
{% set enums_in_subset = [] %}
|
21
|
+
|
22
|
+
{# Collect classes, slots, and enumerations in subset #}
|
23
|
+
{% for c in gen.all_class_objects()|sort(attribute=sort_by) %}
|
24
|
+
{%- if element.name in c.in_subset %}
|
25
|
+
{% set _ = classes_in_subset.append(c) %}
|
26
|
+
{%- endif %}
|
27
|
+
{% endfor %}
|
28
|
+
|
29
|
+
{% for s in gen.all_slot_objects()|sort(attribute=sort_by) %}
|
30
|
+
{%- if element.name in s.in_subset %}
|
31
|
+
{% set _ = slots_in_subset.append(s) %}
|
32
|
+
{%- endif %}
|
33
|
+
{% endfor %}
|
34
|
+
|
35
|
+
{% for e in schemaview.all_enums().values() %}
|
36
|
+
{%- if element.name in e.in_subset %}
|
37
|
+
{% set _ = enums_in_subset.append(e) %}
|
38
|
+
{%- endif %}
|
39
|
+
{% endfor %}
|
40
|
+
|
41
|
+
{% if classes_in_subset %}
|
19
42
|
## Classes in subset
|
20
43
|
|
21
44
|
| Class | Description |
|
@@ -32,34 +55,52 @@ URI: {{ gen.uri_link(element) }}
|
|
32
55
|
|
33
56
|
{{c.description}}
|
34
57
|
|
58
|
+
{%- set filtered_slots = [] -%}
|
59
|
+
|
60
|
+
{%- for s in induced_slots|sort(attribute=sort_by) -%}
|
61
|
+
{%- if element.name in s.in_subset or element.name in schemaview.get_slot(s.name).in_subset -%}
|
62
|
+
{% set _ = filtered_slots.append(s) %}
|
63
|
+
{%- endif -%}
|
64
|
+
{%- endfor %}
|
65
|
+
|
66
|
+
{%- if filtered_slots|length > 0 -%}
|
35
67
|
| Name | Cardinality and Range | Description |
|
36
68
|
| --- | --- | --- |
|
37
|
-
{% for s in
|
38
|
-
{% if element.name in s.in_subset or element.name in schemaview.get_slot(s.name).in_subset -%}
|
69
|
+
{% for s in filtered_slots -%}
|
39
70
|
| {{gen.link(s)}} | {{ gen.cardinality(s) }} <br/> {{gen.link(s.range)}} | {{s.description|enshorten}} {% if s.identifier %}**identifier**{% endif %} |
|
40
|
-
{% endif -%}
|
41
71
|
{% endfor %}
|
72
|
+
{%- endif %}
|
42
73
|
|
43
|
-
|
74
|
+
|
75
|
+
{%- endif %}
|
44
76
|
{% endfor %}
|
45
77
|
|
78
|
+
{%- endif %}
|
79
|
+
|
80
|
+
|
81
|
+
{% if slots_in_subset %}
|
46
82
|
## Slots in subset
|
47
83
|
|
48
84
|
| Slot | Description |
|
49
85
|
| --- | --- |
|
50
|
-
{% for s in
|
86
|
+
{% for s in slots_in_subset|sort(attribute=sort_by) -%}
|
51
87
|
{%- if element.name in s.in_subset -%}
|
52
|
-
| {{gen.link(s)}} | {{s.description|enshorten}} |
|
53
|
-
{
|
88
|
+
| {{ gen.link(s) }} | {{ s.description|enshorten }} |
|
89
|
+
{%- endif %}
|
54
90
|
{% endfor %}
|
55
91
|
|
92
|
+
{%- endif %}
|
93
|
+
|
94
|
+
|
95
|
+
{% if enums_in_subset %}
|
56
96
|
## Enumerations in subset
|
57
97
|
|
58
98
|
| Enumeration | Description |
|
59
99
|
| --- | --- |
|
60
|
-
{% for e in
|
61
|
-
{%- if element.name in e.in_subset
|
62
|
-
| {{gen.link(e)}} | {{e.description|enshorten}} |
|
63
|
-
{
|
100
|
+
{% for e in enums_in_subset|sort(attribute='name') -%}
|
101
|
+
{%- if element.name in e.in_subset %}
|
102
|
+
| {{ gen.link(e) }} | {{ e.description|enshorten }} |
|
103
|
+
{%- endif %}
|
64
104
|
{% endfor %}
|
65
105
|
|
106
|
+
{%- endif %}
|