cognite-neat 0.121.2__py3-none-any.whl → 0.122.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/_version.py +1 -1
- cognite/neat/core/_constants.py +1 -1
- cognite/neat/core/_data_model/catalog/__init__.py +1 -1
- cognite/neat/core/_data_model/exporters/__init__.py +1 -1
- cognite/neat/core/_data_model/exporters/_data_model2instance_template.py +11 -11
- cognite/neat/core/_data_model/importers/__init__.py +2 -2
- cognite/neat/core/_data_model/importers/_dict2data_model.py +11 -6
- cognite/neat/core/_data_model/importers/_rdf/__init__.py +3 -3
- cognite/neat/core/_data_model/importers/_rdf/_base.py +8 -8
- cognite/neat/core/_data_model/importers/_rdf/{_imf2rules.py → _imf2data_model.py} +2 -2
- cognite/neat/core/_data_model/importers/_rdf/{_inference2rules.py → _inference2rdata_model.py} +26 -26
- cognite/neat/core/_data_model/importers/_rdf/{_owl2rules.py → _owl2data_model.py} +5 -5
- cognite/neat/core/_data_model/importers/_spreadsheet2data_model.py +6 -9
- cognite/neat/core/_data_model/models/__init__.py +5 -3
- cognite/neat/core/_data_model/models/_base_unverified.py +12 -12
- cognite/neat/core/_data_model/models/_base_verified.py +6 -11
- cognite/neat/core/_data_model/models/conceptual/_validation.py +1 -1
- cognite/neat/core/_data_model/models/conceptual/_verified.py +2 -2
- cognite/neat/core/_data_model/models/mapping/_classic2core.py +1 -1
- cognite/neat/core/_data_model/models/physical/_exporter.py +4 -3
- cognite/neat/core/_data_model/models/physical/_validation.py +5 -5
- cognite/neat/core/_data_model/transformers/__init__.py +2 -2
- cognite/neat/core/_data_model/transformers/_base.py +1 -1
- cognite/neat/core/_data_model/transformers/_converters.py +9 -9
- cognite/neat/core/_data_model/transformers/_verification.py +1 -1
- cognite/neat/core/_instances/extractors/_base.py +1 -1
- cognite/neat/core/_instances/extractors/_classic_cdf/_classic.py +1 -1
- cognite/neat/core/_instances/extractors/_mock_graph_generator.py +14 -13
- cognite/neat/core/_instances/loaders/_base.py +2 -2
- cognite/neat/core/_instances/loaders/_rdf2dms.py +26 -20
- cognite/neat/core/_instances/transformers/_rdfpath.py +1 -1
- cognite/neat/core/_issues/_factory.py +1 -1
- cognite/neat/core/_issues/errors/_resources.py +1 -1
- cognite/neat/core/_issues/warnings/_properties.py +1 -1
- cognite/neat/session/_base.py +26 -22
- cognite/neat/session/_drop.py +2 -2
- cognite/neat/session/_experimental.py +1 -1
- cognite/neat/session/_inspect.py +8 -8
- cognite/neat/session/_mapping.py +9 -5
- cognite/neat/session/_read.py +38 -36
- cognite/neat/session/_set.py +5 -5
- cognite/neat/session/_show.py +15 -12
- cognite/neat/session/_state/README.md +1 -1
- cognite/neat/session/_state.py +18 -18
- cognite/neat/session/_subset.py +6 -6
- cognite/neat/session/_template.py +13 -11
- cognite/neat/session/_to.py +35 -35
- cognite/neat/session/exceptions.py +5 -2
- {cognite_neat-0.121.2.dist-info → cognite_neat-0.122.1.dist-info}/METADATA +17 -10
- {cognite_neat-0.121.2.dist-info → cognite_neat-0.122.1.dist-info}/RECORD +52 -52
- {cognite_neat-0.121.2.dist-info → cognite_neat-0.122.1.dist-info}/WHEEL +0 -0
- {cognite_neat-0.121.2.dist-info → cognite_neat-0.122.1.dist-info}/licenses/LICENSE +0 -0
cognite/neat/session/_read.py
CHANGED
|
@@ -15,7 +15,7 @@ from cognite.neat.core._data_model.models.entities._single_value import ViewEnti
|
|
|
15
15
|
from cognite.neat.core._data_model.transformers import ClassicPrepareCore
|
|
16
16
|
from cognite.neat.core._data_model.transformers._converters import (
|
|
17
17
|
ToEnterpriseModel,
|
|
18
|
-
|
|
18
|
+
_SubsetEditableCDMPhysicalDataModel,
|
|
19
19
|
)
|
|
20
20
|
from cognite.neat.core._instances import examples as instances_examples
|
|
21
21
|
from cognite.neat.core._instances import extractors
|
|
@@ -113,7 +113,7 @@ class CDFReadAPI(BaseReadAPI):
|
|
|
113
113
|
|
|
114
114
|
self._state._raise_exception_if_condition_not_met(
|
|
115
115
|
"Read data model from CDF",
|
|
116
|
-
|
|
116
|
+
empty_data_model_store_required=True,
|
|
117
117
|
client_required=True,
|
|
118
118
|
)
|
|
119
119
|
|
|
@@ -148,7 +148,7 @@ class CDFReadAPI(BaseReadAPI):
|
|
|
148
148
|
|
|
149
149
|
self._state._raise_exception_if_condition_not_met(
|
|
150
150
|
"Subset Core Data Model",
|
|
151
|
-
|
|
151
|
+
empty_data_model_store_required=True,
|
|
152
152
|
client_required=True,
|
|
153
153
|
)
|
|
154
154
|
|
|
@@ -164,7 +164,7 @@ class CDFReadAPI(BaseReadAPI):
|
|
|
164
164
|
if issues.has_errors:
|
|
165
165
|
return issues
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
cdm_data_model = self._state.data_model_store.last_verified_data_model
|
|
168
168
|
|
|
169
169
|
issues.extend(
|
|
170
170
|
self._state.rule_transform(
|
|
@@ -182,7 +182,7 @@ class CDFReadAPI(BaseReadAPI):
|
|
|
182
182
|
|
|
183
183
|
issues.extend(
|
|
184
184
|
self._state.rule_transform(
|
|
185
|
-
|
|
185
|
+
_SubsetEditableCDMPhysicalDataModel(
|
|
186
186
|
views={
|
|
187
187
|
ViewEntity(
|
|
188
188
|
space=cdm_v1.space,
|
|
@@ -195,8 +195,8 @@ class CDFReadAPI(BaseReadAPI):
|
|
|
195
195
|
)
|
|
196
196
|
)
|
|
197
197
|
|
|
198
|
-
if
|
|
199
|
-
self._state.last_reference =
|
|
198
|
+
if cdm_data_model and not issues.has_errors:
|
|
199
|
+
self._state.last_reference = cdm_data_model
|
|
200
200
|
|
|
201
201
|
return issues
|
|
202
202
|
|
|
@@ -220,7 +220,7 @@ class CDFReadAPI(BaseReadAPI):
|
|
|
220
220
|
"""
|
|
221
221
|
self._state._raise_exception_if_condition_not_met(
|
|
222
222
|
"Read DMS Graph",
|
|
223
|
-
|
|
223
|
+
empty_data_model_store_required=True,
|
|
224
224
|
empty_instances_store_required=True,
|
|
225
225
|
client_required=True,
|
|
226
226
|
)
|
|
@@ -350,7 +350,7 @@ class CDFClassicAPI(BaseReadAPI):
|
|
|
350
350
|
"""
|
|
351
351
|
self._state._raise_exception_if_condition_not_met(
|
|
352
352
|
"Read classic graph",
|
|
353
|
-
|
|
353
|
+
empty_data_model_store_required=True,
|
|
354
354
|
empty_instances_store_required=True,
|
|
355
355
|
client_required=True,
|
|
356
356
|
)
|
|
@@ -399,7 +399,7 @@ class CDFClassicAPI(BaseReadAPI):
|
|
|
399
399
|
# The above transformations creates a new type, so we need to update
|
|
400
400
|
self._state.instances.neat_prefix_by_type_uri.update({namespace["ClassicSourceSystem"]: "ClassicSourceSystem_"})
|
|
401
401
|
# Updating the information model.
|
|
402
|
-
prepare_issues = self._state.
|
|
402
|
+
prepare_issues = self._state.data_model_store.transform(
|
|
403
403
|
ClassicPrepareCore(namespace, reference_timeseries, reference_files)
|
|
404
404
|
)
|
|
405
405
|
|
|
@@ -432,7 +432,7 @@ class CDFClassicAPI(BaseReadAPI):
|
|
|
432
432
|
namespace = CLASSIC_CDF_NAMESPACE
|
|
433
433
|
self._state._raise_exception_if_condition_not_met(
|
|
434
434
|
"Read time series",
|
|
435
|
-
|
|
435
|
+
empty_data_model_store_required=True,
|
|
436
436
|
empty_instances_store_required=True,
|
|
437
437
|
client_required=True,
|
|
438
438
|
)
|
|
@@ -491,7 +491,7 @@ class CDFClassicAPI(BaseReadAPI):
|
|
|
491
491
|
namespace = CLASSIC_CDF_NAMESPACE
|
|
492
492
|
self._state._raise_exception_if_condition_not_met(
|
|
493
493
|
"Read time series",
|
|
494
|
-
|
|
494
|
+
empty_data_model_store_required=True,
|
|
495
495
|
empty_instances_store_required=True,
|
|
496
496
|
client_required=True,
|
|
497
497
|
)
|
|
@@ -528,15 +528,15 @@ class CDFClassicAPI(BaseReadAPI):
|
|
|
528
528
|
|
|
529
529
|
@session_class_wrapper
|
|
530
530
|
class ExcelReadAPI(BaseReadAPI):
|
|
531
|
-
"""Reads a Neat Excel
|
|
532
|
-
or
|
|
531
|
+
"""Reads a Neat Excel Data Model to the data model store.
|
|
532
|
+
The data model spreadsheets may contain conceptual or physical data model definitions.
|
|
533
533
|
|
|
534
534
|
Args:
|
|
535
535
|
io: file path to the Excel sheet
|
|
536
536
|
|
|
537
537
|
Example:
|
|
538
538
|
```python
|
|
539
|
-
neat.read.excel("
|
|
539
|
+
neat.read.excel("conceptual_or_physical_data_model.xlsx")
|
|
540
540
|
```
|
|
541
541
|
"""
|
|
542
542
|
|
|
@@ -544,27 +544,28 @@ class ExcelReadAPI(BaseReadAPI):
|
|
|
544
544
|
super().__init__(state, verbose)
|
|
545
545
|
|
|
546
546
|
def __call__(self, io: Any, enable_manual_edit: bool = False) -> IssueList:
|
|
547
|
-
"""Reads a Neat Excel
|
|
548
|
-
or
|
|
547
|
+
"""Reads a Neat Excel Data Model to the data model store.
|
|
548
|
+
The data model spreadsheets may contain conceptual or physical data model definitions.
|
|
549
549
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
550
|
+
Args:
|
|
551
|
+
io: file path to the Excel sheet
|
|
552
|
+
enable_manual_edit: If True, the user will be able to re-import data model
|
|
553
|
+
which where edit outside NeatSession
|
|
553
554
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
555
|
+
!!! note "Manual Edit Warning"
|
|
556
|
+
This is an alpha feature and is subject to change without notice.
|
|
557
|
+
It is expected to have some limitations and may not work as expected in all cases.
|
|
557
558
|
"""
|
|
558
559
|
reader = NeatReader.create(io)
|
|
559
560
|
path = reader.materialize_path()
|
|
560
561
|
|
|
561
562
|
if enable_manual_edit:
|
|
562
563
|
warnings.filterwarnings("default")
|
|
563
|
-
ExperimentalFlags.
|
|
564
|
+
ExperimentalFlags.manual_data_model_edit.warn()
|
|
564
565
|
else:
|
|
565
566
|
self._state._raise_exception_if_condition_not_met(
|
|
566
|
-
"Read Excel
|
|
567
|
-
|
|
567
|
+
"Read Excel Data Model",
|
|
568
|
+
empty_data_model_store_required=True,
|
|
568
569
|
)
|
|
569
570
|
|
|
570
571
|
return self._state.rule_import(importers.ExcelImporter(path), enable_manual_edit)
|
|
@@ -573,7 +574,8 @@ class ExcelReadAPI(BaseReadAPI):
|
|
|
573
574
|
@session_class_wrapper
|
|
574
575
|
class YamlReadAPI(BaseReadAPI):
|
|
575
576
|
def __call__(self, io: Any, format: Literal["neat", "toolkit"] = "neat") -> IssueList:
|
|
576
|
-
"""Reads a yaml with either neat
|
|
577
|
+
"""Reads a yaml with either neat data mode, or several toolkit yaml files to
|
|
578
|
+
import Data Model(s) into NeatSession.
|
|
577
579
|
|
|
578
580
|
Args:
|
|
579
581
|
io: File path to the Yaml file in the case of "neat" yaml, or path to a zip folder or directory with several
|
|
@@ -587,7 +589,7 @@ class YamlReadAPI(BaseReadAPI):
|
|
|
587
589
|
"""
|
|
588
590
|
self._state._raise_exception_if_condition_not_met(
|
|
589
591
|
"Read YAML data model",
|
|
590
|
-
|
|
592
|
+
empty_data_model_store_required=True,
|
|
591
593
|
)
|
|
592
594
|
reader = NeatReader.create(io)
|
|
593
595
|
path = reader.materialize_path()
|
|
@@ -695,7 +697,7 @@ class XMLReadAPI(BaseReadAPI):
|
|
|
695
697
|
|
|
696
698
|
self._state._raise_exception_if_condition_not_met(
|
|
697
699
|
"Read DEXPI file",
|
|
698
|
-
|
|
700
|
+
empty_data_model_store_required=True,
|
|
699
701
|
empty_instances_store_required=True,
|
|
700
702
|
)
|
|
701
703
|
|
|
@@ -757,7 +759,7 @@ class XMLReadAPI(BaseReadAPI):
|
|
|
757
759
|
|
|
758
760
|
self._state._raise_exception_if_condition_not_met(
|
|
759
761
|
"Read AML file",
|
|
760
|
-
|
|
762
|
+
empty_data_model_store_required=True,
|
|
761
763
|
empty_instances_store_required=True,
|
|
762
764
|
)
|
|
763
765
|
|
|
@@ -817,7 +819,7 @@ class RDFReadAPI(BaseReadAPI):
|
|
|
817
819
|
|
|
818
820
|
self._state._raise_exception_if_condition_not_met(
|
|
819
821
|
"Read Ontology file",
|
|
820
|
-
|
|
822
|
+
empty_data_model_store_required=True,
|
|
821
823
|
)
|
|
822
824
|
|
|
823
825
|
reader = NeatReader.create(io)
|
|
@@ -840,7 +842,7 @@ class RDFReadAPI(BaseReadAPI):
|
|
|
840
842
|
|
|
841
843
|
self._state._raise_exception_if_condition_not_met(
|
|
842
844
|
"Read IMF file",
|
|
843
|
-
|
|
845
|
+
empty_data_model_store_required=True,
|
|
844
846
|
)
|
|
845
847
|
|
|
846
848
|
reader = NeatReader.create(io)
|
|
@@ -850,7 +852,7 @@ class RDFReadAPI(BaseReadAPI):
|
|
|
850
852
|
def instances(self, io: Any) -> IssueList:
|
|
851
853
|
self._state._raise_exception_if_condition_not_met(
|
|
852
854
|
"Read RDF Instances",
|
|
853
|
-
|
|
855
|
+
empty_data_model_store_required=True,
|
|
854
856
|
)
|
|
855
857
|
reader = NeatReader.create(io)
|
|
856
858
|
self._state.instances.store.write(extractors.RdfFileExtractor(reader.materialize_path()))
|
|
@@ -898,7 +900,7 @@ class Examples:
|
|
|
898
900
|
self._state._raise_exception_if_condition_not_met(
|
|
899
901
|
"Read Nordic44 graph example",
|
|
900
902
|
empty_instances_store_required=True,
|
|
901
|
-
|
|
903
|
+
empty_data_model_store_required=True,
|
|
902
904
|
)
|
|
903
905
|
|
|
904
906
|
self._state.instances.store.write(extractors.RdfFileExtractor(instances_examples.nordic44_knowledge_graph))
|
|
@@ -909,7 +911,7 @@ class Examples:
|
|
|
909
911
|
|
|
910
912
|
self._state._raise_exception_if_condition_not_met(
|
|
911
913
|
"Read Pump Data Model example",
|
|
912
|
-
|
|
914
|
+
empty_data_model_store_required=True,
|
|
913
915
|
)
|
|
914
916
|
|
|
915
917
|
importer: importers.ExcelImporter = importers.ExcelImporter(catalog.hello_world_pump)
|
|
@@ -920,7 +922,7 @@ class Examples:
|
|
|
920
922
|
|
|
921
923
|
self._state._raise_exception_if_condition_not_met(
|
|
922
924
|
"Read Core Data Model example",
|
|
923
|
-
|
|
925
|
+
empty_data_model_store_required=True,
|
|
924
926
|
client_required=True,
|
|
925
927
|
)
|
|
926
928
|
|
cognite/neat/session/_set.py
CHANGED
|
@@ -39,11 +39,11 @@ class SetAPI:
|
|
|
39
39
|
neat.set.data_model_id(("my_data_model_space", "MyDataModel", "v1"), name="My Data Model")
|
|
40
40
|
```
|
|
41
41
|
"""
|
|
42
|
-
if self._state.
|
|
43
|
-
raise NeatSessionError("No
|
|
44
|
-
|
|
45
|
-
if isinstance(
|
|
46
|
-
if
|
|
42
|
+
if self._state.data_model_store.empty:
|
|
43
|
+
raise NeatSessionError("No data model to set the data model ID.")
|
|
44
|
+
data_model = self._state.data_model_store.provenance[-1].target_entity.physical
|
|
45
|
+
if isinstance(data_model, PhysicalDataModel):
|
|
46
|
+
if data_model.metadata.as_data_model_id() in COGNITE_MODELS:
|
|
47
47
|
raise NeatSessionError(
|
|
48
48
|
"Cannot change the data model ID of a Cognite Data Model in NeatSession"
|
|
49
49
|
" due to temporarily issue with the reverse direct relation interpretation"
|
cognite/neat/session/_show.py
CHANGED
|
@@ -95,11 +95,11 @@ class ShowDataModelAPI(ShowBaseAPI):
|
|
|
95
95
|
self.implements = ShowDataModelImplementsAPI(self._state)
|
|
96
96
|
|
|
97
97
|
def __call__(self) -> Any:
|
|
98
|
-
if self._state.
|
|
98
|
+
if self._state.data_model_store.empty:
|
|
99
99
|
raise NeatSessionError("No data model available. Try using [bold].read[/bold] to read a data model.")
|
|
100
100
|
|
|
101
|
-
last_target = self._state.
|
|
102
|
-
|
|
101
|
+
last_target = self._state.data_model_store.provenance[-1].target_entity
|
|
102
|
+
data_model = last_target.physical or last_target.conceptual
|
|
103
103
|
analysis = DataModelAnalysis(physical=last_target.physical, conceptual=last_target.conceptual)
|
|
104
104
|
|
|
105
105
|
if last_target.physical is not None:
|
|
@@ -107,7 +107,7 @@ class ShowDataModelAPI(ShowBaseAPI):
|
|
|
107
107
|
else:
|
|
108
108
|
di_graph = analysis._conceptual_di_graph(format="data-model")
|
|
109
109
|
|
|
110
|
-
identifier = to_directory_compatible(str(
|
|
110
|
+
identifier = to_directory_compatible(str(data_model.metadata.identifier))
|
|
111
111
|
name = f"{identifier}.html"
|
|
112
112
|
return self._generate_visualization(di_graph, name)
|
|
113
113
|
|
|
@@ -119,18 +119,18 @@ class ShowDataModelImplementsAPI(ShowBaseAPI):
|
|
|
119
119
|
self._state = state
|
|
120
120
|
|
|
121
121
|
def __call__(self) -> Any:
|
|
122
|
-
if self._state.
|
|
122
|
+
if self._state.data_model_store.empty:
|
|
123
123
|
raise NeatSessionError("No data model available. Try using [bold].read[/bold] to read a data model.")
|
|
124
124
|
|
|
125
|
-
last_target = self._state.
|
|
126
|
-
|
|
125
|
+
last_target = self._state.data_model_store.provenance[-1].target_entity
|
|
126
|
+
data_model = last_target.physical or last_target.conceptual
|
|
127
127
|
analysis = DataModelAnalysis(physical=last_target.physical, conceptual=last_target.conceptual)
|
|
128
128
|
|
|
129
129
|
if last_target.physical is not None:
|
|
130
130
|
di_graph = analysis._physical_di_graph(format="implements")
|
|
131
131
|
else:
|
|
132
132
|
di_graph = analysis._conceptual_di_graph(format="implements")
|
|
133
|
-
identifier = to_directory_compatible(str(
|
|
133
|
+
identifier = to_directory_compatible(str(data_model.metadata.identifier))
|
|
134
134
|
name = f"{identifier}_implements.html"
|
|
135
135
|
return self._generate_visualization(di_graph, name)
|
|
136
136
|
|
|
@@ -144,18 +144,18 @@ class ShowDataModelProvenanceAPI(ShowBaseAPI):
|
|
|
144
144
|
self._state = state
|
|
145
145
|
|
|
146
146
|
def __call__(self) -> Any:
|
|
147
|
-
if not self._state.
|
|
147
|
+
if not self._state.data_model_store.provenance:
|
|
148
148
|
raise NeatSessionError("No data model available. Try using [bold].read[/bold] to load data model.")
|
|
149
149
|
|
|
150
150
|
di_graph = self._generate_dm_provenance_di_graph_and_types()
|
|
151
|
-
unique_hash = self._state.
|
|
151
|
+
unique_hash = self._state.data_model_store.calculate_provenance_hash(shorten=True)
|
|
152
152
|
return self._generate_visualization(di_graph, name=f"data_model_provenance_{unique_hash}.html")
|
|
153
153
|
|
|
154
154
|
def _generate_dm_provenance_di_graph_and_types(self) -> nx.DiGraph:
|
|
155
155
|
di_graph = nx.DiGraph()
|
|
156
156
|
hex_colored_types = _generate_hex_color_per_type(["Agent", "Entity", "Activity", "Export", "Pruned"])
|
|
157
157
|
|
|
158
|
-
for change in self._state.
|
|
158
|
+
for change in self._state.data_model_store.provenance:
|
|
159
159
|
source = uri_display_name(change.source_entity.id_)
|
|
160
160
|
target = uri_display_name(change.target_entity.id_)
|
|
161
161
|
agent = uri_display_name(change.agent.id_)
|
|
@@ -187,7 +187,10 @@ class ShowDataModelProvenanceAPI(ShowBaseAPI):
|
|
|
187
187
|
di_graph.add_edge(source, agent, label="used", color="grey")
|
|
188
188
|
di_graph.add_edge(agent, target, label="generated", color="grey")
|
|
189
189
|
|
|
190
|
-
for
|
|
190
|
+
for (
|
|
191
|
+
source_id,
|
|
192
|
+
exports,
|
|
193
|
+
) in self._state.data_model_store.exports_by_source_entity_id.items():
|
|
191
194
|
source_shorten = uri_display_name(source_id)
|
|
192
195
|
for export in exports:
|
|
193
196
|
export_id = uri_display_name(export.target_entity.id_)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# NeatState
|
|
2
2
|
|
|
3
3
|
**IN DEVELOPMENT**
|
|
4
|
-
The neat state controls the `
|
|
4
|
+
The neat state controls the `NeatInstanceStore` and `NeatGraphStore`. It is implementing a state machine pattern
|
|
5
5
|
to ensure valid state transitions. The diagram below shows the state machine:
|
|
6
6
|
|
|
7
7
|
```mermaid
|
cognite/neat/session/_state.py
CHANGED
|
@@ -25,7 +25,7 @@ class SessionState:
|
|
|
25
25
|
client: NeatClient | None = None,
|
|
26
26
|
) -> None:
|
|
27
27
|
self.instances = InstancesState(store_type, storage_path=storage_path)
|
|
28
|
-
self.
|
|
28
|
+
self.data_model_store = NeatDataModelStore()
|
|
29
29
|
self.last_reference: PhysicalDataModel | ConceptualDataModel | None = None
|
|
30
30
|
self.client = client
|
|
31
31
|
self.quoted_source_identifiers = False
|
|
@@ -33,23 +33,23 @@ class SessionState:
|
|
|
33
33
|
def rule_transform(self, *transformer: VerifiedDataModelTransformer) -> IssueList:
|
|
34
34
|
if not transformer:
|
|
35
35
|
raise NeatSessionError("No transformers provided.")
|
|
36
|
-
start = self.
|
|
37
|
-
issues = self.
|
|
38
|
-
last_entity = self.
|
|
36
|
+
start = self.data_model_store.provenance[-1].target_entity.display_name
|
|
37
|
+
issues = self.data_model_store.transform(*transformer)
|
|
38
|
+
last_entity = self.data_model_store.provenance[-1].target_entity
|
|
39
39
|
issues.action = f"{start} → {last_entity.display_name}"
|
|
40
40
|
issues.hint = "Use the .inspect.issues() for more details."
|
|
41
41
|
return issues
|
|
42
42
|
|
|
43
43
|
def rule_import(self, importer: BaseImporter, enable_manual_edit: bool = False) -> IssueList:
|
|
44
|
-
issues = self.
|
|
44
|
+
issues = self.data_model_store.import_data_model(
|
|
45
45
|
importer,
|
|
46
46
|
client=self.client,
|
|
47
47
|
enable_manual_edit=enable_manual_edit,
|
|
48
48
|
)
|
|
49
|
-
if self.
|
|
49
|
+
if self.data_model_store.empty:
|
|
50
50
|
result = "failed"
|
|
51
51
|
else:
|
|
52
|
-
result = self.
|
|
52
|
+
result = self.data_model_store.provenance[-1].target_entity.display_name
|
|
53
53
|
if isinstance(importer, InferenceImporter):
|
|
54
54
|
issues.action = f"Inferred {result}"
|
|
55
55
|
else:
|
|
@@ -60,19 +60,19 @@ class SessionState:
|
|
|
60
60
|
|
|
61
61
|
def write_graph(self, extractor: KnowledgeGraphExtractor) -> IssueList:
|
|
62
62
|
extract_issues = self.instances.store.write(extractor)
|
|
63
|
-
issues = self.
|
|
63
|
+
issues = self.data_model_store.import_graph(extractor)
|
|
64
64
|
issues.extend(extract_issues)
|
|
65
65
|
return issues
|
|
66
66
|
|
|
67
67
|
def _raise_exception_if_condition_not_met(
|
|
68
68
|
self,
|
|
69
69
|
activity: str,
|
|
70
|
-
|
|
70
|
+
empty_data_model_store_required: bool = False,
|
|
71
71
|
empty_instances_store_required: bool = False,
|
|
72
72
|
instances_required: bool = False,
|
|
73
73
|
client_required: bool = False,
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
has_conceptual_data_model: bool | None = None,
|
|
75
|
+
has_physical_data_model: bool | None = None,
|
|
76
76
|
) -> None:
|
|
77
77
|
"""Set conditions for raising an error in the session that are used by various methods in the session."""
|
|
78
78
|
condition = set()
|
|
@@ -81,14 +81,14 @@ class SessionState:
|
|
|
81
81
|
if client_required and not self.client:
|
|
82
82
|
condition.add(f"{activity} expects a client in NEAT session")
|
|
83
83
|
suggestion.add("Please provide a client")
|
|
84
|
-
if
|
|
85
|
-
condition.add(f"{activity} expects
|
|
86
|
-
suggestion.add("Read in
|
|
87
|
-
if
|
|
88
|
-
condition.add(f"{activity} expects no
|
|
89
|
-
suggestion.add("You already have a
|
|
84
|
+
if has_conceptual_data_model is True and self.data_model_store.try_get_last_conceptual_data_model is None:
|
|
85
|
+
condition.add(f"{activity} expects conceptual data model in NEAT session")
|
|
86
|
+
suggestion.add("Read in conceptual data model to neat session")
|
|
87
|
+
if has_physical_data_model is False and self.data_model_store.try_get_last_physical_data_model is not None:
|
|
88
|
+
condition.add(f"{activity} expects no physical data model in NEAT session")
|
|
89
|
+
suggestion.add("You already have a physical data model in the session")
|
|
90
90
|
try_again = False
|
|
91
|
-
if
|
|
91
|
+
if empty_data_model_store_required and not self.data_model_store.empty:
|
|
92
92
|
condition.add(f"{activity} expects no data model in NEAT session")
|
|
93
93
|
suggestion.add("Start new session")
|
|
94
94
|
if empty_instances_store_required and not self.instances.empty:
|
cognite/neat/session/_subset.py
CHANGED
|
@@ -49,14 +49,14 @@ class SubsetAPI:
|
|
|
49
49
|
neat.subset.data_model("CogniteAsset")
|
|
50
50
|
```
|
|
51
51
|
"""
|
|
52
|
-
if self._state.
|
|
53
|
-
raise NeatSessionError("No
|
|
52
|
+
if self._state.data_model_store.empty:
|
|
53
|
+
raise NeatSessionError("No data model to set the data model ID.")
|
|
54
54
|
|
|
55
55
|
warnings.filterwarnings("default")
|
|
56
56
|
ExperimentalFlags.data_model_subsetting.warn()
|
|
57
57
|
|
|
58
|
-
dms = self._state.
|
|
59
|
-
information = self._state.
|
|
58
|
+
dms = self._state.data_model_store.provenance[-1].target_entity.physical
|
|
59
|
+
information = self._state.data_model_store.provenance[-1].target_entity.conceptual
|
|
60
60
|
|
|
61
61
|
if dms:
|
|
62
62
|
views = {
|
|
@@ -70,14 +70,14 @@ class SubsetAPI:
|
|
|
70
70
|
|
|
71
71
|
issues = self._state.rule_transform(SubsetPhysicalDataModel(views=views))
|
|
72
72
|
if not issues:
|
|
73
|
-
after = len(self._state.
|
|
73
|
+
after = len(self._state.data_model_store.last_verified_physical_data_model.views)
|
|
74
74
|
|
|
75
75
|
elif information:
|
|
76
76
|
classes = {ConceptEntity(prefix=information.metadata.space, suffix=concept) for concept in concepts}
|
|
77
77
|
|
|
78
78
|
issues = self._state.rule_transform(SubsetConceptualDataModel(concepts=classes))
|
|
79
79
|
if not issues:
|
|
80
|
-
after = len(self._state.
|
|
80
|
+
after = len(self._state.data_model_store.last_verified_conceptual_data_model.concepts)
|
|
81
81
|
|
|
82
82
|
else:
|
|
83
83
|
raise NeatSessionError("Something went terrible wrong. Please contact the neat team.")
|
|
@@ -69,7 +69,7 @@ class TemplateAPI:
|
|
|
69
69
|
- Charts
|
|
70
70
|
|
|
71
71
|
"""
|
|
72
|
-
|
|
72
|
+
last_dm = self._state.data_model_store.last_verified_data_model
|
|
73
73
|
issues = self._state.rule_transform(
|
|
74
74
|
ToEnterpriseModel(
|
|
75
75
|
new_model_id=data_model_id,
|
|
@@ -78,8 +78,8 @@ class TemplateAPI:
|
|
|
78
78
|
move_connections=True,
|
|
79
79
|
)
|
|
80
80
|
)
|
|
81
|
-
if
|
|
82
|
-
self._state.last_reference =
|
|
81
|
+
if last_dm and not issues.has_errors:
|
|
82
|
+
self._state.last_reference = last_dm
|
|
83
83
|
return issues
|
|
84
84
|
|
|
85
85
|
def data_product_model(
|
|
@@ -105,9 +105,9 @@ class TemplateAPI:
|
|
|
105
105
|
If you set same-space, only the properties of the views in the same space as the data model
|
|
106
106
|
will be included.
|
|
107
107
|
"""
|
|
108
|
-
|
|
108
|
+
last_dm = self._state.data_model_store.last_verified_data_model
|
|
109
109
|
view_ids, container_ids = PhysicalValidation(
|
|
110
|
-
self._state.
|
|
110
|
+
self._state.data_model_store.last_verified_physical_data_model
|
|
111
111
|
).imported_views_and_containers_ids()
|
|
112
112
|
transformers: list[VerifiedDataModelTransformer] = []
|
|
113
113
|
client = self._state.client
|
|
@@ -123,8 +123,8 @@ class TemplateAPI:
|
|
|
123
123
|
transformers.append(ToDataProductModel(new_model_id=data_model_id, include=include))
|
|
124
124
|
|
|
125
125
|
issues = self._state.rule_transform(*transformers)
|
|
126
|
-
if
|
|
127
|
-
self._state.last_reference =
|
|
126
|
+
if last_dm and not issues.has_errors:
|
|
127
|
+
self._state.last_reference = last_dm
|
|
128
128
|
return issues
|
|
129
129
|
|
|
130
130
|
def conceptual_model(
|
|
@@ -187,14 +187,16 @@ class TemplateAPI:
|
|
|
187
187
|
with catch_issues() as issues:
|
|
188
188
|
read: ImportedDataModel[UnverifiedConceptualDataModel] = ExcelImporter(path).to_data_model()
|
|
189
189
|
if read.unverified_data_model is not None:
|
|
190
|
-
# If
|
|
190
|
+
# If data model arise None there will be issues that are already caught.
|
|
191
191
|
if not isinstance(read.unverified_data_model, UnverifiedConceptualDataModel):
|
|
192
|
-
raise NeatSessionError(
|
|
192
|
+
raise NeatSessionError(
|
|
193
|
+
f"The input {reader.name} must contain an UnverifiedConceptualDataModel object. "
|
|
194
|
+
)
|
|
193
195
|
if self._state.client is None:
|
|
194
196
|
raise NeatSessionError("Client must be set in the session to run the extension.")
|
|
195
197
|
modified = AddCogniteProperties(self._state.client, dummy_property).transform(read)
|
|
196
198
|
if modified.unverified_data_model is not None:
|
|
197
|
-
# If
|
|
199
|
+
# If data model is None there will be issues that are already caught.
|
|
198
200
|
info = modified.unverified_data_model.as_verified_data_model()
|
|
199
201
|
|
|
200
202
|
ExcelExporter(styling="maximal").export_to_file(info, output_path)
|
|
@@ -202,5 +204,5 @@ class TemplateAPI:
|
|
|
202
204
|
|
|
203
205
|
# Adding issues to the state in the rule store
|
|
204
206
|
if issues:
|
|
205
|
-
self._state.
|
|
207
|
+
self._state.data_model_store._last_issues = issues
|
|
206
208
|
return issues
|