cognite-neat 0.99.0__py3-none-any.whl → 0.99.1__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.
Potentially problematic release.
This version of cognite-neat might be problematic. Click here for more details.
- cognite/neat/_client/_api/data_modeling_loaders.py +77 -4
- cognite/neat/_client/_api/schema.py +63 -2
- cognite/neat/_client/data_classes/schema.py +2 -348
- cognite/neat/_constants.py +27 -4
- cognite/neat/_graph/extractors/_classic_cdf/_classic.py +5 -5
- cognite/neat/_graph/loaders/_rdf2dms.py +2 -2
- cognite/neat/_graph/transformers/_classic_cdf.py +24 -13
- cognite/neat/_issues/_base.py +26 -17
- cognite/neat/_issues/errors/__init__.py +4 -2
- cognite/neat/_issues/errors/_external.py +7 -0
- cognite/neat/_issues/errors/_properties.py +2 -7
- cognite/neat/_issues/errors/_resources.py +1 -1
- cognite/neat/_issues/warnings/__init__.py +4 -2
- cognite/neat/_issues/warnings/_external.py +9 -1
- cognite/neat/_issues/warnings/_resources.py +26 -2
- cognite/neat/_issues/warnings/user_modeling.py +4 -4
- cognite/neat/_rules/_constants.py +2 -6
- cognite/neat/_rules/exporters/_rules2dms.py +4 -6
- cognite/neat/_rules/importers/__init__.py +1 -3
- cognite/neat/_rules/importers/_base.py +1 -1
- cognite/neat/_rules/importers/_dms2rules.py +3 -25
- cognite/neat/_rules/importers/_rdf/__init__.py +5 -0
- cognite/neat/_rules/importers/_rdf/_base.py +34 -11
- cognite/neat/_rules/importers/_rdf/_imf2rules.py +91 -0
- cognite/neat/_rules/importers/_rdf/_inference2rules.py +18 -2
- cognite/neat/_rules/importers/_rdf/_owl2rules.py +80 -0
- cognite/neat/_rules/importers/_rdf/_shared.py +138 -441
- cognite/neat/_rules/models/dms/__init__.py +2 -0
- cognite/neat/_rules/models/dms/_exporter.py +32 -30
- cognite/neat/_rules/models/dms/_rules.py +3 -45
- cognite/neat/_rules/models/dms/_validation.py +389 -122
- cognite/neat/_rules/models/information/__init__.py +2 -0
- cognite/neat/_rules/models/information/_rules.py +0 -59
- cognite/neat/_rules/models/information/_validation.py +9 -9
- cognite/neat/_rules/models/mapping/_classic2core.py +1 -1
- cognite/neat/_rules/models/mapping/_classic2core.yaml +8 -4
- cognite/neat/_rules/transformers/_pipelines.py +1 -1
- cognite/neat/_rules/transformers/_verification.py +29 -4
- cognite/neat/_session/_base.py +16 -41
- cognite/neat/_session/_prepare.py +6 -5
- cognite/neat/_session/_to.py +5 -2
- cognite/neat/_session/exceptions.py +4 -0
- cognite/neat/_utils/rdf_.py +6 -4
- cognite/neat/_version.py +1 -1
- cognite/neat/_workflows/steps/lib/current/rules_exporter.py +0 -88
- cognite/neat/_workflows/steps/lib/current/rules_importer.py +2 -16
- cognite/neat/_workflows/steps/lib/current/rules_validator.py +3 -5
- {cognite_neat-0.99.0.dist-info → cognite_neat-0.99.1.dist-info}/METADATA +1 -1
- {cognite_neat-0.99.0.dist-info → cognite_neat-0.99.1.dist-info}/RECORD +52 -60
- cognite/neat/_rules/importers/_rdf/_imf2rules/__init__.py +0 -3
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2classes.py +0 -86
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2metadata.py +0 -29
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2properties.py +0 -130
- cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2rules.py +0 -154
- cognite/neat/_rules/importers/_rdf/_owl2rules/__init__.py +0 -3
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2classes.py +0 -58
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2metadata.py +0 -65
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2properties.py +0 -59
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2rules.py +0 -39
- {cognite_neat-0.99.0.dist-info → cognite_neat-0.99.1.dist-info}/LICENSE +0 -0
- {cognite_neat-0.99.0.dist-info → cognite_neat-0.99.1.dist-info}/WHEEL +0 -0
- {cognite_neat-0.99.0.dist-info → cognite_neat-0.99.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
from datetime import datetime
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
from cognite.client import data_modeling as dm
|
|
4
|
-
from rdflib import
|
|
5
|
+
from rdflib import Graph, Namespace, URIRef
|
|
5
6
|
|
|
7
|
+
from cognite.neat._constants import get_default_prefixes
|
|
6
8
|
from cognite.neat._issues import IssueList
|
|
7
9
|
from cognite.neat._issues.errors import FileReadError
|
|
8
10
|
from cognite.neat._issues.errors._general import NeatValueError
|
|
9
11
|
from cognite.neat._rules._shared import ReadRules
|
|
10
12
|
from cognite.neat._rules.importers._base import BaseImporter
|
|
13
|
+
from cognite.neat._rules.models._base_rules import RoleTypes
|
|
11
14
|
from cognite.neat._rules.models.data_types import AnyURI
|
|
12
15
|
from cognite.neat._rules.models.entities import UnknownEntity
|
|
13
16
|
from cognite.neat._rules.models.information import (
|
|
@@ -30,6 +33,13 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
|
|
|
30
33
|
graph: Knowledge graph
|
|
31
34
|
data_model_id: Data model id to be used for the imported rules
|
|
32
35
|
space: CDF Space to be used for the imported rules
|
|
36
|
+
language: Language for description and human readable entity names
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
!!! note "Language"
|
|
41
|
+
Language is provided as ISO 639-1 code. If not provided, English will be used as default.
|
|
42
|
+
|
|
33
43
|
"""
|
|
34
44
|
|
|
35
45
|
def __init__(
|
|
@@ -39,6 +49,7 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
|
|
|
39
49
|
data_model_id: dm.DataModelId | tuple[str, str, str],
|
|
40
50
|
max_number_of_instance: int,
|
|
41
51
|
non_existing_node_type: UnknownEntity | AnyURI,
|
|
52
|
+
language: str,
|
|
42
53
|
) -> None:
|
|
43
54
|
self.issue_list = issue_list
|
|
44
55
|
self.graph = graph
|
|
@@ -48,6 +59,7 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
|
|
|
48
59
|
|
|
49
60
|
self.max_number_of_instance = max_number_of_instance
|
|
50
61
|
self.non_existing_node_type = non_existing_node_type
|
|
62
|
+
self.language = language
|
|
51
63
|
|
|
52
64
|
@classmethod
|
|
53
65
|
def from_graph_store(
|
|
@@ -56,6 +68,7 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
|
|
|
56
68
|
data_model_id: (dm.DataModelId | tuple[str, str, str]) = DEFAULT_RDF_DATA_MODEL_ID,
|
|
57
69
|
max_number_of_instance: int = -1,
|
|
58
70
|
non_existing_node_type: UnknownEntity | AnyURI = DEFAULT_NON_EXISTING_NODE_TYPE,
|
|
71
|
+
language: str = "en",
|
|
59
72
|
):
|
|
60
73
|
return cls(
|
|
61
74
|
IssueList(title=f"{cls.__name__} issues"),
|
|
@@ -63,6 +76,7 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
|
|
|
63
76
|
data_model_id=data_model_id,
|
|
64
77
|
max_number_of_instance=max_number_of_instance,
|
|
65
78
|
non_existing_node_type=non_existing_node_type,
|
|
79
|
+
language=language,
|
|
66
80
|
)
|
|
67
81
|
|
|
68
82
|
@classmethod
|
|
@@ -72,6 +86,7 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
|
|
|
72
86
|
data_model_id: (dm.DataModelId | tuple[str, str, str]) = DEFAULT_RDF_DATA_MODEL_ID,
|
|
73
87
|
max_number_of_instance: int = -1,
|
|
74
88
|
non_existing_node_type: UnknownEntity | AnyURI = DEFAULT_NON_EXISTING_NODE_TYPE,
|
|
89
|
+
language: str = "en",
|
|
75
90
|
):
|
|
76
91
|
issue_list = IssueList(title=f"{cls.__name__} issues")
|
|
77
92
|
|
|
@@ -82,15 +97,8 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
|
|
|
82
97
|
issue_list.append(FileReadError(filepath, str(e)))
|
|
83
98
|
|
|
84
99
|
# bind key namespaces
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
graph.bind("rdfs", RDFS)
|
|
88
|
-
graph.bind("dcterms", DCTERMS)
|
|
89
|
-
graph.bind("dc", DC)
|
|
90
|
-
graph.bind("skos", SKOS)
|
|
91
|
-
graph.bind("sh", SH)
|
|
92
|
-
graph.bind("xsd", XSD)
|
|
93
|
-
graph.bind("imf", "http://ns.imfid.org/imf#")
|
|
100
|
+
for prefix, namespace in get_default_prefixes().items():
|
|
101
|
+
graph.bind(prefix, namespace)
|
|
94
102
|
|
|
95
103
|
return cls(
|
|
96
104
|
issue_list,
|
|
@@ -98,6 +106,7 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
|
|
|
98
106
|
data_model_id=data_model_id,
|
|
99
107
|
max_number_of_instance=max_number_of_instance,
|
|
100
108
|
non_existing_node_type=non_existing_node_type,
|
|
109
|
+
language=language,
|
|
101
110
|
)
|
|
102
111
|
|
|
103
112
|
def to_rules(
|
|
@@ -129,4 +138,18 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
|
|
|
129
138
|
prefixes: Dict of prefixes and namespaces
|
|
130
139
|
"""
|
|
131
140
|
if Namespace(get_namespace(URI)) not in prefixes.values():
|
|
132
|
-
prefixes[f"
|
|
141
|
+
prefixes[f"prefix_{len(prefixes)+1}"] = Namespace(get_namespace(URI))
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def _metadata(self) -> dict:
|
|
145
|
+
return {
|
|
146
|
+
"role": RoleTypes.information,
|
|
147
|
+
"space": self.data_model_id.space,
|
|
148
|
+
"external_id": self.data_model_id.external_id,
|
|
149
|
+
"version": self.data_model_id.version,
|
|
150
|
+
"created": datetime.now().replace(microsecond=0),
|
|
151
|
+
"updated": datetime.now().replace(microsecond=0),
|
|
152
|
+
"name": None,
|
|
153
|
+
"description": f"Data model imported using {type(self).__name__}",
|
|
154
|
+
"creator": "Neat",
|
|
155
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""This module performs importing of various formats to one of serializations for which
|
|
2
|
+
there are loaders to TransformationRules pydantic class."""
|
|
3
|
+
|
|
4
|
+
from cognite.neat._rules.importers._rdf._base import BaseRDFImporter
|
|
5
|
+
from cognite.neat._rules.importers._rdf._shared import parse_classes, parse_properties
|
|
6
|
+
|
|
7
|
+
CLASSES_QUERY = """
|
|
8
|
+
SELECT ?class_ ?name ?description ?implements
|
|
9
|
+
WHERE {{
|
|
10
|
+
VALUES ?type {{ imf:BlockType imf:TerminalType imf:AttributeType }}
|
|
11
|
+
?class_ a ?type .
|
|
12
|
+
|
|
13
|
+
OPTIONAL {{?class_ rdfs:subClassOf ?parent }}.
|
|
14
|
+
OPTIONAL {{?class_ rdfs:label|skos:prefLabel ?name }}.
|
|
15
|
+
OPTIONAL {{?class_ rdfs:comment|skos:definition ?description}}.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Add imf:Attribute as parent class when no parent is found
|
|
19
|
+
BIND(IF(!bound(?parent) && ?type = imf:AttributeType, imf:Attribute, ?parent) AS ?implements)
|
|
20
|
+
|
|
21
|
+
# FILTERS
|
|
22
|
+
FILTER (!isBlank(?class_))
|
|
23
|
+
FILTER (!bound(?implements) || !isBlank(?implements))
|
|
24
|
+
|
|
25
|
+
FILTER (!bound(?name) || LANG(?name) = "" || LANGMATCHES(LANG(?name), "{language}"))
|
|
26
|
+
FILTER (!bound(?description) || LANG(?description) = "" || LANGMATCHES(LANG(?description), "{language}"))
|
|
27
|
+
}}
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
PROPERTIES_QUERY = """
|
|
31
|
+
SELECT ?class_ ?property_ ?name ?description ?value_type ?min_count ?max_count ?default
|
|
32
|
+
WHERE
|
|
33
|
+
{{
|
|
34
|
+
# CASE 1: Handling Blocks and Terminals
|
|
35
|
+
{{
|
|
36
|
+
VALUES ?type {{ imf:BlockType imf:TerminalType }}
|
|
37
|
+
?class_ a ?type ;
|
|
38
|
+
sh:property ?propertyShape .
|
|
39
|
+
?propertyShape sh:path ?property_ .
|
|
40
|
+
|
|
41
|
+
OPTIONAL {{ ?property_ skos:prefLabel ?name . }}
|
|
42
|
+
OPTIONAL {{ ?property_ skos:definition ?description . }}
|
|
43
|
+
OPTIONAL {{ ?property_ rdfs:range ?range . }}
|
|
44
|
+
|
|
45
|
+
OPTIONAL {{ ?propertyShape sh:minCount ?min_count . }}
|
|
46
|
+
OPTIONAL {{ ?propertyShape sh:maxCount ?max_count . }}
|
|
47
|
+
OPTIONAL {{ ?propertyShape sh:hasValue ?default . }}
|
|
48
|
+
OPTIONAL {{ ?propertyShape sh:class | sh:qualifiedValueShape/sh:class ?valueShape . }}
|
|
49
|
+
}}
|
|
50
|
+
|
|
51
|
+
UNION
|
|
52
|
+
|
|
53
|
+
# CASE 2: Handling Attributes
|
|
54
|
+
{{
|
|
55
|
+
?class_ a imf:AttributeType .
|
|
56
|
+
BIND(xsd:anyURI AS ?valueShape)
|
|
57
|
+
BIND(imf:predicate AS ?property_)
|
|
58
|
+
?class_ ?property_ ?defaultURI .
|
|
59
|
+
BIND(STR(?defaultURI) AS ?default)
|
|
60
|
+
|
|
61
|
+
}}
|
|
62
|
+
|
|
63
|
+
# Set the value type for the property based on sh:class, sh:qualifiedValueType or rdfs:range
|
|
64
|
+
BIND(IF(BOUND(?valueShape), ?valueShape, IF(BOUND(?range) , ?range , ?valueShape)) AS ?value_type)
|
|
65
|
+
|
|
66
|
+
FILTER (!isBlank(?property_))
|
|
67
|
+
FILTER (!bound(?class_) || !isBlank(?class_))
|
|
68
|
+
FILTER (!bound(?name) || LANG(?name) = "" || LANGMATCHES(LANG(?name), "{language}"))
|
|
69
|
+
FILTER (!bound(?description) || LANG(?description) = "" || LANGMATCHES(LANG(?description), "{language}"))
|
|
70
|
+
}}
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class IMFImporter(BaseRDFImporter):
|
|
75
|
+
"""Convert IMF Types provided as SHACL shapes to Input Rules."""
|
|
76
|
+
|
|
77
|
+
def _to_rules_components(
|
|
78
|
+
self,
|
|
79
|
+
) -> dict:
|
|
80
|
+
classes, issue_list = parse_classes(self.graph, CLASSES_QUERY, self.language, self.issue_list)
|
|
81
|
+
self.issue_list = issue_list
|
|
82
|
+
properties, issue_list = parse_properties(self.graph, PROPERTIES_QUERY, self.language, self.issue_list)
|
|
83
|
+
self.issue_list = issue_list
|
|
84
|
+
|
|
85
|
+
components = {
|
|
86
|
+
"Metadata": self._metadata,
|
|
87
|
+
"Classes": list(classes.values()) if classes else [],
|
|
88
|
+
"Properties": list(properties.values()) if properties else [],
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return components
|
|
@@ -69,8 +69,15 @@ class InferenceImporter(BaseRDFImporter):
|
|
|
69
69
|
data_model_id: (dm.DataModelId | tuple[str, str, str]) = DEFAULT_INFERENCE_DATA_MODEL_ID,
|
|
70
70
|
max_number_of_instance: int = -1,
|
|
71
71
|
non_existing_node_type: UnknownEntity | AnyURI = DEFAULT_NON_EXISTING_NODE_TYPE,
|
|
72
|
+
language: str = "en",
|
|
72
73
|
) -> "InferenceImporter":
|
|
73
|
-
return super().from_graph_store(
|
|
74
|
+
return super().from_graph_store(
|
|
75
|
+
store,
|
|
76
|
+
data_model_id,
|
|
77
|
+
max_number_of_instance,
|
|
78
|
+
non_existing_node_type,
|
|
79
|
+
language,
|
|
80
|
+
)
|
|
74
81
|
|
|
75
82
|
@classmethod
|
|
76
83
|
def from_file(
|
|
@@ -79,8 +86,15 @@ class InferenceImporter(BaseRDFImporter):
|
|
|
79
86
|
data_model_id: (dm.DataModelId | tuple[str, str, str]) = DEFAULT_INFERENCE_DATA_MODEL_ID,
|
|
80
87
|
max_number_of_instance: int = -1,
|
|
81
88
|
non_existing_node_type: UnknownEntity | AnyURI = DEFAULT_NON_EXISTING_NODE_TYPE,
|
|
89
|
+
language: str = "en",
|
|
82
90
|
) -> "InferenceImporter":
|
|
83
|
-
return super().from_file(
|
|
91
|
+
return super().from_file(
|
|
92
|
+
filepath,
|
|
93
|
+
data_model_id,
|
|
94
|
+
max_number_of_instance,
|
|
95
|
+
non_existing_node_type,
|
|
96
|
+
language,
|
|
97
|
+
)
|
|
84
98
|
|
|
85
99
|
@classmethod
|
|
86
100
|
def from_json_file(
|
|
@@ -88,6 +102,7 @@ class InferenceImporter(BaseRDFImporter):
|
|
|
88
102
|
filepath: Path,
|
|
89
103
|
data_model_id: (dm.DataModelId | tuple[str, str, str]) = DEFAULT_INFERENCE_DATA_MODEL_ID,
|
|
90
104
|
max_number_of_instance: int = -1,
|
|
105
|
+
language: str = "en",
|
|
91
106
|
) -> "InferenceImporter":
|
|
92
107
|
raise NotImplementedError("JSON file format is not supported yet.")
|
|
93
108
|
|
|
@@ -97,6 +112,7 @@ class InferenceImporter(BaseRDFImporter):
|
|
|
97
112
|
filepath: Path,
|
|
98
113
|
data_model_id: (dm.DataModelId | tuple[str, str, str]) = DEFAULT_INFERENCE_DATA_MODEL_ID,
|
|
99
114
|
max_number_of_instance: int = -1,
|
|
115
|
+
language: str = "en",
|
|
100
116
|
) -> "InferenceImporter":
|
|
101
117
|
raise NotImplementedError("YAML file format is not supported yet.")
|
|
102
118
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""This module performs importing of various formats to one of serializations for which
|
|
2
|
+
there are loaders to TransformationRules pydantic class."""
|
|
3
|
+
|
|
4
|
+
from cognite.neat._rules.importers._rdf._base import BaseRDFImporter
|
|
5
|
+
from cognite.neat._rules.importers._rdf._shared import parse_classes, parse_properties
|
|
6
|
+
|
|
7
|
+
CLASSES_QUERY = """SELECT ?class_ ?name ?description ?implements
|
|
8
|
+
WHERE {{
|
|
9
|
+
|
|
10
|
+
?class_ a owl:Class .
|
|
11
|
+
OPTIONAL {{?class_ rdfs:subClassOf ?implements }}.
|
|
12
|
+
OPTIONAL {{?class_ rdfs:label|skos:prefLabel ?name }}.
|
|
13
|
+
OPTIONAL {{?class_ rdfs:comment|skos:definition ?description}} .
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
FILTER (!isBlank(?class_))
|
|
17
|
+
FILTER (!bound(?implements) || !isBlank(?implements))
|
|
18
|
+
|
|
19
|
+
FILTER (!bound(?name) || LANG(?name) = "" || LANGMATCHES(LANG(?name), "{language}"))
|
|
20
|
+
FILTER (!bound(?description) || LANG(?description) = "" || LANGMATCHES(LANG(?description), "{language}"))
|
|
21
|
+
|
|
22
|
+
}}
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
PROPERTIES_QUERY = """
|
|
26
|
+
|
|
27
|
+
SELECT ?class_ ?property_ ?name ?description ?value_type ?minCount ?maxCount ?default
|
|
28
|
+
WHERE {{
|
|
29
|
+
?property_ a ?property_Type.
|
|
30
|
+
FILTER (?property_Type IN (owl:ObjectProperty, owl:DatatypeProperty ) )
|
|
31
|
+
OPTIONAL {{?property_ rdfs:domain ?class_ }}.
|
|
32
|
+
OPTIONAL {{?property_ rdfs:range ?value_type }}.
|
|
33
|
+
OPTIONAL {{?property_ rdfs:label|skos:prefLabel ?name }}.
|
|
34
|
+
OPTIONAL {{?property_ rdfs:comment|skos:definition ?description}}.
|
|
35
|
+
OPTIONAL {{?property_ owl:maxCardinality ?maxCount}}.
|
|
36
|
+
OPTIONAL {{?property_ owl:minCardinality ?minCount}}.
|
|
37
|
+
|
|
38
|
+
# FILTERS
|
|
39
|
+
FILTER (!isBlank(?property_))
|
|
40
|
+
FILTER (!bound(?name) || LANG(?name) = "" || LANGMATCHES(LANG(?name), "{language}"))
|
|
41
|
+
FILTER (!bound(?description) || LANG(?description) = "" || LANGMATCHES(LANG(?description), "{language}"))
|
|
42
|
+
}}
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class OWLImporter(BaseRDFImporter):
|
|
47
|
+
"""Convert OWL ontology to tables/ transformation rules / Excel file.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
filepath: Path to OWL ontology
|
|
51
|
+
|
|
52
|
+
!!! Note
|
|
53
|
+
OWL Ontologies are information models which completeness varies. As such, constructing functional
|
|
54
|
+
data model directly will often be impossible, therefore the produced Rules object will be ill formed.
|
|
55
|
+
To avoid this, neat will automatically attempt to make the imported rules compliant by adding default
|
|
56
|
+
values for missing information, attaching dangling properties to default containers based on the
|
|
57
|
+
property type, etc.
|
|
58
|
+
|
|
59
|
+
One has to be aware that NEAT will be opinionated about how to make the ontology
|
|
60
|
+
compliant, and that the resulting rules may not be what you expect.
|
|
61
|
+
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def _to_rules_components(
|
|
65
|
+
self,
|
|
66
|
+
) -> dict:
|
|
67
|
+
classes, issue_list = parse_classes(self.graph, CLASSES_QUERY, self.language, self.issue_list)
|
|
68
|
+
self.issue_list = issue_list
|
|
69
|
+
|
|
70
|
+
# NeatError
|
|
71
|
+
properties, issue_list = parse_properties(self.graph, PROPERTIES_QUERY, self.language, self.issue_list)
|
|
72
|
+
self.issue_list = issue_list
|
|
73
|
+
|
|
74
|
+
components = {
|
|
75
|
+
"Metadata": self._metadata,
|
|
76
|
+
"Classes": list(classes.values()) if classes else [],
|
|
77
|
+
"Properties": list(properties.values()) if properties else [],
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return components
|