cognite-neat 0.103.0__py3-none-any.whl → 0.104.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/_graph/extractors/_mock_graph_generator.py +1 -1
- cognite/neat/_graph/transformers/_base.py +109 -1
- cognite/neat/_graph/transformers/_classic_cdf.py +4 -0
- cognite/neat/_graph/transformers/_prune_graph.py +103 -47
- cognite/neat/_graph/transformers/_rdfpath.py +41 -17
- cognite/neat/_graph/transformers/_value_type.py +119 -154
- cognite/neat/_issues/_base.py +35 -8
- cognite/neat/_issues/warnings/_resources.py +1 -1
- cognite/neat/_rules/_shared.py +18 -34
- cognite/neat/_rules/exporters/_base.py +28 -2
- cognite/neat/_rules/exporters/_rules2dms.py +4 -0
- cognite/neat/_rules/exporters/_rules2excel.py +11 -0
- cognite/neat/_rules/exporters/_rules2instance_template.py +4 -0
- cognite/neat/_rules/exporters/_rules2ontology.py +13 -1
- cognite/neat/_rules/exporters/_rules2yaml.py +4 -0
- cognite/neat/_rules/importers/_base.py +9 -0
- cognite/neat/_rules/importers/_dms2rules.py +17 -5
- cognite/neat/_rules/importers/_dtdl2rules/dtdl_importer.py +5 -2
- cognite/neat/_rules/importers/_rdf/_base.py +10 -8
- cognite/neat/_rules/importers/_rdf/_imf2rules.py +4 -0
- cognite/neat/_rules/importers/_rdf/_inference2rules.py +7 -0
- cognite/neat/_rules/importers/_rdf/_owl2rules.py +4 -0
- cognite/neat/_rules/importers/_spreadsheet2rules.py +17 -8
- cognite/neat/_rules/importers/_yaml2rules.py +21 -7
- cognite/neat/_rules/models/_base_input.py +1 -1
- cognite/neat/_rules/models/_base_rules.py +5 -0
- cognite/neat/_rules/models/dms/_rules.py +4 -0
- cognite/neat/_rules/models/dms/_rules_input.py +9 -0
- cognite/neat/_rules/models/dms/_validation.py +2 -0
- cognite/neat/_rules/models/entities/_single_value.py +25 -5
- cognite/neat/_rules/models/information/_rules.py +4 -0
- cognite/neat/_rules/models/information/_rules_input.py +9 -0
- cognite/neat/_rules/models/mapping/_classic2core.py +2 -5
- cognite/neat/_rules/transformers/__init__.py +5 -4
- cognite/neat/_rules/transformers/_base.py +41 -65
- cognite/neat/_rules/transformers/_converters.py +149 -62
- cognite/neat/_rules/transformers/_mapping.py +17 -12
- cognite/neat/_rules/transformers/_verification.py +50 -37
- cognite/neat/_session/_base.py +32 -121
- cognite/neat/_session/_inspect.py +3 -3
- cognite/neat/_session/_mapping.py +17 -105
- cognite/neat/_session/_prepare.py +36 -254
- cognite/neat/_session/_read.py +11 -130
- cognite/neat/_session/_set.py +6 -30
- cognite/neat/_session/_show.py +49 -30
- cognite/neat/_session/_state.py +49 -107
- cognite/neat/_session/_to.py +42 -31
- cognite/neat/_shared.py +23 -2
- cognite/neat/_store/_provenance.py +3 -82
- cognite/neat/_store/_rules_store.py +372 -10
- cognite/neat/_store/exceptions.py +23 -0
- cognite/neat/_utils/graph_transformations_report.py +36 -0
- cognite/neat/_utils/io_.py +11 -0
- cognite/neat/_utils/rdf_.py +8 -0
- cognite/neat/_utils/spreadsheet.py +5 -4
- cognite/neat/_version.py +1 -1
- cognite/neat/_workflows/steps/lib/current/rules_exporter.py +7 -7
- cognite/neat/_workflows/steps/lib/current/rules_importer.py +24 -99
- {cognite_neat-0.103.0.dist-info → cognite_neat-0.104.0.dist-info}/METADATA +1 -1
- {cognite_neat-0.103.0.dist-info → cognite_neat-0.104.0.dist-info}/RECORD +63 -61
- cognite/neat/_rules/transformers/_pipelines.py +0 -70
- {cognite_neat-0.103.0.dist-info → cognite_neat-0.104.0.dist-info}/LICENSE +0 -0
- {cognite_neat-0.103.0.dist-info → cognite_neat-0.104.0.dist-info}/WHEEL +0 -0
- {cognite_neat-0.103.0.dist-info → cognite_neat-0.104.0.dist-info}/entry_points.txt +0 -0
cognite/neat/_session/_base.py
CHANGED
|
@@ -1,26 +1,17 @@
|
|
|
1
|
-
from
|
|
2
|
-
from typing import Literal, cast
|
|
1
|
+
from typing import Literal
|
|
3
2
|
|
|
4
3
|
from cognite.client import CogniteClient
|
|
5
4
|
from cognite.client import data_modeling as dm
|
|
6
5
|
|
|
7
6
|
from cognite.neat import _version
|
|
8
7
|
from cognite.neat._client import NeatClient
|
|
9
|
-
from cognite.neat._issues import IssueList
|
|
8
|
+
from cognite.neat._issues import IssueList
|
|
10
9
|
from cognite.neat._issues.errors import RegexViolationError
|
|
11
10
|
from cognite.neat._rules import importers
|
|
12
|
-
from cognite.neat._rules.
|
|
13
|
-
from cognite.neat._rules.models import DMSRules
|
|
14
|
-
from cognite.neat._rules.models.dms import DMSValidation
|
|
15
|
-
from cognite.neat._rules.models.information import InformationValidation
|
|
11
|
+
from cognite.neat._rules.models._base_input import InputRules
|
|
16
12
|
from cognite.neat._rules.models.information._rules import InformationRules
|
|
17
|
-
from cognite.neat._rules.models.information._rules_input import InformationInputRules
|
|
18
13
|
from cognite.neat._rules.transformers import ConvertToRules, InformationToDMS, VerifyAnyRules
|
|
19
14
|
from cognite.neat._rules.transformers._converters import ConversionTransformer
|
|
20
|
-
from cognite.neat._store._provenance import (
|
|
21
|
-
INSTANCES_ENTITY,
|
|
22
|
-
Change,
|
|
23
|
-
)
|
|
24
15
|
|
|
25
16
|
from ._collector import _COLLECTOR, Collector
|
|
26
17
|
from ._drop import DropAPI
|
|
@@ -128,47 +119,16 @@ class NeatSession:
|
|
|
128
119
|
neat.verify()
|
|
129
120
|
```
|
|
130
121
|
"""
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
elif isinstance(output.rules, InformationRules):
|
|
140
|
-
issues = InformationValidation(output.rules).validate()
|
|
141
|
-
else:
|
|
142
|
-
raise NeatSessionError("Unsupported rule type")
|
|
143
|
-
if issues.has_errors:
|
|
144
|
-
# This is up for discussion, but I think we should not return rules that
|
|
145
|
-
# only pass the verification but not the validation.
|
|
146
|
-
output.rules = None
|
|
147
|
-
output.issues.extend(issues)
|
|
148
|
-
|
|
149
|
-
end = datetime.now(timezone.utc)
|
|
150
|
-
|
|
151
|
-
if output.rules:
|
|
152
|
-
change = Change.from_rules_activity(
|
|
153
|
-
output.rules,
|
|
154
|
-
transformer.agent,
|
|
155
|
-
start,
|
|
156
|
-
end,
|
|
157
|
-
f"Verified data model {source_id} as {output.rules.metadata.identifier}",
|
|
158
|
-
self._state.data_model.provenance.source_entity(source_id)
|
|
159
|
-
or self._state.data_model.provenance.target_entity(source_id),
|
|
160
|
-
)
|
|
161
|
-
|
|
162
|
-
self._state.data_model.write(output.rules, change)
|
|
163
|
-
|
|
164
|
-
if isinstance(output.rules, InformationRules):
|
|
165
|
-
self._state.instances.store.add_rules(output.rules)
|
|
166
|
-
|
|
167
|
-
output.issues.action = "verify"
|
|
168
|
-
self._state.data_model.issue_lists.append(output.issues)
|
|
169
|
-
if output.issues:
|
|
122
|
+
transformer = VerifyAnyRules(validate=True, client=self._client) # type: ignore[var-annotated]
|
|
123
|
+
issues = self._state.rule_transform(transformer)
|
|
124
|
+
if not issues.has_errors:
|
|
125
|
+
rules = self._state.rule_store.last_verified_rule
|
|
126
|
+
if isinstance(rules, InformationRules):
|
|
127
|
+
self._state.instances.store.add_rules(rules)
|
|
128
|
+
|
|
129
|
+
if issues:
|
|
170
130
|
print("You can inspect the issues with the .inspect.issues(...) method.")
|
|
171
|
-
return
|
|
131
|
+
return issues
|
|
172
132
|
|
|
173
133
|
def convert(
|
|
174
134
|
self, target: Literal["dms", "information"], mode: Literal["edge_properties"] | None = None
|
|
@@ -192,43 +152,17 @@ class NeatSession:
|
|
|
192
152
|
neat.convert(target="information")
|
|
193
153
|
```
|
|
194
154
|
"""
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
converter = ConvertToRules(InformationRules)
|
|
207
|
-
converted_rules = converter.transform(dms_rules).rules
|
|
208
|
-
else:
|
|
209
|
-
# Session errors are not caught by the catch_issues context manager
|
|
210
|
-
raise NeatSessionError(f"Target {target} not supported.")
|
|
211
|
-
|
|
212
|
-
end = datetime.now(timezone.utc)
|
|
213
|
-
if issues:
|
|
214
|
-
self._state.data_model.issue_lists.append(issues)
|
|
215
|
-
|
|
216
|
-
if converted_rules is not None and converter is not None:
|
|
217
|
-
# Provenance
|
|
218
|
-
change = Change.from_rules_activity(
|
|
219
|
-
converted_rules,
|
|
220
|
-
converter.agent,
|
|
221
|
-
start,
|
|
222
|
-
end,
|
|
223
|
-
f"Converted data model {source_id} to {converted_rules.metadata.identifier}",
|
|
224
|
-
self._state.data_model.provenance.source_entity(source_id)
|
|
225
|
-
or self._state.data_model.provenance.target_entity(source_id),
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
self._state.data_model.write(converted_rules, change)
|
|
229
|
-
|
|
230
|
-
if self._verbose and not issues.has_errors:
|
|
231
|
-
print(f"Rules converted to {target}")
|
|
155
|
+
converter: ConversionTransformer
|
|
156
|
+
if target == "dms":
|
|
157
|
+
converter = InformationToDMS(mode=mode)
|
|
158
|
+
elif target == "information":
|
|
159
|
+
converter = ConvertToRules(InformationRules)
|
|
160
|
+
else:
|
|
161
|
+
raise NeatSessionError(f"Target {target} not supported.")
|
|
162
|
+
issues = self._state.rule_transform(converter)
|
|
163
|
+
|
|
164
|
+
if self._verbose and not issues.has_errors:
|
|
165
|
+
print(f"Rules converted to {target}")
|
|
232
166
|
else:
|
|
233
167
|
print("Conversion failed.")
|
|
234
168
|
if issues:
|
|
@@ -263,53 +197,30 @@ class NeatSession:
|
|
|
263
197
|
```
|
|
264
198
|
"""
|
|
265
199
|
model_id = dm.DataModelId.load(model_id)
|
|
266
|
-
|
|
267
|
-
start = datetime.now(timezone.utc)
|
|
268
200
|
importer = importers.InferenceImporter.from_graph_store(
|
|
269
201
|
store=self._state.instances.store,
|
|
270
202
|
max_number_of_instance=max_number_of_instance,
|
|
203
|
+
data_model_id=model_id,
|
|
271
204
|
)
|
|
272
|
-
|
|
273
|
-
end = datetime.now(timezone.utc)
|
|
274
|
-
|
|
275
|
-
if model_id.space:
|
|
276
|
-
cast(InformationInputRules, inferred_rules.rules).metadata.space = model_id.space
|
|
277
|
-
if model_id.external_id:
|
|
278
|
-
cast(InformationInputRules, inferred_rules.rules).metadata.external_id = model_id.external_id
|
|
279
|
-
|
|
280
|
-
if model_id.version:
|
|
281
|
-
cast(InformationInputRules, inferred_rules.rules).metadata.version = model_id.version
|
|
282
|
-
|
|
283
|
-
# Provenance
|
|
284
|
-
change = Change.from_rules_activity(
|
|
285
|
-
inferred_rules,
|
|
286
|
-
importer.agent,
|
|
287
|
-
start,
|
|
288
|
-
end,
|
|
289
|
-
"Inferred data model",
|
|
290
|
-
INSTANCES_ENTITY,
|
|
291
|
-
)
|
|
292
|
-
|
|
293
|
-
self._state.data_model.write(inferred_rules, change)
|
|
294
|
-
return inferred_rules.issues
|
|
205
|
+
return self._state.rule_import(importer)
|
|
295
206
|
|
|
296
207
|
def _repr_html_(self) -> str:
|
|
297
208
|
state = self._state
|
|
298
209
|
if (
|
|
299
210
|
not state.instances.has_store
|
|
300
|
-
and not state.
|
|
301
|
-
and not state.
|
|
211
|
+
and not state.rule_store.has_unverified_rules
|
|
212
|
+
and not state.rule_store.has_verified_rules
|
|
302
213
|
):
|
|
303
214
|
return "<strong>Empty session</strong>. Get started by reading something with the <em>.read</em> attribute."
|
|
304
215
|
|
|
305
216
|
output = []
|
|
306
217
|
|
|
307
|
-
if state.
|
|
308
|
-
rules:
|
|
309
|
-
output.append(f"<H2>Unverified Data Model</H2><br />{rules.
|
|
218
|
+
if state.rule_store.has_unverified_rules and not state.rule_store.has_verified_rules:
|
|
219
|
+
rules: InputRules = state.rule_store.last_unverified_rule
|
|
220
|
+
output.append(f"<H2>Unverified Data Model</H2><br />{rules._repr_html_()}") # type: ignore
|
|
310
221
|
|
|
311
|
-
if state.
|
|
312
|
-
output.append(f"<H2>Verified Data Model</H2><br />{state.
|
|
222
|
+
if state.rule_store.has_verified_rules:
|
|
223
|
+
output.append(f"<H2>Verified Data Model</H2><br />{state.rule_store.last_verified_rule._repr_html_()}") # type: ignore
|
|
313
224
|
|
|
314
225
|
if state.instances.has_store:
|
|
315
226
|
output.append(f"<H2>Instances</H2> {state.instances.store._repr_html_()}")
|
|
@@ -59,7 +59,7 @@ class InspectAPI:
|
|
|
59
59
|
neat.inspect.properties
|
|
60
60
|
```
|
|
61
61
|
"""
|
|
62
|
-
return self._state.
|
|
62
|
+
return self._state.rule_store.last_verified_rule.properties.to_pandas()
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
@session_class_wrapper
|
|
@@ -89,7 +89,7 @@ class InspectIssues:
|
|
|
89
89
|
return_dataframe: bool = (False if IN_NOTEBOOK else True), # type: ignore[assignment]
|
|
90
90
|
) -> pd.DataFrame | None:
|
|
91
91
|
"""Returns the issues of the current data model."""
|
|
92
|
-
issues = self._state.
|
|
92
|
+
issues = self._state.rule_store.last_issues
|
|
93
93
|
if not issues:
|
|
94
94
|
self._print("No issues found.")
|
|
95
95
|
|
|
@@ -141,7 +141,7 @@ class InspectOutcome:
|
|
|
141
141
|
"""
|
|
142
142
|
|
|
143
143
|
def __init__(self, state: SessionState) -> None:
|
|
144
|
-
self.data_model = InspectUploadOutcome(lambda: state.
|
|
144
|
+
self.data_model = InspectUploadOutcome(lambda: state.rule_store.last_outcome)
|
|
145
145
|
self.instances = InspectUploadOutcome(lambda: state.instances.last_outcome)
|
|
146
146
|
|
|
147
147
|
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
from datetime import datetime, timezone
|
|
2
|
-
|
|
3
1
|
from cognite.neat._client import NeatClient
|
|
4
|
-
from cognite.neat.
|
|
5
|
-
from cognite.neat._rules.
|
|
6
|
-
from cognite.neat._rules.models.dms import DMSValidation
|
|
2
|
+
from cognite.neat._issues import IssueList
|
|
3
|
+
from cognite.neat._rules.models import DMSRules
|
|
7
4
|
from cognite.neat._rules.models.mapping import load_classic_to_core_mapping
|
|
8
|
-
from cognite.neat._rules.transformers import AsParentPropertyId,
|
|
9
|
-
from cognite.neat._store._provenance import Agent as ProvenanceAgent
|
|
10
|
-
from cognite.neat._store._provenance import Change
|
|
5
|
+
from cognite.neat._rules.transformers import AsParentPropertyId, IncludeReferenced, RuleMapper
|
|
11
6
|
|
|
12
7
|
from ._state import SessionState
|
|
13
8
|
from .exceptions import NeatSessionError, session_class_wrapper
|
|
@@ -25,7 +20,7 @@ class DataModelMappingAPI:
|
|
|
25
20
|
self._state = state
|
|
26
21
|
self._client = client
|
|
27
22
|
|
|
28
|
-
def classic_to_core(self, company_prefix: str, use_parent_property_name: bool = True) ->
|
|
23
|
+
def classic_to_core(self, company_prefix: str, use_parent_property_name: bool = True) -> IssueList:
|
|
29
24
|
"""Map classic types to core types.
|
|
30
25
|
|
|
31
26
|
Note this automatically creates an extended CogniteCore model.
|
|
@@ -44,101 +39,18 @@ class DataModelMappingAPI:
|
|
|
44
39
|
neat.mapping.classic_to_core(company_prefix="WindFarmX", use_parent_property_name=True)
|
|
45
40
|
```
|
|
46
41
|
"""
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
load_classic_to_core_mapping(company_prefix, rules.metadata.space, rules.metadata.version)
|
|
52
|
-
)
|
|
53
|
-
output = transformer.transform(rules)
|
|
54
|
-
end = datetime.now(timezone.utc)
|
|
55
|
-
|
|
56
|
-
change = Change.from_rules_activity(
|
|
57
|
-
output,
|
|
58
|
-
transformer.agent,
|
|
59
|
-
start,
|
|
60
|
-
end,
|
|
61
|
-
"Mapping classic to core",
|
|
62
|
-
self._state.data_model.provenance.source_entity(source_id)
|
|
63
|
-
or self._state.data_model.provenance.target_entity(source_id),
|
|
64
|
-
)
|
|
42
|
+
rules = self._state.rule_store.get_last_successful_entity().result
|
|
43
|
+
if not isinstance(rules, DMSRules):
|
|
44
|
+
# Todo better hint of what you should do.
|
|
45
|
+
raise NeatSessionError(f"Expected DMSRules, got {type(rules)}")
|
|
65
46
|
|
|
66
|
-
self._state.data_model.write(output.rules, change)
|
|
67
|
-
|
|
68
|
-
start = datetime.now(timezone.utc)
|
|
69
|
-
|
|
70
|
-
source_id, rules = self._state.data_model.last_verified_dms_rules
|
|
71
|
-
view_ids, container_ids = DMSValidation(rules, self._client).imported_views_and_containers_ids()
|
|
72
|
-
if not (view_ids or container_ids):
|
|
73
|
-
print(
|
|
74
|
-
f"Data model {rules.metadata.as_data_model_id()} does not have any referenced views or containers."
|
|
75
|
-
f"that is not already included in the data model."
|
|
76
|
-
)
|
|
77
|
-
return
|
|
78
47
|
if self._client is None:
|
|
79
|
-
raise NeatSessionError(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
imported = importer.to_rules()
|
|
89
|
-
if imported.rules is None:
|
|
90
|
-
self._state.data_model.issue_lists.append(imported.issues)
|
|
91
|
-
raise NeatSessionError(
|
|
92
|
-
"Could not import the referenced views and containers. "
|
|
93
|
-
"See `neat.inspect.issues()` for more information."
|
|
94
|
-
)
|
|
95
|
-
verified = VerifyDMSRules("continue", validate=False).transform(imported.rules)
|
|
96
|
-
if verified.rules is None:
|
|
97
|
-
self._state.data_model.issue_lists.append(verified.issues)
|
|
98
|
-
raise NeatSessionError(
|
|
99
|
-
"Could not verify the referenced views and containers. "
|
|
100
|
-
"See `neat.inspect.issues()` for more information."
|
|
101
|
-
)
|
|
102
|
-
if copy_.containers is None:
|
|
103
|
-
copy_.containers = verified.rules.containers
|
|
104
|
-
else:
|
|
105
|
-
existing_containers = {c.container for c in copy_.containers}
|
|
106
|
-
copy_.containers.extend(
|
|
107
|
-
[c for c in verified.rules.containers or [] if c.container not in existing_containers]
|
|
108
|
-
)
|
|
109
|
-
existing_views = {v.view for v in copy_.views}
|
|
110
|
-
copy_.views.extend([v for v in verified.rules.views if v.view not in existing_views])
|
|
111
|
-
end = datetime.now(timezone.utc)
|
|
112
|
-
|
|
113
|
-
change = Change.from_rules_activity(
|
|
114
|
-
copy_,
|
|
115
|
-
ProvenanceAgent(id_=DEFAULT_NAMESPACE["agent/"]),
|
|
116
|
-
start,
|
|
117
|
-
end,
|
|
118
|
-
(f"Included referenced views and containers in the data model {rules.metadata.as_data_model_id()}"),
|
|
119
|
-
self._state.data_model.provenance.source_entity(source_id)
|
|
120
|
-
or self._state.data_model.provenance.target_entity(source_id),
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
self._state.data_model.write(copy_, change)
|
|
124
|
-
|
|
125
|
-
if not use_parent_property_name:
|
|
126
|
-
return
|
|
127
|
-
|
|
128
|
-
source_id, rules = self._state.data_model.last_verified_dms_rules
|
|
129
|
-
start = datetime.now(timezone.utc)
|
|
130
|
-
transformer = AsParentPropertyId(self._client)
|
|
131
|
-
output = transformer.transform(rules)
|
|
132
|
-
end = datetime.now(timezone.utc)
|
|
133
|
-
|
|
134
|
-
change = Change.from_rules_activity(
|
|
135
|
-
output,
|
|
136
|
-
transformer.agent,
|
|
137
|
-
start,
|
|
138
|
-
end,
|
|
139
|
-
"Renaming property names to parent name",
|
|
140
|
-
self._state.data_model.provenance.source_entity(source_id)
|
|
141
|
-
or self._state.data_model.provenance.target_entity(source_id),
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
self._state.data_model.write(output.rules, change)
|
|
48
|
+
raise NeatSessionError("Client is required to map classic to core")
|
|
49
|
+
|
|
50
|
+
transformers = [
|
|
51
|
+
RuleMapper(load_classic_to_core_mapping(company_prefix, rules.metadata.space, rules.metadata.version)),
|
|
52
|
+
IncludeReferenced(self._client),
|
|
53
|
+
]
|
|
54
|
+
if use_parent_property_name:
|
|
55
|
+
transformers.append(AsParentPropertyId(self._client))
|
|
56
|
+
return self._state.rule_transform(*transformers)
|