cognite-neat 0.78.2__py3-none-any.whl → 0.78.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.
Potentially problematic release.
This version of cognite-neat might be problematic. Click here for more details.
- cognite/neat/_version.py +1 -1
- cognite/neat/rules/exporters/_rules2ontology.py +10 -6
- cognite/neat/rules/importers/_inference2rules.py +52 -56
- cognite/neat/rules/models/entities.py +71 -6
- cognite/neat/rules/models/information/_rules.py +8 -1
- cognite/neat/rules/models/information/_rules_input.py +15 -3
- cognite/neat/workflows/steps/lib/current/rules_importer.py +1 -12
- {cognite_neat-0.78.2.dist-info → cognite_neat-0.78.3.dist-info}/METADATA +1 -1
- {cognite_neat-0.78.2.dist-info → cognite_neat-0.78.3.dist-info}/RECORD +12 -12
- {cognite_neat-0.78.2.dist-info → cognite_neat-0.78.3.dist-info}/LICENSE +0 -0
- {cognite_neat-0.78.2.dist-info → cognite_neat-0.78.3.dist-info}/WHEEL +0 -0
- {cognite_neat-0.78.2.dist-info → cognite_neat-0.78.3.dist-info}/entry_points.txt +0 -0
cognite/neat/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.78.
|
|
1
|
+
__version__ = "0.78.3"
|
|
@@ -331,7 +331,7 @@ class OWLProperty(OntologyModel):
|
|
|
331
331
|
elif isinstance(definition.value_type, ClassEntity):
|
|
332
332
|
owl_property.range_.add(namespace[str(definition.value_type.suffix)])
|
|
333
333
|
else:
|
|
334
|
-
raise ValueError(f"Value type {definition.value_type} is not supported")
|
|
334
|
+
raise ValueError(f"Value type {definition.value_type.type_} is not supported")
|
|
335
335
|
owl_property.domain.add(namespace[str(definition.class_.suffix)])
|
|
336
336
|
owl_property.label.add(definition.name or definition.property_)
|
|
337
337
|
if definition.description:
|
|
@@ -549,15 +549,19 @@ class SHACLPropertyShape(OntologyModel):
|
|
|
549
549
|
|
|
550
550
|
@classmethod
|
|
551
551
|
def from_property(cls, definition: InformationProperty, namespace: Namespace) -> "SHACLPropertyShape":
|
|
552
|
+
# TODO requires PR to fix MultiValueType and UnknownValueType
|
|
553
|
+
if isinstance(definition.value_type, ClassEntity):
|
|
554
|
+
expected_value_type = namespace[f"{definition.value_type.suffix}Shape"]
|
|
555
|
+
elif isinstance(definition.value_type, DataType):
|
|
556
|
+
expected_value_type = XSD[definition.value_type.xsd]
|
|
557
|
+
else:
|
|
558
|
+
raise ValueError(f"Value type {definition.value_type.type_} is not supported")
|
|
559
|
+
|
|
552
560
|
return cls(
|
|
553
561
|
id_=BNode(),
|
|
554
562
|
path=namespace[definition.property_],
|
|
555
563
|
node_kind=SHACL.IRI if definition.type_ == EntityTypes.object_property else SHACL.Literal,
|
|
556
|
-
expected_value_type=
|
|
557
|
-
namespace[f"{definition.value_type.suffix}Shape"]
|
|
558
|
-
if isinstance(definition.value_type, ClassEntity)
|
|
559
|
-
else XSD[definition.value_type.xsd]
|
|
560
|
-
),
|
|
564
|
+
expected_value_type=expected_value_type,
|
|
561
565
|
min_count=definition.min_count,
|
|
562
566
|
max_count=(
|
|
563
567
|
int(definition.max_count) if definition.max_count and definition.max_count != float("inf") else None
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import re
|
|
1
2
|
from datetime import datetime
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Literal, cast, overload
|
|
@@ -12,12 +13,11 @@ from cognite.neat.rules.importers._base import BaseImporter, Rules, _handle_issu
|
|
|
12
13
|
from cognite.neat.rules.issues import IssueList
|
|
13
14
|
from cognite.neat.rules.models import InformationRules, RoleTypes
|
|
14
15
|
from cognite.neat.rules.models._base import MatchType
|
|
15
|
-
from cognite.neat.rules.models.entities import ClassEntity
|
|
16
16
|
from cognite.neat.rules.models.information import (
|
|
17
17
|
InformationMetadata,
|
|
18
18
|
InformationRulesInput,
|
|
19
19
|
)
|
|
20
|
-
from cognite.neat.utils.utils import get_namespace, remove_namespace
|
|
20
|
+
from cognite.neat.utils.utils import get_namespace, remove_namespace
|
|
21
21
|
|
|
22
22
|
ORDERED_CLASSES_QUERY = """SELECT ?class (count(?s) as ?instances )
|
|
23
23
|
WHERE { ?s a ?class . }
|
|
@@ -39,29 +39,21 @@ class InferenceImporter(BaseImporter):
|
|
|
39
39
|
issue_list: Issue list to store issues
|
|
40
40
|
graph: Knowledge graph
|
|
41
41
|
max_number_of_instance: Maximum number of instances to be used in inference
|
|
42
|
-
make_compliant: If True, NEAT will attempt to make the imported rules compliant with CDF
|
|
43
42
|
"""
|
|
44
43
|
|
|
45
|
-
def __init__(
|
|
46
|
-
self, issue_list: IssueList, graph: Graph, make_compliant: bool = False, max_number_of_instance: int = -1
|
|
47
|
-
):
|
|
44
|
+
def __init__(self, issue_list: IssueList, graph: Graph, max_number_of_instance: int = -1):
|
|
48
45
|
self.issue_list = issue_list
|
|
49
46
|
self.graph = graph
|
|
50
47
|
self.max_number_of_instance = max_number_of_instance
|
|
51
|
-
self.make_compliant = make_compliant
|
|
52
48
|
|
|
53
49
|
@classmethod
|
|
54
|
-
def from_graph_store(
|
|
55
|
-
cls, store: NeatGraphStoreBase, make_compliant: bool = False, max_number_of_instance: int = -1
|
|
56
|
-
):
|
|
50
|
+
def from_graph_store(cls, store: NeatGraphStoreBase, max_number_of_instance: int = -1):
|
|
57
51
|
issue_list = IssueList(title="Inferred from graph store")
|
|
58
52
|
|
|
59
|
-
return cls(
|
|
60
|
-
issue_list, store.graph, make_compliant=make_compliant, max_number_of_instance=max_number_of_instance
|
|
61
|
-
)
|
|
53
|
+
return cls(issue_list, store.graph, max_number_of_instance=max_number_of_instance)
|
|
62
54
|
|
|
63
55
|
@classmethod
|
|
64
|
-
def from_rdf_file(cls, filepath: Path,
|
|
56
|
+
def from_rdf_file(cls, filepath: Path, max_number_of_instance: int = -1):
|
|
65
57
|
issue_list = IssueList(title=f"'{filepath.name}'")
|
|
66
58
|
|
|
67
59
|
graph = Graph()
|
|
@@ -70,18 +62,18 @@ class InferenceImporter(BaseImporter):
|
|
|
70
62
|
except Exception:
|
|
71
63
|
issue_list.append(issues.fileread.FileReadError(filepath))
|
|
72
64
|
|
|
73
|
-
return cls(issue_list, graph,
|
|
65
|
+
return cls(issue_list, graph, max_number_of_instance=max_number_of_instance)
|
|
74
66
|
|
|
75
67
|
@classmethod
|
|
76
|
-
def from_json_file(cls, filepath: Path,
|
|
68
|
+
def from_json_file(cls, filepath: Path, max_number_of_instance: int = -1):
|
|
77
69
|
raise NotImplementedError("JSON file format is not supported yet.")
|
|
78
70
|
|
|
79
71
|
@classmethod
|
|
80
|
-
def from_yaml_file(cls, filepath: Path,
|
|
72
|
+
def from_yaml_file(cls, filepath: Path, max_number_of_instance: int = -1):
|
|
81
73
|
raise NotImplementedError("YAML file format is not supported yet.")
|
|
82
74
|
|
|
83
75
|
@classmethod
|
|
84
|
-
def from_xml_file(cls, filepath: Path,
|
|
76
|
+
def from_xml_file(cls, filepath: Path, max_number_of_instance: int = -1):
|
|
85
77
|
raise NotImplementedError("JSON file format is not supported yet.")
|
|
86
78
|
|
|
87
79
|
@overload
|
|
@@ -117,9 +109,6 @@ class InferenceImporter(BaseImporter):
|
|
|
117
109
|
if future.result == "failure" or self.issue_list.has_errors:
|
|
118
110
|
return self._return_or_raise(self.issue_list, errors)
|
|
119
111
|
|
|
120
|
-
if self.make_compliant and rules:
|
|
121
|
-
self._make_dms_compliant_rules(rules)
|
|
122
|
-
|
|
123
112
|
return self._to_output(
|
|
124
113
|
rules,
|
|
125
114
|
self.issue_list,
|
|
@@ -155,7 +144,7 @@ class InferenceImporter(BaseImporter):
|
|
|
155
144
|
"class_": class_id,
|
|
156
145
|
"reference": class_uri,
|
|
157
146
|
"match_type": MatchType.exact,
|
|
158
|
-
"comment": f"Inferred from knowledge graph, where this class has {no_instances} instances",
|
|
147
|
+
"comment": f"Inferred from knowledge graph, where this class has <{no_instances}> instances",
|
|
159
148
|
}
|
|
160
149
|
|
|
161
150
|
# Infers all the properties of the class
|
|
@@ -179,7 +168,7 @@ class InferenceImporter(BaseImporter):
|
|
|
179
168
|
|
|
180
169
|
self._add_uri_namespace_to_prefixes(cast(URIRef, value_type_uri), prefixes)
|
|
181
170
|
value_type_id = remove_namespace(value_type_uri)
|
|
182
|
-
id_ = f"{class_id}:{property_id}
|
|
171
|
+
id_ = f"{class_id}:{property_id}"
|
|
183
172
|
|
|
184
173
|
definition = {
|
|
185
174
|
"class_": class_id,
|
|
@@ -187,15 +176,41 @@ class InferenceImporter(BaseImporter):
|
|
|
187
176
|
"max_count": cast(RdfLiteral, occurrence).value,
|
|
188
177
|
"value_type": value_type_id,
|
|
189
178
|
"reference": property_uri,
|
|
179
|
+
"comment": (
|
|
180
|
+
f"Class <{class_id}> has property <{property_id}> with "
|
|
181
|
+
f"value type <{value_type_id}> which occurs <1> times in the graph"
|
|
182
|
+
),
|
|
190
183
|
}
|
|
191
184
|
|
|
192
185
|
# USE CASE 1: If property is not present in properties
|
|
193
186
|
if id_ not in properties:
|
|
194
187
|
properties[id_] = definition
|
|
195
|
-
|
|
196
|
-
|
|
188
|
+
|
|
189
|
+
# USE CASE 2: first time redefinition, value type change to multi
|
|
190
|
+
elif id_ in properties and definition["value_type"] not in properties[id_]["value_type"]:
|
|
191
|
+
properties[id_]["value_type"] = properties[id_]["value_type"] + " | " + definition["value_type"]
|
|
192
|
+
properties[id_]["comment"] = (
|
|
193
|
+
properties[id_]["comment"] + ", with" + definition["comment"].split("with")[1]
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# USE CASE 3: existing but max count is different
|
|
197
|
+
elif (
|
|
198
|
+
id_ in properties
|
|
199
|
+
and definition["value_type"] in properties[id_]["value_type"]
|
|
200
|
+
and not (properties[id_]["max_count"] == definition["max_count"])
|
|
201
|
+
):
|
|
197
202
|
properties[id_]["max_count"] = max(properties[id_]["max_count"], definition["max_count"])
|
|
198
203
|
|
|
204
|
+
properties[id_]["comment"] = self._update_value_type_occurrence_in_comment(
|
|
205
|
+
definition["value_type"], properties[id_]["comment"]
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
# USE CASE 4: Just update the comment with occurrence
|
|
209
|
+
else:
|
|
210
|
+
properties[id_]["comment"] = self._update_value_type_occurrence_in_comment(
|
|
211
|
+
definition["value_type"], properties[id_]["comment"]
|
|
212
|
+
)
|
|
213
|
+
|
|
199
214
|
return {
|
|
200
215
|
"metadata": self._default_metadata().model_dump(),
|
|
201
216
|
"classes": list(classes.values()),
|
|
@@ -228,36 +243,17 @@ class InferenceImporter(BaseImporter):
|
|
|
228
243
|
)
|
|
229
244
|
|
|
230
245
|
@classmethod
|
|
231
|
-
def
|
|
232
|
-
cls.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
seen = set()
|
|
238
|
-
for i, property_ in enumerate(rules.properties.data):
|
|
239
|
-
prop_id = f"{property_.class_}.{property_.property_}"
|
|
240
|
-
if prop_id in seen:
|
|
241
|
-
property_.property_ = f"{property_.property_}_{i+1}"
|
|
242
|
-
seen.add(f"{property_.class_}.{property_.property_}")
|
|
243
|
-
else:
|
|
244
|
-
seen.add(prop_id)
|
|
246
|
+
def _update_value_type_occurrence_in_comment(cls, value_type: str, comment: str) -> str:
|
|
247
|
+
occurrence = cls._read_value_type_occurrence_from_comment(value_type, comment)
|
|
248
|
+
return comment.replace(
|
|
249
|
+
f"with value type <{value_type}> which occurs <{occurrence}> times in the graph",
|
|
250
|
+
f"with value type <{value_type}> which occurs <{occurrence+1}> times in the graph",
|
|
251
|
+
)
|
|
245
252
|
|
|
246
253
|
@classmethod
|
|
247
|
-
def
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
# Fixing property definitions
|
|
254
|
-
for property_ in rules.properties:
|
|
255
|
-
# fix class id
|
|
256
|
-
property_.class_ = property_.class_.as_dms_compliant_entity()
|
|
257
|
-
|
|
258
|
-
# fix property id
|
|
259
|
-
property_.property_ = replace_non_alphanumeric_with_underscore(property_.property_)
|
|
260
|
-
|
|
261
|
-
# fix value type
|
|
262
|
-
if isinstance(property_.value_type, ClassEntity):
|
|
263
|
-
property_.value_type = property_.value_type.as_dms_compliant_entity()
|
|
254
|
+
def _read_value_type_occurrence_from_comment(cls, value_type: str, comment: str) -> int:
|
|
255
|
+
return int(
|
|
256
|
+
cast(
|
|
257
|
+
re.Match, re.search(rf"with value type <{value_type}> which occurs <(\d+)> times in the graph", comment)
|
|
258
|
+
).group(1)
|
|
259
|
+
)
|
|
@@ -5,8 +5,17 @@ from functools import total_ordering
|
|
|
5
5
|
from typing import Annotated, Any, ClassVar, Generic, TypeVar, cast
|
|
6
6
|
|
|
7
7
|
from cognite.client.data_classes.data_modeling.ids import ContainerId, DataModelId, NodeId, PropertyId, ViewId
|
|
8
|
-
from pydantic import
|
|
8
|
+
from pydantic import (
|
|
9
|
+
AnyHttpUrl,
|
|
10
|
+
BaseModel,
|
|
11
|
+
BeforeValidator,
|
|
12
|
+
Field,
|
|
13
|
+
PlainSerializer,
|
|
14
|
+
model_serializer,
|
|
15
|
+
model_validator,
|
|
16
|
+
)
|
|
9
17
|
|
|
18
|
+
from cognite.neat.rules.models.data_types import DataType
|
|
10
19
|
from cognite.neat.utils.utils import replace_non_alphanumeric_with_underscore
|
|
11
20
|
|
|
12
21
|
if sys.version_info >= (3, 11):
|
|
@@ -38,6 +47,7 @@ class EntityTypes(StrEnum):
|
|
|
38
47
|
container = "container"
|
|
39
48
|
datamodel = "datamodel"
|
|
40
49
|
undefined = "undefined"
|
|
50
|
+
multi_value_type = "multi_value_type"
|
|
41
51
|
|
|
42
52
|
|
|
43
53
|
# ALLOWED
|
|
@@ -58,6 +68,7 @@ _CLASS_ID_REGEX_COMPILED = re.compile(rf"^{_CLASS_ID_REGEX}$")
|
|
|
58
68
|
_PROPERTY_ID_REGEX = rf"\((?P<{EntityTypes.property_}>{_ENTITY_ID_REGEX})\)"
|
|
59
69
|
|
|
60
70
|
_ENTITY_PATTERN = re.compile(r"^(?P<prefix>.*?):?(?P<suffix>[^(:]*)(\((?P<content>[^)]+)\))?$")
|
|
71
|
+
_MULTI_VALUE_TYPE_PATTERN = re.compile(r"^(?P<types>.*?)(\((?P<content>[^)]+)\))?$")
|
|
61
72
|
|
|
62
73
|
|
|
63
74
|
class _UndefinedType(BaseModel): ...
|
|
@@ -238,11 +249,6 @@ class ClassEntity(Entity):
|
|
|
238
249
|
space = default_space if isinstance(self.prefix, _UndefinedType) else self.prefix
|
|
239
250
|
return ContainerEntity(space=space, externalId=str(self.suffix))
|
|
240
251
|
|
|
241
|
-
def as_dms_compliant_entity(self) -> "Self":
|
|
242
|
-
new_entity = self.model_copy(deep=True)
|
|
243
|
-
new_entity.suffix = replace_non_alphanumeric_with_underscore(new_entity.suffix)
|
|
244
|
-
return new_entity
|
|
245
|
-
|
|
246
252
|
|
|
247
253
|
class ParentClassEntity(ClassEntity):
|
|
248
254
|
type_: ClassVar[EntityTypes] = EntityTypes.parent_class
|
|
@@ -264,6 +270,60 @@ class UnknownEntity(ClassEntity):
|
|
|
264
270
|
T_ID = TypeVar("T_ID", bound=ContainerId | ViewId | DataModelId | PropertyId | NodeId | None)
|
|
265
271
|
|
|
266
272
|
|
|
273
|
+
class MultiValueTypeInfo(BaseModel):
|
|
274
|
+
type_: ClassVar[EntityTypes] = EntityTypes.multi_value_type
|
|
275
|
+
types: list[DataType | ClassEntity]
|
|
276
|
+
|
|
277
|
+
def __str__(self) -> str:
|
|
278
|
+
return " | ".join([str(t) for t in self.types])
|
|
279
|
+
|
|
280
|
+
@model_serializer(when_used="unless-none", return_type=str)
|
|
281
|
+
def as_str(self) -> str:
|
|
282
|
+
return str(self)
|
|
283
|
+
|
|
284
|
+
@classmethod
|
|
285
|
+
def load(cls, data: Any) -> "MultiValueTypeInfo":
|
|
286
|
+
# already instance of MultiValueTypeInfo
|
|
287
|
+
if isinstance(data, cls):
|
|
288
|
+
return data
|
|
289
|
+
|
|
290
|
+
# it is a raw string that needs to be parsed
|
|
291
|
+
elif isinstance(data, str):
|
|
292
|
+
return cls.model_validate({_PARSE: data})
|
|
293
|
+
|
|
294
|
+
# it is dict that needs to be parsed
|
|
295
|
+
else:
|
|
296
|
+
return cls.model_validate(data)
|
|
297
|
+
|
|
298
|
+
@model_validator(mode="before")
|
|
299
|
+
def _load(cls, data: Any) -> "dict | MultiValueTypeInfo":
|
|
300
|
+
if isinstance(data, dict) and _PARSE in data:
|
|
301
|
+
data = data[_PARSE]
|
|
302
|
+
elif isinstance(data, dict):
|
|
303
|
+
return data
|
|
304
|
+
else:
|
|
305
|
+
raise ValueError(f"Cannot load {cls.__name__} from {data}")
|
|
306
|
+
|
|
307
|
+
result = cls._parse(data)
|
|
308
|
+
return result
|
|
309
|
+
|
|
310
|
+
@classmethod
|
|
311
|
+
def _parse(cls, raw: str) -> dict:
|
|
312
|
+
if not (types := [type_.strip() for type_ in raw.split("|")]):
|
|
313
|
+
return {"types": [UnknownEntity()]}
|
|
314
|
+
else:
|
|
315
|
+
return {
|
|
316
|
+
"types": [
|
|
317
|
+
DataType.load(type_) if DataType.is_data_type(type_) else ClassEntity.load(type_) for type_ in types
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
def set_default_prefix(self, prefix: str):
|
|
322
|
+
for type_ in self.types:
|
|
323
|
+
if isinstance(type_, ClassEntity) and type_.prefix is Undefined:
|
|
324
|
+
type_.prefix = prefix
|
|
325
|
+
|
|
326
|
+
|
|
267
327
|
class DMSEntity(Entity, Generic[T_ID], ABC):
|
|
268
328
|
type_: ClassVar[EntityTypes] = EntityTypes.undefined
|
|
269
329
|
prefix: str = Field(alias="space")
|
|
@@ -297,6 +357,11 @@ class DMSEntity(Entity, Generic[T_ID], ABC):
|
|
|
297
357
|
def as_class(self) -> ClassEntity:
|
|
298
358
|
return ClassEntity(prefix=self.space, suffix=self.external_id)
|
|
299
359
|
|
|
360
|
+
def as_dms_compliant_entity(self) -> "Self":
|
|
361
|
+
new_entity = self.model_copy(deep=True)
|
|
362
|
+
new_entity.suffix = replace_non_alphanumeric_with_underscore(new_entity.suffix)
|
|
363
|
+
return new_entity
|
|
364
|
+
|
|
300
365
|
|
|
301
366
|
T_DMSEntity = TypeVar("T_DMSEntity", bound=DMSEntity)
|
|
302
367
|
|
|
@@ -44,6 +44,7 @@ from cognite.neat.rules.models.domain import DomainRules
|
|
|
44
44
|
from cognite.neat.rules.models.entities import (
|
|
45
45
|
ClassEntity,
|
|
46
46
|
EntityTypes,
|
|
47
|
+
MultiValueTypeInfo,
|
|
47
48
|
ParentClassEntity,
|
|
48
49
|
ParentEntityList,
|
|
49
50
|
ReferenceEntity,
|
|
@@ -162,7 +163,9 @@ class InformationProperty(SheetEntity):
|
|
|
162
163
|
property_: PropertyType = Field(alias="Property")
|
|
163
164
|
name: str | None = Field(alias="Name", default=None)
|
|
164
165
|
description: str | None = Field(alias="Description", default=None)
|
|
165
|
-
value_type: DataType | ClassEntity | UnknownEntity = Field(
|
|
166
|
+
value_type: DataType | ClassEntity | MultiValueTypeInfo | UnknownEntity = Field(
|
|
167
|
+
alias="Value Type", union_mode="left_to_right"
|
|
168
|
+
)
|
|
166
169
|
min_count: int | None = Field(alias="Min Count", default=None)
|
|
167
170
|
max_count: int | float | None = Field(alias="Max Count", default=None)
|
|
168
171
|
default: Any | None = Field(alias="Default", default=None)
|
|
@@ -277,6 +280,10 @@ class InformationRules(BaseRules):
|
|
|
277
280
|
for property_ in self.properties:
|
|
278
281
|
if isinstance(property_.value_type, ClassEntity) and property_.value_type.prefix is Undefined:
|
|
279
282
|
property_.value_type.prefix = self.metadata.prefix
|
|
283
|
+
|
|
284
|
+
if isinstance(property_.value_type, MultiValueTypeInfo):
|
|
285
|
+
property_.value_type.set_default_prefix(self.metadata.prefix)
|
|
286
|
+
|
|
280
287
|
if property_.class_.prefix is Undefined:
|
|
281
288
|
property_.class_.prefix = self.metadata.prefix
|
|
282
289
|
|
|
@@ -7,7 +7,13 @@ from rdflib import Namespace
|
|
|
7
7
|
|
|
8
8
|
from cognite.neat.rules.models._base import DataModelType, ExtensionCategory, SchemaCompleteness, _add_alias
|
|
9
9
|
from cognite.neat.rules.models.data_types import DataType
|
|
10
|
-
from cognite.neat.rules.models.entities import
|
|
10
|
+
from cognite.neat.rules.models.entities import (
|
|
11
|
+
ClassEntity,
|
|
12
|
+
MultiValueTypeInfo,
|
|
13
|
+
ParentClassEntity,
|
|
14
|
+
Unknown,
|
|
15
|
+
UnknownEntity,
|
|
16
|
+
)
|
|
11
17
|
|
|
12
18
|
from ._rules import InformationClass, InformationMetadata, InformationProperty, InformationRules
|
|
13
19
|
|
|
@@ -121,10 +127,15 @@ class InformationPropertyInput:
|
|
|
121
127
|
)
|
|
122
128
|
|
|
123
129
|
def dump(self, default_prefix: str) -> dict[str, Any]:
|
|
124
|
-
value_type: DataType | ClassEntity | UnknownEntity
|
|
130
|
+
value_type: MultiValueTypeInfo | DataType | ClassEntity | UnknownEntity
|
|
125
131
|
|
|
126
132
|
# property holding xsd data type
|
|
127
|
-
if
|
|
133
|
+
# check if it is multi value type
|
|
134
|
+
if "|" in self.value_type:
|
|
135
|
+
value_type = MultiValueTypeInfo.load(self.value_type)
|
|
136
|
+
value_type.set_default_prefix(default_prefix)
|
|
137
|
+
|
|
138
|
+
elif DataType.is_data_type(self.value_type):
|
|
128
139
|
value_type = DataType.load(self.value_type)
|
|
129
140
|
|
|
130
141
|
# unknown value type
|
|
@@ -257,6 +268,7 @@ class InformationRulesInput:
|
|
|
257
268
|
elif isinstance(self.last, InformationRules):
|
|
258
269
|
# We need to load through the InformationRulesInput to set the correct default space and version
|
|
259
270
|
last = InformationRulesInput.load(self.last.model_dump()).dump()
|
|
271
|
+
|
|
260
272
|
return dict(
|
|
261
273
|
Metadata=self.metadata.dump(),
|
|
262
274
|
Properties=[prop.dump(default_prefix) for prop in self.properties],
|
|
@@ -276,16 +276,6 @@ class RulesInferenceFromRdfFile(Step):
|
|
|
276
276
|
label="For what role Rules are intended?",
|
|
277
277
|
options=["infer", *RoleTypes.__members__.keys()],
|
|
278
278
|
),
|
|
279
|
-
Configurable(
|
|
280
|
-
name="Make compliant",
|
|
281
|
-
value="True",
|
|
282
|
-
label=(
|
|
283
|
-
"Attempt to make the imported Rules compliant, by fixing "
|
|
284
|
-
"redefinition of properties and by making ids of entities compliant with"
|
|
285
|
-
" CDF-allowed set of characters ."
|
|
286
|
-
),
|
|
287
|
-
options=["True", "False"],
|
|
288
|
-
),
|
|
289
279
|
Configurable(
|
|
290
280
|
name="Maximum number of instances to process",
|
|
291
281
|
value="-1",
|
|
@@ -302,7 +292,6 @@ class RulesInferenceFromRdfFile(Step):
|
|
|
302
292
|
|
|
303
293
|
file_path = self.configs.get("File path", None)
|
|
304
294
|
full_path = flow_message.payload.get("full_path", None) if flow_message.payload else None
|
|
305
|
-
make_compliant = self.configs.get("Make compliant", "True") == "True"
|
|
306
295
|
|
|
307
296
|
try:
|
|
308
297
|
max_number_of_instance = int(self.configs.get("Maximum number of instances to process", -1))
|
|
@@ -325,7 +314,7 @@ class RulesInferenceFromRdfFile(Step):
|
|
|
325
314
|
role_enum = RoleTypes[role]
|
|
326
315
|
|
|
327
316
|
inference_importer = importers.InferenceImporter.from_rdf_file(
|
|
328
|
-
rdf_file_path,
|
|
317
|
+
rdf_file_path, max_number_of_instance=max_number_of_instance
|
|
329
318
|
)
|
|
330
319
|
rules, issues = inference_importer.to_rules(errors="continue", role=role_enum)
|
|
331
320
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
cognite/neat/__init__.py,sha256=v-rRiDOgZ3sQSMQKq0vgUQZvpeOkoHFXissAx6Ktg84,61
|
|
2
|
-
cognite/neat/_version.py,sha256=
|
|
2
|
+
cognite/neat/_version.py,sha256=oEHe9RtsScnXCOzPdKOEz68VfnXPGqwRpt9BirfOZTw,23
|
|
3
3
|
cognite/neat/app/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
cognite/neat/app/api/asgi/metrics.py,sha256=nxFy7L5cChTI0a-zkCiJ59Aq8yLuIJp5c9Dg0wRXtV0,152
|
|
5
5
|
cognite/neat/app/api/configuration.py,sha256=2U5M6M252swvQPQyooA1EBzFUZNtcTmuSaywfJDgckM,4232
|
|
@@ -167,7 +167,7 @@ cognite/neat/rules/exporters/_base.py,sha256=m63iw8xjlZbZAxGL8mn7pjGf1pW3rVv8C20
|
|
|
167
167
|
cognite/neat/rules/exporters/_models.py,sha256=vRd0P_YsrZ1eaAGGHfdTeFunaqHdaa0ZtnWiVZBR1nc,1976
|
|
168
168
|
cognite/neat/rules/exporters/_rules2dms.py,sha256=US2IO4YTJSF_CDzau1dTpXyeHntJWVSPkMCQoUoKeC0,13688
|
|
169
169
|
cognite/neat/rules/exporters/_rules2excel.py,sha256=HvUdXYHxfLMijYWdTnfqCsw3Izf8S-XDSve-2ZbqF8Y,14248
|
|
170
|
-
cognite/neat/rules/exporters/_rules2ontology.py,sha256=
|
|
170
|
+
cognite/neat/rules/exporters/_rules2ontology.py,sha256=Od53uLdcC2Q7UiF5PA2P0gw3O14eTD3MeJ1-trd64ZM,20388
|
|
171
171
|
cognite/neat/rules/exporters/_rules2yaml.py,sha256=GA8eUYRxUfIU6IMvlyGO5JidkOD5eUKSbH3qAiFiaCg,3026
|
|
172
172
|
cognite/neat/rules/exporters/_validation.py,sha256=OlKIyf4nhSDehJwFHDQ8Zdf6HpNfW7dSe2s67eywHu4,4078
|
|
173
173
|
cognite/neat/rules/importers/__init__.py,sha256=gR6_TAEa3iO5NCLKRztHg-FMiLdBnx47Z3iSzbwLfcE,481
|
|
@@ -178,7 +178,7 @@ cognite/neat/rules/importers/_dtdl2rules/_unit_lookup.py,sha256=wW4saKva61Q_i17g
|
|
|
178
178
|
cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py,sha256=ysmWUxZ0npwrTB0uiH5jA0v37sfCwowGaYk17IyxPUU,12663
|
|
179
179
|
cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py,sha256=QDyGt5YBaxzF4v_oCFSgKRSpwVdVruDU3-VW0DEiHbY,6718
|
|
180
180
|
cognite/neat/rules/importers/_dtdl2rules/spec.py,sha256=tim_MfN1J0F3Oeqk3BMgIA82d_MZvhRuRMsLK3B4PYc,11897
|
|
181
|
-
cognite/neat/rules/importers/_inference2rules.py,sha256=
|
|
181
|
+
cognite/neat/rules/importers/_inference2rules.py,sha256=JsV3Ii2wmgRELtpV0GC4Y1KtjhyyGR0dtEFpBonHoA8,11213
|
|
182
182
|
cognite/neat/rules/importers/_owl2rules/__init__.py,sha256=tdGcrgtozdQyST-pTlxIa4cLBNTLvtk1nNYR4vOdFSw,63
|
|
183
183
|
cognite/neat/rules/importers/_owl2rules/_owl2classes.py,sha256=QpTxvrTGczIa48X8lgXGnMN1AWPhHK0DR6uNq175xak,7357
|
|
184
184
|
cognite/neat/rules/importers/_owl2rules/_owl2metadata.py,sha256=nwnUaBNAAYMoBre2UmsnkJXUuaqGEpR3U3txDrH2w6g,7527
|
|
@@ -210,11 +210,11 @@ cognite/neat/rules/models/dms/_schema.py,sha256=A4z8CINmLQgWzHoScxejRPMRo40ngKly
|
|
|
210
210
|
cognite/neat/rules/models/dms/_serializer.py,sha256=iqp2zyyf8jEcU-R3PERuN8nu248xIqyxiWj4owAn92g,6406
|
|
211
211
|
cognite/neat/rules/models/dms/_validation.py,sha256=nPSyfM1vGZ7d9Uv_2vF2HvMetygtehXW7eNtPD6eW8E,13937
|
|
212
212
|
cognite/neat/rules/models/domain.py,sha256=tkKcHvDXnZ5IkOr1wHiuNBtE1h8OCFmf6GZSqzHzxjI,2814
|
|
213
|
-
cognite/neat/rules/models/entities.py,sha256=
|
|
213
|
+
cognite/neat/rules/models/entities.py,sha256=lkLsKg8U3Xto30PCB85ScDpv2SPRVq1ukVEQHzH53_g,18868
|
|
214
214
|
cognite/neat/rules/models/information/__init__.py,sha256=HR6g8xgyU53U7Ck8pPdbT70817Q4NC1r1pCRq5SA8iw,291
|
|
215
215
|
cognite/neat/rules/models/information/_converter.py,sha256=JN63_G5bygdL5WCz-q0_ygiU0NHkzUxm5mZ3WD8yUes,11029
|
|
216
|
-
cognite/neat/rules/models/information/_rules.py,sha256=
|
|
217
|
-
cognite/neat/rules/models/information/_rules_input.py,sha256=
|
|
216
|
+
cognite/neat/rules/models/information/_rules.py,sha256=bUzDzwFyWK9EH0FKCQPH9DCfKG3AUtBHaOshTW7VMRY,13476
|
|
217
|
+
cognite/neat/rules/models/information/_rules_input.py,sha256=xmcQQl2vBYSG_IbxOwb6x4CdN3nIg_TY2-3RAeGDYic,10418
|
|
218
218
|
cognite/neat/rules/models/information/_serializer.py,sha256=yti9I_xJruxrib66YIBInhze___Io-oPTQH6uWDumPE,3503
|
|
219
219
|
cognite/neat/rules/models/information/_validation.py,sha256=Is2GzL2lZU3A5zPu3NjvlXfmIU2_Y10C5Nxi5Denz4g,7528
|
|
220
220
|
cognite/neat/rules/models/wrapped_entities.py,sha256=ThhjnNNrpgz0HeORIQ8Q894trxP73P7T_TuZj6qH2CU,7157
|
|
@@ -259,7 +259,7 @@ cognite/neat/workflows/steps/lib/current/graph_extractor.py,sha256=vW9UpJScx5dFV
|
|
|
259
259
|
cognite/neat/workflows/steps/lib/current/graph_loader.py,sha256=HfGg1HRZhbV58TFu89FTjKeUxGsbCYLeFJIQFDN_pQM,2341
|
|
260
260
|
cognite/neat/workflows/steps/lib/current/graph_store.py,sha256=r7VTxdaz8jJQU7FJbnRDMxvEYbSAZFNMABhPyfNwiFk,6295
|
|
261
261
|
cognite/neat/workflows/steps/lib/current/rules_exporter.py,sha256=iFwzDWgUDBSPajaNAcXvu9pVw-jX66upvwyMXyTq7SE,23822
|
|
262
|
-
cognite/neat/workflows/steps/lib/current/rules_importer.py,sha256=
|
|
262
|
+
cognite/neat/workflows/steps/lib/current/rules_importer.py,sha256=QaGEVJ0JFoDbUt4YuJMQQrmL8jVubIzC077g4Wq9iCs,14697
|
|
263
263
|
cognite/neat/workflows/steps/lib/current/rules_validator.py,sha256=LwF9lXlnuPOxDSsOMMTHBi2BHc5rk08IF5zahS9yQuw,4844
|
|
264
264
|
cognite/neat/workflows/steps/lib/io/__init__.py,sha256=k7IPbIq3ey19oRc5sA_15F99-O6dxzqbm1LihGRRo5A,32
|
|
265
265
|
cognite/neat/workflows/steps/lib/io/io_steps.py,sha256=QAGypoi1vP32BRiIgBZ0B4qsbFMcwhzpRiVUUnWysLA,16874
|
|
@@ -276,8 +276,8 @@ cognite/neat/workflows/steps_registry.py,sha256=fkTX14ZA7_gkUYfWIlx7A1XbCidvqR23
|
|
|
276
276
|
cognite/neat/workflows/tasks.py,sha256=dqlJwKAb0jlkl7abbY8RRz3m7MT4SK8-7cntMWkOYjw,788
|
|
277
277
|
cognite/neat/workflows/triggers.py,sha256=_BLNplzoz0iic367u1mhHMHiUrCwP-SLK6_CZzfODX0,7071
|
|
278
278
|
cognite/neat/workflows/utils.py,sha256=gKdy3RLG7ctRhbCRwaDIWpL9Mi98zm56-d4jfHDqP1E,453
|
|
279
|
-
cognite_neat-0.78.
|
|
280
|
-
cognite_neat-0.78.
|
|
281
|
-
cognite_neat-0.78.
|
|
282
|
-
cognite_neat-0.78.
|
|
283
|
-
cognite_neat-0.78.
|
|
279
|
+
cognite_neat-0.78.3.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
|
|
280
|
+
cognite_neat-0.78.3.dist-info/METADATA,sha256=rvUofmdp5RnFDBlXQwKlBytNiizOBnvhA1rJcEOunjg,9306
|
|
281
|
+
cognite_neat-0.78.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
282
|
+
cognite_neat-0.78.3.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
|
|
283
|
+
cognite_neat-0.78.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|