linkml 1.7.2__tar.gz → 1.7.4__tar.gz
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-1.7.2 → linkml-1.7.4}/PKG-INFO +1 -2
- {linkml-1.7.2 → linkml-1.7.4}/linkml/__init__.py +7 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen.py +9 -9
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/erdiagramgen.py +6 -6
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/excelgen.py +3 -3
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/golanggen.py +1 -1
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/javagen.py +5 -5
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/jsonldcontextgen.py +6 -5
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/jsonschemagen.py +3 -3
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/linkmlgen.py +3 -3
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/markdowngen.py +2 -2
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/oocodegen.py +4 -1
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/owlgen.py +45 -26
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/plantumlgen.py +4 -3
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/protogen.py +2 -2
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/pydanticgen.py +159 -13
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/pythongen.py +5 -5
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/rdfgen.py +2 -2
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/shaclgen.py +2 -2
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqltablegen.py +13 -9
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/summarygen.py +2 -2
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/yamlgen.py +2 -2
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/yumlgen.py +5 -4
- {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/relmodel_transformer.py +5 -5
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/converter.py +3 -2
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/generator.py +4 -4
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/sqlutils.py +2 -1
- {linkml-1.7.2 → linkml-1.7.4}/pyproject.toml +1 -5
- {linkml-1.7.2 → linkml-1.7.4}/setup.py +1 -1
- {linkml-1.7.2 → linkml-1.7.4}/LICENSE +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/README.md +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/_version.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/PythonGenNotes.md +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/README.md +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/common/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/common/type_designators.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/csvgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/class.md.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/class_diagram.md.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/common_metadata.md.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/enum.md.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/index.md.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/index.tex.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/schema.md.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/slot.md.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/subset.md.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/type.md.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/dotgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/golrgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/graphqlgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/javagen/example_template.java.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/javagen/java_record_template.jinja2 +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/jsonldgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/legacy/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/namespacegen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/prefixmapgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/projectgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/shexgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sparqlgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlalchemy/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlalchemy/sqlalchemy_declarative_template.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlalchemy/sqlalchemy_imperative_template.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlalchemygen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlddlgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sssomgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/string_template.md +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/terminusdbgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/typescriptgen.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/cli.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/datamodel/.linkmllint.yaml +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/datamodel/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/datamodel/config.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/datamodel/config.yaml +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/default.yaml +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/recommended.yaml +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/formatter.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/json_formatter.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/markdown_formatter.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/terminal_formatter.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/tsv_formatter.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/linter.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/rules.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/reporting/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/reporting/model.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/logical_model_transformer.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/model_transformer.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/schema_renamer.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/cli_utils.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/datautils.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/datavalidator.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/execute_tutorial.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/helpers.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/ifabsent_functions.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/logictools.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/mergeutils.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/rawloader.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/schema_builder.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/schema_fixer.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/schemaloader.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/schemasynopsis.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/typereferences.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/validation.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/cli.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/delimited_file_loader.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/json_loader.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/loader.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/passthrough_loader.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/yaml_loader.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/jsonschema_validation_plugin.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/pydantic_validation_plugin.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/recommended_slots_plugin.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/shacl_validation_plugin.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/validation_plugin.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/report.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/validation_context.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/validator.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validators/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validators/jsonschemavalidator.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/validators/sparqlvalidator.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/datamodel/__init__.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/datamodel/workspaces.py +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/datamodel/workspaces.yaml +0 -0
- {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/example_runner.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: linkml
|
3
|
-
Version: 1.7.
|
3
|
+
Version: 1.7.4
|
4
4
|
Summary: Linked Open Data Modeling Language
|
5
5
|
Home-page: https://linkml.io/linkml/
|
6
6
|
Keywords: schema,linked data,data modeling,rdf,owl,biolink
|
@@ -22,7 +22,6 @@ Classifier: Programming Language :: Python :: 3.11
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.8
|
23
23
|
Classifier: Programming Language :: Python :: 3.9
|
24
24
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
25
|
-
Provides-Extra: docs
|
26
25
|
Requires-Dist: antlr4-python3-runtime (>=4.9.0,<4.10)
|
27
26
|
Requires-Dist: click (>=7.0)
|
28
27
|
Requires-Dist: graphviz (>=0.10.1)
|
@@ -71,3 +71,10 @@ BIOLINK_MODEL_URI = "https://w3id.org/biolink/biolink-model"
|
|
71
71
|
BIOLINK_MODEL_PYTHON_LOC = "biolink.model"
|
72
72
|
|
73
73
|
TurtleSerializer.roundtrip_prefixes = [""]
|
74
|
+
|
75
|
+
REQUESTS_TIMEOUT = 10
|
76
|
+
"""
|
77
|
+
Time (in seconds) to wait before failing a network request
|
78
|
+
|
79
|
+
See: https://docs.python-requests.org/en/latest/user/advanced/#timeouts
|
80
|
+
"""
|
@@ -126,7 +126,7 @@ class DocGenerator(Generator):
|
|
126
126
|
# ObjectVars
|
127
127
|
dialect: Optional[Union[DIALECT, str]] = None
|
128
128
|
"""markdown dialect (e.g MyST, Python)"""
|
129
|
-
sort_by: str =
|
129
|
+
sort_by: str = "name"
|
130
130
|
visit_all_class_slots = False
|
131
131
|
template_mappings: Dict[str, str] = None
|
132
132
|
directory: str = None
|
@@ -141,19 +141,19 @@ class DocGenerator(Generator):
|
|
141
141
|
diagram_type: Optional[Union[DiagramType, str]] = None
|
142
142
|
"""style of diagram (ER, UML)"""
|
143
143
|
|
144
|
-
include_top_level_diagram: bool =
|
144
|
+
include_top_level_diagram: bool = False
|
145
145
|
"""Whether the index page should include a schema diagram"""
|
146
146
|
|
147
147
|
example_directory: Optional[str] = None
|
148
148
|
example_runner: ExampleRunner = field(default_factory=lambda: ExampleRunner())
|
149
149
|
|
150
|
-
genmeta: bool =
|
151
|
-
gen_classvars: bool =
|
152
|
-
gen_slots: bool =
|
153
|
-
no_types_dir: bool =
|
154
|
-
use_slot_uris: bool =
|
155
|
-
use_class_uris: bool =
|
156
|
-
hierarchical_class_view: bool =
|
150
|
+
genmeta: bool = False
|
151
|
+
gen_classvars: bool = True
|
152
|
+
gen_slots: bool = True
|
153
|
+
no_types_dir: bool = False
|
154
|
+
use_slot_uris: bool = False
|
155
|
+
use_class_uris: bool = False
|
156
|
+
hierarchical_class_view: bool = False
|
157
157
|
|
158
158
|
def __post_init__(self):
|
159
159
|
dialect = self.dialect
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import os
|
2
|
-
from dataclasses import dataclass
|
2
|
+
from dataclasses import dataclass
|
3
3
|
from enum import Enum
|
4
4
|
from typing import List, Optional, Union
|
5
5
|
|
@@ -129,11 +129,11 @@ class ERDiagramGenerator(Generator):
|
|
129
129
|
exclude_attributes: bool = False
|
130
130
|
"""If True, do not include attributes in entities"""
|
131
131
|
|
132
|
-
genmeta: bool =
|
133
|
-
gen_classvars: bool =
|
134
|
-
gen_slots: bool =
|
135
|
-
no_types_dir: bool =
|
136
|
-
use_slot_uris: bool =
|
132
|
+
genmeta: bool = False
|
133
|
+
gen_classvars: bool = True
|
134
|
+
gen_slots: bool = True
|
135
|
+
no_types_dir: bool = False
|
136
|
+
use_slot_uris: bool = False
|
137
137
|
|
138
138
|
def __post_init__(self):
|
139
139
|
self.schemaview = SchemaView(self.schema)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import logging
|
2
|
-
from dataclasses import dataclass
|
2
|
+
from dataclasses import dataclass
|
3
3
|
from pathlib import Path
|
4
4
|
from typing import List
|
5
5
|
|
@@ -22,8 +22,8 @@ class ExcelGenerator(Generator):
|
|
22
22
|
uses_schemaloader = False
|
23
23
|
requires_metamodel = False
|
24
24
|
|
25
|
-
split_workbook_by_class: bool =
|
26
|
-
include_mixins: bool =
|
25
|
+
split_workbook_by_class: bool = False
|
26
|
+
include_mixins: bool = False
|
27
27
|
|
28
28
|
def __post_init__(self) -> None:
|
29
29
|
super().__post_init__()
|
@@ -160,7 +160,7 @@ class GolangGenerator(Generator):
|
|
160
160
|
rc_name = self.name(rc)
|
161
161
|
id_slot = self.get_identifier_or_key_slot(r)
|
162
162
|
if slot.multivalued:
|
163
|
-
if not id_slot or slot.inlined:
|
163
|
+
if not id_slot or slot.inlined or slot.inlined_as_list:
|
164
164
|
if slot.inlined_as_list or not id_slot:
|
165
165
|
return f"[]{rc_name}"
|
166
166
|
else:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import importlib.util
|
2
2
|
import os
|
3
|
-
from dataclasses import dataclass
|
3
|
+
from dataclasses import dataclass
|
4
4
|
from typing import Optional
|
5
5
|
|
6
6
|
import click
|
@@ -78,10 +78,10 @@ class JavaGenerator(OOCodeGenerator):
|
|
78
78
|
|
79
79
|
template_file: Optional[str] = None
|
80
80
|
|
81
|
-
gen_classvars: bool =
|
82
|
-
gen_slots: bool =
|
83
|
-
genmeta: bool =
|
84
|
-
emit_metadata: bool =
|
81
|
+
gen_classvars: bool = True
|
82
|
+
gen_slots: bool = True
|
83
|
+
genmeta: bool = False
|
84
|
+
emit_metadata: bool = True
|
85
85
|
|
86
86
|
def default_value_for_type(self, typ: str) -> str:
|
87
87
|
return TYPE_DEFAULTS.get(typ, "null")
|
@@ -45,12 +45,12 @@ class ContextGenerator(Generator):
|
|
45
45
|
default_ns: str = None
|
46
46
|
context_body: Dict = field(default_factory=lambda: dict())
|
47
47
|
slot_class_maps: Dict = field(default_factory=lambda: dict())
|
48
|
-
emit_metadata: bool =
|
49
|
-
model: Optional[bool] =
|
48
|
+
emit_metadata: bool = False
|
49
|
+
model: Optional[bool] = True
|
50
50
|
base: Optional[str] = None
|
51
51
|
output: Optional[str] = None
|
52
|
-
prefixes: Optional[bool] =
|
53
|
-
flatprefixes: Optional[bool] =
|
52
|
+
prefixes: Optional[bool] = True
|
53
|
+
flatprefixes: Optional[bool] = False
|
54
54
|
|
55
55
|
def __post_init__(self) -> None:
|
56
56
|
super().__post_init__()
|
@@ -150,7 +150,8 @@ class ContextGenerator(Generator):
|
|
150
150
|
else:
|
151
151
|
slot_def = {}
|
152
152
|
if not slot.usage_slot_name:
|
153
|
-
|
153
|
+
any_of_ranges = [any_of_el.range for any_of_el in slot.any_of]
|
154
|
+
if slot.range in self.schema.classes or any(rng in self.schema.classes for rng in any_of_ranges):
|
154
155
|
slot_def["@type"] = "@id"
|
155
156
|
elif slot.range in self.schema.enums:
|
156
157
|
slot_def["@context"] = ENUM_CONTEXT
|
@@ -2,7 +2,7 @@ import json
|
|
2
2
|
import logging
|
3
3
|
import os
|
4
4
|
from copy import deepcopy
|
5
|
-
from dataclasses import dataclass
|
5
|
+
from dataclasses import dataclass
|
6
6
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
7
7
|
|
8
8
|
import click
|
@@ -179,7 +179,7 @@ class JsonSchemaGenerator(Generator):
|
|
179
179
|
# @deprecated("Use top_class")
|
180
180
|
topClass: Optional[str] = None
|
181
181
|
|
182
|
-
not_closed: Optional[bool] =
|
182
|
+
not_closed: Optional[bool] = True
|
183
183
|
"""If not closed, then an open-ended set of attributes can be instantiated for any object"""
|
184
184
|
|
185
185
|
indent: int = 4
|
@@ -188,7 +188,7 @@ class JsonSchemaGenerator(Generator):
|
|
188
188
|
top_class: Optional[Union[ClassDefinitionName, str]] = None # JSON object is one instance of this
|
189
189
|
"""Class instantiated by the root node of the document tree"""
|
190
190
|
|
191
|
-
include_range_class_descendants: bool =
|
191
|
+
include_range_class_descendants: bool = False
|
192
192
|
"""If set, use an open world assumption and allow the range of a slot to be any descendant of the declared range.
|
193
193
|
Note that if the range of a slot has a type designator, descendants will always be included.
|
194
194
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
|
-
from dataclasses import dataclass
|
3
|
+
from dataclasses import dataclass
|
4
4
|
from typing import Union
|
5
5
|
|
6
6
|
import click
|
@@ -30,8 +30,8 @@ class LinkmlGenerator(Generator):
|
|
30
30
|
uses_schemaloader = False
|
31
31
|
requires_metamodel = False
|
32
32
|
|
33
|
-
materialize_attributes: bool =
|
34
|
-
materialize_patterns: bool =
|
33
|
+
materialize_attributes: bool = False
|
34
|
+
materialize_patterns: bool = False
|
35
35
|
|
36
36
|
def __post_init__(self):
|
37
37
|
# TODO: consider moving up a level
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
from contextlib import redirect_stdout
|
3
|
-
from dataclasses import dataclass
|
3
|
+
from dataclasses import dataclass
|
4
4
|
from io import StringIO
|
5
5
|
from typing import Any, Callable, Dict, List, Optional, Set, Union
|
6
6
|
|
@@ -47,7 +47,7 @@ class MarkdownGenerator(Generator):
|
|
47
47
|
image_directory: Optional[str] = None
|
48
48
|
classes: Set[ClassDefinitionName] = None
|
49
49
|
image_dir: bool = False
|
50
|
-
index_file: str =
|
50
|
+
index_file: str = "index.md"
|
51
51
|
noimages: bool = False
|
52
52
|
noyuml: bool = False
|
53
53
|
no_types_dir: bool = False
|
@@ -141,7 +141,10 @@ class OOCodeGenerator(Generator):
|
|
141
141
|
enum["description"] = enum_original.description
|
142
142
|
|
143
143
|
for pv in enum_original.permissible_values.values():
|
144
|
-
|
144
|
+
if pv.title:
|
145
|
+
label = self.generate_enum_label(pv.title)
|
146
|
+
else:
|
147
|
+
label = self.generate_enum_label(pv.text)
|
145
148
|
val = {"label": label, "value": pv.text.replace('"', '\\"')}
|
146
149
|
if hasattr(pv, "description"):
|
147
150
|
val["description"] = pv.description
|
@@ -118,29 +118,29 @@ class OwlSchemaGenerator(Generator):
|
|
118
118
|
"""By default, use the linkml metadata profile,
|
119
119
|
this allows for overrides."""
|
120
120
|
|
121
|
-
metaclasses: bool =
|
121
|
+
metaclasses: bool = True
|
122
122
|
"""if True, include OWL representations of ClassDefinition, SlotDefinition, etc. Introduces punning"""
|
123
123
|
|
124
|
-
add_root_classes: bool =
|
124
|
+
add_root_classes: bool = False
|
125
125
|
|
126
|
-
add_ols_annotations: bool =
|
126
|
+
add_ols_annotations: bool = True
|
127
127
|
graph: Optional[Graph] = None
|
128
128
|
"""Mutable graph that is being built up during OWL generation."""
|
129
129
|
|
130
130
|
top_value_uri: Optional[URIRef] = None
|
131
131
|
"""If metaclasses=True, then this property is used to connect object shadows to literals"""
|
132
132
|
|
133
|
-
type_objects: bool =
|
133
|
+
type_objects: bool = True
|
134
134
|
"""if True, represents types as classes (and thus all slots are object properties);
|
135
135
|
typed object classes effectively shadow the main xsd literal types.
|
136
136
|
The purpose of this is to allow a uniform ObjectProperty representation for all slots,
|
137
137
|
without having to commit to being either Data or Object property (OWL-DL does not
|
138
138
|
allow a property to be both."""
|
139
139
|
|
140
|
-
assert_equivalent_classes: bool =
|
140
|
+
assert_equivalent_classes: bool = False
|
141
141
|
"""If True, assert equivalence between definition_uris and class_uris"""
|
142
142
|
|
143
|
-
use_native_uris: bool =
|
143
|
+
use_native_uris: bool = True
|
144
144
|
"""If True, use the definition_uris, otherwise use class_uris."""
|
145
145
|
|
146
146
|
mixins_as_expressions: bool = None
|
@@ -152,10 +152,10 @@ class OwlSchemaGenerator(Generator):
|
|
152
152
|
node_owltypes: Mapping[Union[BNode, URIRef], Set[OWL_TYPE]] = field(default_factory=lambda: defaultdict(set))
|
153
153
|
"""rdfs:Datatype, owl:Thing"""
|
154
154
|
|
155
|
-
simplify: bool =
|
155
|
+
simplify: bool = True
|
156
156
|
"""Reduce complex expressions to simpler forms"""
|
157
157
|
|
158
|
-
use_swrl: bool =
|
158
|
+
use_swrl: bool = False
|
159
159
|
"""Use of SWRL is experimental"""
|
160
160
|
|
161
161
|
target_profile: OWLProfile = field(default_factory=lambda: OWLProfile.dl)
|
@@ -378,8 +378,12 @@ class OwlSchemaGenerator(Generator):
|
|
378
378
|
# rules yield OWL GCI subClassOf axioms
|
379
379
|
for rule in cls.rules:
|
380
380
|
pre_node = condition_to_bnode(rule.preconditions)
|
381
|
+
if not pre_node:
|
382
|
+
continue
|
381
383
|
pre_node = self._intersection_of([pre_node, subject_expr])
|
382
384
|
post_node = condition_to_bnode(rule.postconditions)
|
385
|
+
if not post_node:
|
386
|
+
continue
|
383
387
|
self.graph.add((pre_node, RDFS.subClassOf, post_node))
|
384
388
|
# classification rules yield OWL GCI subClassOf axioms
|
385
389
|
for expr in cls.classification_rules:
|
@@ -433,15 +437,10 @@ class OwlSchemaGenerator(Generator):
|
|
433
437
|
if slot.name in slot_map:
|
434
438
|
for k, v in slot.__dict__.items():
|
435
439
|
curr = slot_map[slot.name].get(k, None)
|
436
|
-
# print(f"MERGE={slot.name}.{k} = {v} // CURR={curr}")
|
437
440
|
if v and not curr:
|
438
441
|
slot_map[slot.name][k] = v
|
439
|
-
# print(f"OVERRIDE={slot.name}, k={k}, v={v}")
|
440
442
|
else:
|
441
443
|
slot_map[slot.name] = copy(slot.__dict__)
|
442
|
-
# print(f"INIT={slot.name}, vals={slot_map[slot.name]}")
|
443
|
-
|
444
|
-
# print(f"SN={slot.name}, vals={slot_map[slot.name]}")
|
445
444
|
own_slots = [SlotDefinition(**v) for v in slot_map.values()]
|
446
445
|
# sort by name
|
447
446
|
own_slots.sort(key=lambda x: x.name)
|
@@ -462,6 +461,8 @@ class OwlSchemaGenerator(Generator):
|
|
462
461
|
:param cls: LinkML class expression (anonymous if called recursively)
|
463
462
|
:return: blank node representing the OWL expression
|
464
463
|
"""
|
464
|
+
if cls is None:
|
465
|
+
cls = AnonymousClassExpression()
|
465
466
|
graph = self.graph
|
466
467
|
sv = self.schemaview
|
467
468
|
own_slots = self.get_own_slots(cls)
|
@@ -477,11 +478,13 @@ class OwlSchemaGenerator(Generator):
|
|
477
478
|
graph.add((cls_uri, OWL.disjointUnionOf, listnode))
|
478
479
|
else:
|
479
480
|
sub_sub_exprs = []
|
480
|
-
for i, x in enumerate(
|
481
|
-
rest =
|
482
|
-
neg_expr = self._complement_of_union_of(rest)
|
483
|
-
|
484
|
-
|
481
|
+
for i, x in enumerate(cls.exactly_one_of):
|
482
|
+
rest = cls.exactly_one_of[0:i] + cls.exactly_one_of[i + 1 :]
|
483
|
+
neg_expr = self._complement_of_union_of([self.transform_class_expression(nx) for nx in rest])
|
484
|
+
pos_expr = self._intersection_of([self.transform_class_expression(x), neg_expr])
|
485
|
+
sub_sub_exprs.append(pos_expr)
|
486
|
+
owl_exprs.append(self._union_of(sub_sub_exprs))
|
487
|
+
# owl_exprs.extend(sub_exprs)
|
485
488
|
if cls.all_of:
|
486
489
|
owl_exprs.append(self._intersection_of([self.transform_class_expression(x) for x in cls.all_of]))
|
487
490
|
if cls.none_of:
|
@@ -533,7 +536,8 @@ class OwlSchemaGenerator(Generator):
|
|
533
536
|
graph.add((max_card_expr, OWL.onProperty, slot_uri))
|
534
537
|
if slot.has_member:
|
535
538
|
has_member_expr = self.transform_class_slot_expression(cls, slot.has_member, slot)
|
536
|
-
|
539
|
+
if has_member_expr:
|
540
|
+
owl_exprs.append(self._some_values_from(slot_uri, has_member_expr))
|
537
541
|
return self._intersection_of(owl_exprs)
|
538
542
|
|
539
543
|
def slot_node_owltypes(self, slot: Union[SlotDefinition, AnonymousSlotExpression]) -> Set[URIRef]:
|
@@ -558,7 +562,7 @@ class OwlSchemaGenerator(Generator):
|
|
558
562
|
slot: Union[SlotDefinition, AnonymousSlotExpression],
|
559
563
|
main_slot: SlotDefinition = None,
|
560
564
|
owl_types: Set[OWL_TYPE] = None,
|
561
|
-
) -> Union[BNode, URIRef]:
|
565
|
+
) -> Optional[Union[BNode, URIRef]]:
|
562
566
|
"""
|
563
567
|
Take a ClassExpression and SlotExpression combination and transform to a node.
|
564
568
|
|
@@ -597,11 +601,19 @@ class OwlSchemaGenerator(Generator):
|
|
597
601
|
)
|
598
602
|
)
|
599
603
|
if slot.exactly_one_of:
|
600
|
-
|
601
|
-
|
602
|
-
|
604
|
+
disj_exprs = []
|
605
|
+
for i, operand in enumerate(slot.exactly_one_of):
|
606
|
+
rest = slot.exactly_one_of[0:i] + slot.exactly_one_of[i + 1 :]
|
607
|
+
neg_expr = self._complement_of_union_of(
|
608
|
+
[self.transform_class_slot_expression(cls, x, main_slot, owl_types) for x in rest],
|
609
|
+
owl_types=owl_types,
|
603
610
|
)
|
604
|
-
|
611
|
+
pos_expr = self._intersection_of(
|
612
|
+
[self.transform_class_slot_expression(cls, operand, main_slot, owl_types), neg_expr],
|
613
|
+
owl_types=owl_types,
|
614
|
+
)
|
615
|
+
disj_exprs.append(pos_expr)
|
616
|
+
owl_exprs.append(self._union_of(disj_exprs, owl_types=owl_types))
|
605
617
|
range = slot.range
|
606
618
|
# if not range and not owl_exprs:
|
607
619
|
# range = sv.schema.default_range
|
@@ -929,6 +941,10 @@ class OwlSchemaGenerator(Generator):
|
|
929
941
|
triples.extend(graph.triples((obj, None, None)))
|
930
942
|
|
931
943
|
def _some_values_from(self, property: URIRef, filler: Union[URIRef, BNode]) -> BNode:
|
944
|
+
if not property:
|
945
|
+
raise ValueError(f"Property is required, filler: {filler}")
|
946
|
+
if not filler:
|
947
|
+
raise ValueError(f"Filler is required, property: {property}")
|
932
948
|
node = BNode()
|
933
949
|
self.graph.add((node, RDF.type, OWL.Restriction))
|
934
950
|
self.graph.add((node, OWL.onProperty, property))
|
@@ -970,11 +986,14 @@ class OwlSchemaGenerator(Generator):
|
|
970
986
|
def _metaslot_uri(self, name: str) -> URIRef:
|
971
987
|
return URIRef("https://w3id.org/linkml/" + name)
|
972
988
|
|
973
|
-
def _complement_of_union_of(
|
989
|
+
def _complement_of_union_of(
|
990
|
+
self, exprs: List[Union[BNode, URIRef]], owl_types: Set[OWL_TYPE] = None, **kwargs
|
991
|
+
) -> Optional[Union[BNode, URIRef]]:
|
974
992
|
if not exprs:
|
975
993
|
raise ValueError("Must pass at least one")
|
976
994
|
neg_expr = BNode()
|
977
|
-
|
995
|
+
if not owl_types:
|
996
|
+
owl_types = self._get_owltypes(set(), exprs)
|
978
997
|
complement_predicate = OWL.complementOf
|
979
998
|
if len(owl_types) == 1:
|
980
999
|
if RDFS.Literal in owl_types:
|
@@ -7,7 +7,7 @@ https://plantuml.com/
|
|
7
7
|
import base64
|
8
8
|
import os
|
9
9
|
import zlib
|
10
|
-
from dataclasses import dataclass
|
10
|
+
from dataclasses import dataclass
|
11
11
|
from typing import Callable, List, Optional, Set, cast
|
12
12
|
|
13
13
|
import click
|
@@ -19,6 +19,7 @@ from linkml_runtime.linkml_model.meta import (
|
|
19
19
|
)
|
20
20
|
from linkml_runtime.utils.formatutils import camelcase, underscore
|
21
21
|
|
22
|
+
from linkml import REQUESTS_TIMEOUT
|
22
23
|
from linkml._version import __version__
|
23
24
|
from linkml.utils.generator import Generator, shared_arguments
|
24
25
|
|
@@ -48,7 +49,7 @@ class PlantumlGenerator(Generator):
|
|
48
49
|
classes: Set[ClassDefinitionName] = None
|
49
50
|
directory: Optional[str] = None
|
50
51
|
kroki_server: Optional[str] = "https://kroki.io"
|
51
|
-
load_image: bool =
|
52
|
+
load_image: bool = True
|
52
53
|
|
53
54
|
def visit_schema(
|
54
55
|
self,
|
@@ -101,7 +102,7 @@ class PlantumlGenerator(Generator):
|
|
101
102
|
camelcase(sorted(classes)[0] if classes else self.schema.name) + file_suffix,
|
102
103
|
)
|
103
104
|
if load_image:
|
104
|
-
resp = requests.get(plantuml_url, stream=True)
|
105
|
+
resp = requests.get(plantuml_url, stream=True, timeout=REQUESTS_TIMEOUT)
|
105
106
|
if resp.ok:
|
106
107
|
with open(self.output_file_name, "wb") as f:
|
107
108
|
for chunk in resp.iter_content(chunk_size=2048):
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import os
|
2
|
-
from dataclasses import dataclass
|
2
|
+
from dataclasses import dataclass
|
3
3
|
|
4
4
|
import click
|
5
5
|
from linkml_runtime.linkml_model.meta import ClassDefinition, SlotDefinition
|
@@ -24,7 +24,7 @@ class ProtoGenerator(Generator):
|
|
24
24
|
uses_schemaloader = True
|
25
25
|
|
26
26
|
# ObjectVars
|
27
|
-
relative_slot_num: int =
|
27
|
+
relative_slot_num: int = 0
|
28
28
|
|
29
29
|
def __post_init__(self):
|
30
30
|
super().__post_init__()
|