cognite-neat 0.99.0__py3-none-any.whl → 0.100.0__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 +390 -116
- cognite/neat/_client/_api/schema.py +63 -2
- cognite/neat/_client/data_classes/data_modeling.py +4 -0
- cognite/neat/_client/data_classes/schema.py +2 -348
- cognite/neat/_constants.py +27 -4
- cognite/neat/_graph/extractors/_base.py +7 -0
- cognite/neat/_graph/extractors/_classic_cdf/_classic.py +28 -18
- cognite/neat/_graph/loaders/_rdf2dms.py +52 -13
- cognite/neat/_graph/transformers/__init__.py +3 -3
- cognite/neat/_graph/transformers/_classic_cdf.py +135 -56
- 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 +6 -2
- cognite/neat/_issues/warnings/_external.py +9 -1
- cognite/neat/_issues/warnings/_resources.py +41 -2
- cognite/neat/_issues/warnings/user_modeling.py +4 -4
- cognite/neat/_rules/_constants.py +2 -6
- cognite/neat/_rules/analysis/_base.py +15 -5
- cognite/neat/_rules/analysis/_dms.py +20 -0
- cognite/neat/_rules/analysis/_information.py +22 -0
- cognite/neat/_rules/exporters/_base.py +3 -5
- cognite/neat/_rules/exporters/_rules2dms.py +190 -200
- 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 +40 -7
- cognite/neat/_rules/importers/_rdf/_owl2rules.py +80 -0
- cognite/neat/_rules/importers/_rdf/_shared.py +138 -441
- cognite/neat/_rules/models/_base_rules.py +19 -0
- cognite/neat/_rules/models/_types.py +5 -0
- cognite/neat/_rules/models/dms/__init__.py +2 -0
- cognite/neat/_rules/models/dms/_exporter.py +247 -123
- cognite/neat/_rules/models/dms/_rules.py +7 -49
- cognite/neat/_rules/models/dms/_rules_input.py +8 -3
- cognite/neat/_rules/models/dms/_validation.py +421 -123
- cognite/neat/_rules/models/entities/_multi_value.py +3 -0
- cognite/neat/_rules/models/information/__init__.py +2 -0
- cognite/neat/_rules/models/information/_rules.py +17 -61
- cognite/neat/_rules/models/information/_rules_input.py +11 -2
- cognite/neat/_rules/models/information/_validation.py +107 -11
- cognite/neat/_rules/models/mapping/_classic2core.py +1 -1
- cognite/neat/_rules/models/mapping/_classic2core.yaml +8 -4
- cognite/neat/_rules/transformers/__init__.py +2 -1
- cognite/neat/_rules/transformers/_converters.py +163 -61
- cognite/neat/_rules/transformers/_mapping.py +132 -2
- cognite/neat/_rules/transformers/_pipelines.py +1 -1
- cognite/neat/_rules/transformers/_verification.py +29 -4
- cognite/neat/_session/_base.py +46 -60
- cognite/neat/_session/_mapping.py +105 -5
- cognite/neat/_session/_prepare.py +49 -14
- cognite/neat/_session/_read.py +50 -4
- cognite/neat/_session/_set.py +1 -0
- cognite/neat/_session/_to.py +38 -12
- cognite/neat/_session/_wizard.py +5 -0
- cognite/neat/_session/engine/_interface.py +3 -2
- cognite/neat/_session/exceptions.py +4 -0
- cognite/neat/_store/_base.py +79 -19
- cognite/neat/_utils/collection_.py +22 -0
- cognite/neat/_utils/rdf_.py +30 -4
- cognite/neat/_version.py +2 -2
- cognite/neat/_workflows/steps/lib/current/rules_exporter.py +3 -91
- 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.100.0.dist-info}/METADATA +1 -1
- {cognite_neat-0.99.0.dist-info → cognite_neat-0.100.0.dist-info}/RECORD +74 -82
- 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.100.0.dist-info}/LICENSE +0 -0
- {cognite_neat-0.99.0.dist-info → cognite_neat-0.100.0.dist-info}/WHEEL +0 -0
- {cognite_neat-0.99.0.dist-info → cognite_neat-0.100.0.dist-info}/entry_points.txt +0 -0
|
@@ -13,6 +13,21 @@ class ResourceNeatWarning(NeatWarning, Generic[T_Identifier]):
|
|
|
13
13
|
resource_type: ResourceType
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
@dataclass(unsafe_hash=True)
|
|
17
|
+
class ResourceRegexViolationWarning(ResourceNeatWarning):
|
|
18
|
+
"""The {resource_type} with identifier {identifier} in the {location} is violating
|
|
19
|
+
the CDF regex {regex}. This will lead to errors when converting to DMS data model.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
fix = (
|
|
23
|
+
"Either export the data model and make the necessary changes manually"
|
|
24
|
+
" or run prepare.cdf_compliant_external_ids."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
location: str
|
|
28
|
+
regex: str
|
|
29
|
+
|
|
30
|
+
|
|
16
31
|
@dataclass(unsafe_hash=True)
|
|
17
32
|
class ResourceNotFoundWarning(ResourceNeatWarning, Generic[T_Identifier, T_ReferenceIdentifier]):
|
|
18
33
|
"""The {resource_type} with identifier {identifier} referred by {referred_type} {referred_by} does not exist.
|
|
@@ -24,6 +39,30 @@ class ResourceNotFoundWarning(ResourceNeatWarning, Generic[T_Identifier, T_Refer
|
|
|
24
39
|
referred_type: str
|
|
25
40
|
|
|
26
41
|
|
|
42
|
+
@dataclass(unsafe_hash=True)
|
|
43
|
+
class ResourceNotDefinedWarning(ResourceNeatWarning, Generic[T_Identifier, T_ReferenceIdentifier]):
|
|
44
|
+
"""The {resource_type} {identifier} is not defined in the {location}"""
|
|
45
|
+
|
|
46
|
+
extra = "{column_name} {row_number} in {sheet_name}"
|
|
47
|
+
fix = "Define the {resource_type} {identifier} in {location}."
|
|
48
|
+
|
|
49
|
+
location: str
|
|
50
|
+
column_name: str | None = None
|
|
51
|
+
row_number: int | None = None
|
|
52
|
+
sheet_name: str | None = None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass(unsafe_hash=True)
|
|
56
|
+
class ResourceRedefinedWarning(ResourceNeatWarning, Generic[T_Identifier, T_ReferenceIdentifier]):
|
|
57
|
+
"""The {resource_type} {identifier} feature {feature} is being redefine from {current_value} to {new_value}.
|
|
58
|
+
This will be ignored."""
|
|
59
|
+
|
|
60
|
+
fix = "Avoid redefinition {resource_type} features"
|
|
61
|
+
feature: str
|
|
62
|
+
current_value: str
|
|
63
|
+
new_value: str
|
|
64
|
+
|
|
65
|
+
|
|
27
66
|
@dataclass(unsafe_hash=True)
|
|
28
67
|
class ResourcesDuplicatedWarning(NeatWarning, Generic[T_Identifier]):
|
|
29
68
|
"""Duplicated {resource_type} with identifiers {resources} were found. {default_action}"""
|
|
@@ -37,12 +76,12 @@ class ResourcesDuplicatedWarning(NeatWarning, Generic[T_Identifier]):
|
|
|
37
76
|
|
|
38
77
|
@dataclass(unsafe_hash=True)
|
|
39
78
|
class ResourceRetrievalWarning(NeatWarning, Generic[T_Identifier]):
|
|
40
|
-
"""Failed to retrieve {resource_type} with
|
|
79
|
+
"""Failed to retrieve {resource_type} with identifier(s) {resources}. Continuing without
|
|
41
80
|
these resources."""
|
|
42
81
|
|
|
43
82
|
extra = "The error was: {error}"
|
|
44
83
|
|
|
45
|
-
fix = "Check the error."
|
|
84
|
+
fix = "Check the error and fix accordingly."
|
|
46
85
|
|
|
47
86
|
resources: frozenset[T_Identifier]
|
|
48
87
|
resource_type: ResourceType
|
|
@@ -17,7 +17,7 @@ __all__ = [
|
|
|
17
17
|
"HasDataFilterOnNoPropertiesViewWarning",
|
|
18
18
|
"NodeTypeFilterOnParentViewWarning",
|
|
19
19
|
"HasDataFilterOnViewWithReferencesWarning",
|
|
20
|
-
"
|
|
20
|
+
"ContainerPropertyLimitWarning",
|
|
21
21
|
"NotNeatSupportedFilterWarning",
|
|
22
22
|
"ParentInDifferentSpaceWarning",
|
|
23
23
|
]
|
|
@@ -89,15 +89,15 @@ class HasDataFilterOnViewWithReferencesWarning(UserModelingWarning):
|
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
@dataclass(unsafe_hash=True)
|
|
92
|
-
class
|
|
93
|
-
"""The number of properties in the {
|
|
92
|
+
class ContainerPropertyLimitWarning(UserModelingWarning):
|
|
93
|
+
"""The number of properties in the {container_id} view is {count} which
|
|
94
94
|
is more than the API limit {limit} properties.
|
|
95
95
|
This can lead to performance issues.
|
|
96
96
|
Reduce the number of properties in the view."""
|
|
97
97
|
|
|
98
98
|
fix = "Reduce the number of properties in the view"
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
container_id: ContainerId
|
|
101
101
|
count: int
|
|
102
102
|
limit: int = DMS_CONTAINER_PROPERTY_SIZE_LIMIT
|
|
103
103
|
|
|
@@ -106,13 +106,9 @@ VIEW_ID_COMPLIANCE_REGEX = (
|
|
|
106
106
|
DMS_PROPERTY_ID_COMPLIANCE_REGEX = (
|
|
107
107
|
rf"(?!^({'|'.join(get_reserved_words('property'))})$)" r"(^[a-zA-Z][a-zA-Z0-9_]{0,253}[a-zA-Z0-9]?$)"
|
|
108
108
|
)
|
|
109
|
-
CLASS_ID_COMPLIANCE_REGEX = (
|
|
110
|
-
rf"(?!^({'|'.join(get_reserved_words('class'))})$)" r"(^[a-zA-Z][a-zA-Z0-9._-]{0,253}[a-zA-Z0-9]?$)"
|
|
111
|
-
)
|
|
109
|
+
CLASS_ID_COMPLIANCE_REGEX = rf"(?!^({'|'.join(get_reserved_words('class'))})$)" r"(^[a-zA-Z0-9._-]{0,253}[a-zA-Z0-9]?$)"
|
|
112
110
|
|
|
113
|
-
INFORMATION_PROPERTY_ID_COMPLIANCE_REGEX = (
|
|
114
|
-
r"^(\*)|(?!^(Property|property)$)(^[a-zA-Z][a-zA-Z0-9._-]{0,253}[a-zA-Z0-9]?$)"
|
|
115
|
-
)
|
|
111
|
+
INFORMATION_PROPERTY_ID_COMPLIANCE_REGEX = r"^(\*)|(?!^(Property|property)$)(^[a-zA-Z0-9._-]{0,253}[a-zA-Z0-9]?$)"
|
|
116
112
|
VERSION_COMPLIANCE_REGEX = r"^[a-zA-Z0-9]([.a-zA-Z0-9_-]{0,41}[a-zA-Z0-9])?$"
|
|
117
113
|
|
|
118
114
|
|
|
@@ -4,23 +4,25 @@ from abc import ABC, abstractmethod
|
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
from collections.abc import Set
|
|
6
6
|
from dataclasses import dataclass
|
|
7
|
-
from typing import Generic, TypeVar
|
|
7
|
+
from typing import Generic, TypeVar, cast
|
|
8
8
|
|
|
9
9
|
import pandas as pd
|
|
10
|
-
from
|
|
10
|
+
from rdflib import URIRef
|
|
11
11
|
|
|
12
12
|
from cognite.neat._rules.models._base_rules import BaseRules
|
|
13
13
|
from cognite.neat._rules.models._rdfpath import RDFPath
|
|
14
|
+
from cognite.neat._rules.models.dms._rules import DMSProperty, DMSView
|
|
14
15
|
from cognite.neat._rules.models.entities import (
|
|
15
16
|
ClassEntity,
|
|
16
17
|
Entity,
|
|
17
18
|
)
|
|
18
19
|
from cognite.neat._rules.models.information import InformationProperty
|
|
20
|
+
from cognite.neat._rules.models.information._rules import InformationClass
|
|
19
21
|
from cognite.neat._utils.rdf_ import get_inheritance_path
|
|
20
22
|
|
|
21
23
|
T_Rules = TypeVar("T_Rules", bound=BaseRules)
|
|
22
|
-
T_Property = TypeVar("T_Property", bound=
|
|
23
|
-
T_Class = TypeVar("T_Class", bound=
|
|
24
|
+
T_Property = TypeVar("T_Property", bound=InformationProperty | DMSProperty)
|
|
25
|
+
T_Class = TypeVar("T_Class", bound=InformationClass | DMSView)
|
|
24
26
|
T_ClassEntity = TypeVar("T_ClassEntity", bound=Entity)
|
|
25
27
|
T_PropertyEntity = TypeVar("T_PropertyEntity", bound=Entity | str)
|
|
26
28
|
|
|
@@ -108,6 +110,14 @@ class BaseAnalysis(ABC, Generic[T_Rules, T_Class, T_Property, T_ClassEntity, T_P
|
|
|
108
110
|
def inherited_referred_classes(self) -> set[ClassEntity]:
|
|
109
111
|
raise NotImplementedError
|
|
110
112
|
|
|
113
|
+
@property
|
|
114
|
+
def properties_by_neat_id(self) -> dict[URIRef, T_Property]:
|
|
115
|
+
return {cast(URIRef, prop.neatId): prop for prop in self._get_properties()}
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def classes_by_neat_id(self) -> dict[URIRef, T_Class]:
|
|
119
|
+
return {cast(URIRef, class_.neatId): class_ for class_ in self._get_classes()}
|
|
120
|
+
|
|
111
121
|
# Todo Lru cache this method.
|
|
112
122
|
def class_parent_pairs(self, allow_different_space: bool = False) -> dict[T_ClassEntity, list[T_ClassEntity]]:
|
|
113
123
|
"""This only returns class - parent pairs only if parent is in the same data model"""
|
|
@@ -176,7 +186,7 @@ class BaseAnalysis(ABC, Generic[T_Rules, T_Class, T_Property, T_ClassEntity, T_P
|
|
|
176
186
|
# ParentClassEntity -> ClassEntity to match the type of class_property_pairs
|
|
177
187
|
if parent in class_property_pairs:
|
|
178
188
|
for property_ in class_property_pairs[parent]:
|
|
179
|
-
property_ = property_.model_copy()
|
|
189
|
+
property_ = property_.model_copy() # type: ignore
|
|
180
190
|
|
|
181
191
|
# This corresponds to importing properties from parent class
|
|
182
192
|
# making sure that the property is attached to desired child class
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
2
|
+
|
|
3
|
+
from rdflib import URIRef
|
|
4
|
+
|
|
1
5
|
from cognite.neat._constants import DMS_LISTABLE_PROPERTY_LIMIT
|
|
2
6
|
from cognite.neat._rules.models.dms import DMSProperty, DMSRules, DMSView
|
|
3
7
|
from cognite.neat._rules.models.entities import ViewEntity
|
|
@@ -35,3 +39,19 @@ class DMSAnalysis(BaseAnalysis[DMSRules, DMSView, DMSProperty, ViewEntity, str])
|
|
|
35
39
|
|
|
36
40
|
def _get_prop_entity(self, property_: DMSProperty) -> str:
|
|
37
41
|
return property_.view_property
|
|
42
|
+
|
|
43
|
+
def views_with_properties_linked_to_classes(
|
|
44
|
+
self,
|
|
45
|
+
consider_inheritance: bool = False,
|
|
46
|
+
allow_different_namespace: bool = False,
|
|
47
|
+
) -> dict[ViewEntity, dict[str, URIRef]]:
|
|
48
|
+
view_property_pairs = self.classes_with_properties(consider_inheritance, allow_different_namespace)
|
|
49
|
+
|
|
50
|
+
view_and_properties_with_links: dict[ViewEntity, dict[str, URIRef]] = defaultdict(dict)
|
|
51
|
+
|
|
52
|
+
for view, properties in view_property_pairs.items():
|
|
53
|
+
view_and_properties_with_links[view] = {
|
|
54
|
+
prop.view_property: prop.logical for prop in properties if prop.logical
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return view_and_properties_with_links
|
|
@@ -101,6 +101,28 @@ class InformationAnalysis(BaseAnalysis[InformationRules, InformationClass, Infor
|
|
|
101
101
|
|
|
102
102
|
return property_renaming_configuration
|
|
103
103
|
|
|
104
|
+
def neat_id_to_transformation_property_uri(self, property_neat_id: URIRef) -> URIRef | None:
|
|
105
|
+
if (
|
|
106
|
+
(property_ := self.properties_by_neat_id.get(property_neat_id))
|
|
107
|
+
and property_.transformation
|
|
108
|
+
and isinstance(
|
|
109
|
+
property_.transformation.traversal,
|
|
110
|
+
SingleProperty,
|
|
111
|
+
)
|
|
112
|
+
and (
|
|
113
|
+
property_.transformation.traversal.property.prefix in self.rules.prefixes
|
|
114
|
+
or property_.transformation.traversal.property.prefix == self.rules.metadata.prefix
|
|
115
|
+
)
|
|
116
|
+
):
|
|
117
|
+
namespace = (
|
|
118
|
+
self.rules.metadata.namespace
|
|
119
|
+
if property_.transformation.traversal.property.prefix == self.rules.metadata.prefix
|
|
120
|
+
else self.rules.prefixes[property_.transformation.traversal.property.prefix]
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
return namespace[property_.transformation.traversal.property.suffix]
|
|
124
|
+
return None
|
|
125
|
+
|
|
104
126
|
def property_types(self, class_: ClassEntity) -> dict[str, EntityTypes]:
|
|
105
127
|
property_types = {}
|
|
106
128
|
if definitions := self.class_property_pairs(consider_inheritance=True).get(class_, None):
|
|
@@ -31,11 +31,9 @@ class BaseExporter(ABC, Generic[T_VerifiedRules, T_Export]):
|
|
|
31
31
|
class CDFExporter(BaseExporter[T_VerifiedRules, T_Export]):
|
|
32
32
|
@abstractmethod
|
|
33
33
|
def export_to_cdf_iterable(
|
|
34
|
-
self, rules: T_VerifiedRules, client: NeatClient, dry_run: bool = False
|
|
34
|
+
self, rules: T_VerifiedRules, client: NeatClient, dry_run: bool = False
|
|
35
35
|
) -> Iterable[UploadResult]:
|
|
36
36
|
raise NotImplementedError
|
|
37
37
|
|
|
38
|
-
def export_to_cdf(
|
|
39
|
-
self
|
|
40
|
-
) -> UploadResultList:
|
|
41
|
-
return UploadResultList(self.export_to_cdf_iterable(rules, client, dry_run, fallback_one_by_one))
|
|
38
|
+
def export_to_cdf(self, rules: T_VerifiedRules, client: NeatClient, dry_run: bool = False) -> UploadResultList:
|
|
39
|
+
return UploadResultList(self.export_to_cdf_iterable(rules, client, dry_run))
|