cognite-neat 0.121.0__py3-none-any.whl → 0.121.2__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/_client/_api/statistics.py +91 -0
- cognite/neat/core/_client/_api_client.py +2 -0
- cognite/neat/core/_client/data_classes/statistics.py +125 -0
- cognite/neat/core/_client/testing.py +4 -0
- cognite/neat/core/_constants.py +6 -7
- cognite/neat/core/{_rules → _data_model}/_constants.py +25 -18
- cognite/neat/core/_data_model/_shared.py +59 -0
- cognite/neat/core/_data_model/analysis/__init__.py +3 -0
- cognite/neat/core/{_rules → _data_model}/analysis/_base.py +202 -195
- cognite/neat/core/{_rules → _data_model}/catalog/__init__.py +1 -1
- cognite/neat/core/{_rules → _data_model}/exporters/__init__.py +5 -5
- cognite/neat/core/{_rules → _data_model}/exporters/_base.py +10 -8
- cognite/neat/core/{_rules/exporters/_rules2dms.py → _data_model/exporters/_data_model2dms.py} +22 -18
- cognite/neat/core/{_rules/exporters/_rules2excel.py → _data_model/exporters/_data_model2excel.py} +61 -56
- cognite/neat/core/{_rules/exporters/_rules2instance_template.py → _data_model/exporters/_data_model2instance_template.py} +11 -9
- cognite/neat/core/{_rules/exporters/_rules2ontology.py → _data_model/exporters/_data_model2ontology.py} +64 -61
- cognite/neat/core/{_rules/exporters/_rules2yaml.py → _data_model/exporters/_data_model2yaml.py} +21 -18
- cognite/neat/core/{_rules → _data_model}/importers/__init__.py +6 -8
- cognite/neat/core/{_rules → _data_model}/importers/_base.py +8 -6
- cognite/neat/core/_data_model/importers/_base_file_reader.py +56 -0
- cognite/neat/core/{_rules/importers/_yaml2rules.py → _data_model/importers/_dict2data_model.py} +41 -21
- cognite/neat/core/{_rules/importers/_dms2rules.py → _data_model/importers/_dms2data_model.py} +79 -66
- cognite/neat/core/{_rules/importers/_dtdl2rules → _data_model/importers/_dtdl2data_model}/dtdl_converter.py +41 -41
- cognite/neat/core/{_rules/importers/_dtdl2rules → _data_model/importers/_dtdl2data_model}/dtdl_importer.py +16 -16
- cognite/neat/core/{_rules/importers/_dtdl2rules → _data_model/importers/_dtdl2data_model}/spec.py +3 -3
- cognite/neat/core/{_rules → _data_model}/importers/_rdf/_base.py +18 -16
- cognite/neat/core/{_rules → _data_model}/importers/_rdf/_imf2rules.py +17 -17
- cognite/neat/core/{_rules → _data_model}/importers/_rdf/_inference2rules.py +50 -50
- cognite/neat/core/{_rules → _data_model}/importers/_rdf/_owl2rules.py +14 -14
- cognite/neat/core/{_rules → _data_model}/importers/_rdf/_shared.py +25 -25
- cognite/neat/core/{_rules/importers/_spreadsheet2rules.py → _data_model/importers/_spreadsheet2data_model.py} +69 -38
- cognite/neat/core/_data_model/models/__init__.py +36 -0
- cognite/neat/core/{_rules/models/_base_input.py → _data_model/models/_base_unverified.py} +12 -12
- cognite/neat/core/{_rules/models/_base_rules.py → _data_model/models/_base_verified.py} +13 -13
- cognite/neat/core/{_rules → _data_model}/models/_types.py +13 -13
- cognite/neat/core/_data_model/models/conceptual/__init__.py +25 -0
- cognite/neat/core/{_rules/models/information/_rules_input.py → _data_model/models/conceptual/_unverified.py} +46 -43
- cognite/neat/core/{_rules/models/information → _data_model/models/conceptual}/_validation.py +93 -79
- cognite/neat/core/{_rules/models/information/_rules.py → _data_model/models/conceptual/_verified.py} +83 -83
- cognite/neat/core/{_rules → _data_model}/models/data_types.py +4 -4
- cognite/neat/core/{_rules → _data_model}/models/entities/__init__.py +8 -8
- cognite/neat/core/{_rules → _data_model}/models/entities/_loaders.py +12 -11
- cognite/neat/core/{_rules → _data_model}/models/entities/_multi_value.py +7 -7
- cognite/neat/core/{_rules → _data_model}/models/entities/_single_value.py +45 -39
- cognite/neat/core/{_rules → _data_model}/models/entities/_types.py +9 -3
- cognite/neat/core/{_rules → _data_model}/models/entities/_wrapped.py +3 -3
- cognite/neat/core/{_rules → _data_model}/models/mapping/_classic2core.py +12 -9
- cognite/neat/core/_data_model/models/physical/__init__.py +40 -0
- cognite/neat/core/{_rules/models/dms → _data_model/models/physical}/_exporter.py +83 -64
- cognite/neat/core/{_rules/models/dms/_rules_input.py → _data_model/models/physical/_unverified.py} +56 -44
- cognite/neat/core/{_rules/models/dms → _data_model/models/physical}/_validation.py +20 -17
- cognite/neat/core/{_rules/models/dms/_rules.py → _data_model/models/physical/_verified.py} +79 -71
- cognite/neat/core/{_rules → _data_model}/transformers/__init__.py +27 -23
- cognite/neat/core/{_rules → _data_model}/transformers/_base.py +29 -19
- cognite/neat/core/{_rules → _data_model}/transformers/_converters.py +758 -659
- cognite/neat/core/{_rules → _data_model}/transformers/_mapping.py +79 -60
- cognite/neat/core/_data_model/transformers/_verification.py +120 -0
- cognite/neat/core/{_graph → _instances}/extractors/_base.py +2 -2
- cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_base.py +1 -1
- cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_classic.py +17 -11
- cognite/neat/core/{_graph → _instances}/extractors/_dms_graph.py +47 -39
- cognite/neat/core/{_graph → _instances}/extractors/_mock_graph_generator.py +102 -99
- cognite/neat/core/{_graph → _instances}/extractors/_rdf_file.py +2 -2
- cognite/neat/core/{_graph → _instances}/loaders/_base.py +2 -2
- cognite/neat/core/{_graph → _instances}/loaders/_rdf2dms.py +16 -14
- cognite/neat/core/{_graph → _instances}/transformers/_base.py +7 -4
- cognite/neat/core/{_graph → _instances}/transformers/_classic_cdf.py +1 -1
- cognite/neat/core/{_graph → _instances}/transformers/_value_type.py +2 -6
- cognite/neat/core/_issues/_base.py +4 -4
- cognite/neat/core/_issues/errors/__init__.py +2 -2
- cognite/neat/core/_issues/errors/_wrapper.py +2 -2
- cognite/neat/core/_issues/warnings/__init__.py +2 -0
- cognite/neat/core/_issues/warnings/_models.py +4 -4
- cognite/neat/core/_issues/warnings/_properties.py +7 -0
- cognite/neat/core/_store/__init__.py +3 -3
- cognite/neat/core/_store/{_rules_store.py → _data_model.py} +128 -121
- cognite/neat/core/_store/{_graph_store.py → _instance.py} +7 -8
- cognite/neat/core/_store/_provenance.py +2 -2
- cognite/neat/core/_store/exceptions.py +4 -4
- cognite/neat/core/_utils/rdf_.py +14 -0
- cognite/neat/core/_utils/spreadsheet.py +1 -1
- cognite/neat/core/_utils/text.py +2 -2
- cognite/neat/session/_base.py +29 -25
- cognite/neat/session/_drop.py +3 -3
- cognite/neat/session/_fix.py +2 -2
- cognite/neat/session/_inspect.py +5 -5
- cognite/neat/session/_mapping.py +11 -9
- cognite/neat/session/_prepare.py +4 -4
- cognite/neat/session/_read.py +15 -15
- cognite/neat/session/_set.py +5 -5
- cognite/neat/session/_show.py +11 -11
- cognite/neat/session/_state.py +17 -17
- cognite/neat/session/_subset.py +14 -11
- cognite/neat/session/_template.py +19 -19
- cognite/neat/session/_to.py +21 -21
- cognite/neat/session/_wizard.py +1 -1
- {cognite_neat-0.121.0.dist-info → cognite_neat-0.121.2.dist-info}/METADATA +1 -1
- cognite_neat-0.121.2.dist-info/RECORD +189 -0
- cognite/neat/core/_rules/_shared.py +0 -43
- cognite/neat/core/_rules/analysis/__init__.py +0 -3
- cognite/neat/core/_rules/exporters/_validation.py +0 -14
- cognite/neat/core/_rules/models/__init__.py +0 -34
- cognite/neat/core/_rules/models/dms/__init__.py +0 -32
- cognite/neat/core/_rules/models/information/__init__.py +0 -20
- cognite/neat/core/_rules/transformers/_verification.py +0 -111
- cognite_neat-0.121.0.dist-info/RECORD +0 -187
- /cognite/neat/core/{_graph → _data_model}/__init__.py +0 -0
- /cognite/neat/core/{_rules → _data_model}/catalog/classic_model.xlsx +0 -0
- /cognite/neat/core/{_rules/catalog/info-rules-imf.xlsx → _data_model/catalog/conceptual-imf-data-model.xlsx} +0 -0
- /cognite/neat/core/{_rules → _data_model}/catalog/hello_world_pump.xlsx +0 -0
- /cognite/neat/core/{_rules/importers/_dtdl2rules → _data_model/importers/_dtdl2data_model}/__init__.py +0 -0
- /cognite/neat/core/{_rules/importers/_dtdl2rules → _data_model/importers/_dtdl2data_model}/_unit_lookup.py +0 -0
- /cognite/neat/core/{_rules → _data_model}/importers/_rdf/__init__.py +0 -0
- /cognite/neat/core/{_rules → _data_model}/models/entities/_constants.py +0 -0
- /cognite/neat/core/{_rules → _data_model}/models/mapping/__init__.py +0 -0
- /cognite/neat/core/{_rules → _data_model}/models/mapping/_classic2core.yaml +0 -0
- /cognite/neat/core/{_graph/extractors/_classic_cdf → _instances}/__init__.py +0 -0
- /cognite/neat/core/{_graph → _instances}/_shared.py +0 -0
- /cognite/neat/core/{_graph → _instances}/_tracking/__init__.py +0 -0
- /cognite/neat/core/{_graph → _instances}/_tracking/base.py +0 -0
- /cognite/neat/core/{_graph → _instances}/_tracking/log.py +0 -0
- /cognite/neat/core/{_graph → _instances}/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
- /cognite/neat/core/{_graph → _instances}/examples/Knowledge-Graph-Nordic44.xml +0 -0
- /cognite/neat/core/{_graph → _instances}/examples/__init__.py +0 -0
- /cognite/neat/core/{_graph → _instances}/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/__init__.py +0 -0
- /cognite/neat/core/{_rules → _instances/extractors/_classic_cdf}/__init__.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_assets.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_data_sets.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_events.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_files.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_labels.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_relationships.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_sequences.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_classic_cdf/_timeseries.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_dict.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_dms.py +0 -0
- /cognite/neat/core/{_graph → _instances}/extractors/_raw.py +0 -0
- /cognite/neat/core/{_graph → _instances}/loaders/__init__.py +0 -0
- /cognite/neat/core/{_graph → _instances}/queries/__init__.py +0 -0
- /cognite/neat/core/{_graph → _instances}/queries/_base.py +0 -0
- /cognite/neat/core/{_graph → _instances}/queries/_queries.py +0 -0
- /cognite/neat/core/{_graph → _instances}/queries/_select.py +0 -0
- /cognite/neat/core/{_graph → _instances}/queries/_update.py +0 -0
- /cognite/neat/core/{_graph → _instances}/transformers/__init__.py +0 -0
- /cognite/neat/core/{_graph → _instances}/transformers/_prune_graph.py +0 -0
- /cognite/neat/core/{_graph → _instances}/transformers/_rdfpath.py +0 -0
- {cognite_neat-0.121.0.dist-info → cognite_neat-0.121.2.dist-info}/WHEEL +0 -0
- {cognite_neat-0.121.0.dist-info → cognite_neat-0.121.2.dist-info}/licenses/LICENSE +0 -0
cognite/neat/session/_base.py
CHANGED
|
@@ -6,20 +6,22 @@ from cognite.client import data_modeling as dm
|
|
|
6
6
|
|
|
7
7
|
from cognite.neat import _version
|
|
8
8
|
from cognite.neat.core._client import NeatClient
|
|
9
|
+
from cognite.neat.core._data_model import importers
|
|
10
|
+
from cognite.neat.core._data_model.models import PhysicalDataModel
|
|
11
|
+
from cognite.neat.core._data_model.models.conceptual._verified import (
|
|
12
|
+
ConceptualDataModel,
|
|
13
|
+
)
|
|
14
|
+
from cognite.neat.core._data_model.transformers import (
|
|
15
|
+
ConceptualToPhysical,
|
|
16
|
+
MergeConceptualDataModels,
|
|
17
|
+
MergePhysicalDataModels,
|
|
18
|
+
ToDMSCompliantEntities,
|
|
19
|
+
VerifyConceptualDataModel,
|
|
20
|
+
)
|
|
9
21
|
from cognite.neat.core._issues import IssueList
|
|
10
22
|
from cognite.neat.core._issues.errors import RegexViolationError
|
|
11
23
|
from cognite.neat.core._issues.errors._general import NeatImportError
|
|
12
|
-
from cognite.neat.core.
|
|
13
|
-
from cognite.neat.core._rules.models import DMSRules
|
|
14
|
-
from cognite.neat.core._rules.models.information._rules import InformationRules
|
|
15
|
-
from cognite.neat.core._rules.transformers import (
|
|
16
|
-
InformationToDMS,
|
|
17
|
-
MergeDMSRules,
|
|
18
|
-
MergeInformationRules,
|
|
19
|
-
ToDMSCompliantEntities,
|
|
20
|
-
VerifyInformationRules,
|
|
21
|
-
)
|
|
22
|
-
from cognite.neat.core._store._rules_store import RulesEntity
|
|
24
|
+
from cognite.neat.core._store._data_model import DataModelEntity
|
|
23
25
|
from cognite.neat.core._utils.auxiliary import local_import
|
|
24
26
|
|
|
25
27
|
from ._collector import _COLLECTOR, Collector
|
|
@@ -168,7 +170,7 @@ class NeatSession:
|
|
|
168
170
|
self._state._raise_exception_if_condition_not_met(
|
|
169
171
|
"Convert to physical", has_dms_rules=False, has_information_rules=True
|
|
170
172
|
)
|
|
171
|
-
converter =
|
|
173
|
+
converter = ConceptualToPhysical(reserved_properties=reserved_properties, client=self._state.client)
|
|
172
174
|
|
|
173
175
|
issues = self._state.rule_transform(converter)
|
|
174
176
|
|
|
@@ -229,7 +231,7 @@ class NeatSession:
|
|
|
229
231
|
),
|
|
230
232
|
) -> IssueList:
|
|
231
233
|
"""Infer data model from instances."""
|
|
232
|
-
last_entity:
|
|
234
|
+
last_entity: DataModelEntity | None = None
|
|
233
235
|
if self._state.rule_store.provenance:
|
|
234
236
|
last_entity = self._state.rule_store.provenance[-1].target_entity
|
|
235
237
|
|
|
@@ -238,24 +240,26 @@ class NeatSession:
|
|
|
238
240
|
importer = importers.SubclassInferenceImporter(
|
|
239
241
|
issue_list=IssueList(),
|
|
240
242
|
graph=self._state.instances.store.graph(),
|
|
241
|
-
rules=last_entity.
|
|
242
|
-
data_model_id=dm.DataModelId.load(model_id) if last_entity is None else None,
|
|
243
|
+
rules=last_entity.conceptual if last_entity is not None else None,
|
|
244
|
+
data_model_id=(dm.DataModelId.load(model_id) if last_entity is None else None),
|
|
243
245
|
)
|
|
244
246
|
|
|
245
|
-
def action() -> tuple[
|
|
246
|
-
unverified_information = importer.
|
|
247
|
+
def action() -> tuple[ConceptualDataModel, PhysicalDataModel | None]:
|
|
248
|
+
unverified_information = importer.to_data_model()
|
|
247
249
|
unverified_information = ToDMSCompliantEntities(rename_warning="raise").transform(unverified_information)
|
|
248
250
|
|
|
249
|
-
extra_info =
|
|
251
|
+
extra_info = VerifyConceptualDataModel().transform(unverified_information)
|
|
250
252
|
if not last_entity:
|
|
251
253
|
return extra_info, None
|
|
252
|
-
merged_info =
|
|
253
|
-
if not last_entity.
|
|
254
|
+
merged_info = MergeConceptualDataModels(extra_info).transform(last_entity.conceptual)
|
|
255
|
+
if not last_entity.physical:
|
|
254
256
|
return merged_info, None
|
|
255
257
|
|
|
256
|
-
extra_dms =
|
|
258
|
+
extra_dms = ConceptualToPhysical(reserved_properties="warning", client=self._state.client).transform(
|
|
259
|
+
extra_info
|
|
260
|
+
)
|
|
257
261
|
|
|
258
|
-
merged_dms =
|
|
262
|
+
merged_dms = MergePhysicalDataModels(extra_dms).transform(last_entity.physical)
|
|
259
263
|
return merged_info, merged_dms
|
|
260
264
|
|
|
261
265
|
return self._state.rule_store.do_activity(action, importer)
|
|
@@ -269,10 +273,10 @@ class NeatSession:
|
|
|
269
273
|
|
|
270
274
|
if state.rule_store.provenance:
|
|
271
275
|
last_entity = state.rule_store.provenance[-1].target_entity
|
|
272
|
-
if last_entity.
|
|
273
|
-
html = last_entity.
|
|
276
|
+
if last_entity.physical:
|
|
277
|
+
html = last_entity.physical._repr_html_()
|
|
274
278
|
else:
|
|
275
|
-
html = last_entity.
|
|
279
|
+
html = last_entity.conceptual._repr_html_()
|
|
276
280
|
output.append(f"<H2>Data Model</H2><br />{html}") # type: ignore
|
|
277
281
|
|
|
278
282
|
if not state.instances.empty:
|
cognite/neat/session/_drop.py
CHANGED
|
@@ -6,8 +6,8 @@ from cognite.client.utils.useful_types import SequenceNotStr
|
|
|
6
6
|
from rdflib import URIRef
|
|
7
7
|
|
|
8
8
|
from cognite.neat.core._constants import COGNITE_MODELS
|
|
9
|
+
from cognite.neat.core._data_model.transformers import DropModelViews
|
|
9
10
|
from cognite.neat.core._issues import IssueList
|
|
10
|
-
from cognite.neat.core._rules.transformers import DropModelViews
|
|
11
11
|
|
|
12
12
|
from ._state import SessionState
|
|
13
13
|
from .exceptions import NeatSessionError, session_class_wrapper
|
|
@@ -78,7 +78,7 @@ class DropDataModelAPI:
|
|
|
78
78
|
"""
|
|
79
79
|
if sum([view_external_id is not None, group is not None]) != 1:
|
|
80
80
|
raise NeatSessionError("Only one of view_external_id or group can be specified.")
|
|
81
|
-
last_dms = self._state.rule_store.
|
|
81
|
+
last_dms = self._state.rule_store.last_verified_physical_data_model
|
|
82
82
|
if group is not None and last_dms.metadata.as_data_model_id() not in COGNITE_MODELS:
|
|
83
83
|
raise NeatSessionError("Group can only be specified for CogniteCore models.")
|
|
84
84
|
if view_external_id is not None:
|
|
@@ -98,6 +98,6 @@ class DropDataModelAPI:
|
|
|
98
98
|
)
|
|
99
99
|
before = len(last_dms.views)
|
|
100
100
|
issues = self._state.rule_transform(DropModelViews(view_external_id, group))
|
|
101
|
-
after = len(self._state.rule_store.
|
|
101
|
+
after = len(self._state.rule_store.last_verified_physical_data_model.views)
|
|
102
102
|
print(f"Dropped {before - after} views.")
|
|
103
103
|
return issues
|
cognite/neat/session/_fix.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from cognite.neat.core.
|
|
2
|
-
from cognite.neat.core._rules.transformers import (
|
|
1
|
+
from cognite.neat.core._data_model.transformers import (
|
|
3
2
|
ToCompliantEntities,
|
|
4
3
|
)
|
|
4
|
+
from cognite.neat.core._issues._base import IssueList
|
|
5
5
|
|
|
6
6
|
from ._state import SessionState
|
|
7
7
|
from .exceptions import session_class_wrapper
|
cognite/neat/session/_inspect.py
CHANGED
|
@@ -65,10 +65,10 @@ class InspectAPI:
|
|
|
65
65
|
if self._state.rule_store.empty:
|
|
66
66
|
return pd.DataFrame()
|
|
67
67
|
last_entity = self._state.rule_store.provenance[-1].target_entity
|
|
68
|
-
if last_entity.
|
|
69
|
-
df = last_entity.
|
|
68
|
+
if last_entity.physical:
|
|
69
|
+
df = last_entity.physical.properties.to_pandas()
|
|
70
70
|
else:
|
|
71
|
-
df = last_entity.
|
|
71
|
+
df = last_entity.conceptual.properties.to_pandas()
|
|
72
72
|
df.drop(columns=["neatId"], errors="ignore", inplace=True)
|
|
73
73
|
return df
|
|
74
74
|
|
|
@@ -76,9 +76,9 @@ class InspectAPI:
|
|
|
76
76
|
if self._state.rule_store.empty:
|
|
77
77
|
return pd.DataFrame()
|
|
78
78
|
last_entity = self._state.rule_store.provenance[-1].target_entity
|
|
79
|
-
if last_entity.
|
|
79
|
+
if last_entity.physical is None:
|
|
80
80
|
return pd.DataFrame()
|
|
81
|
-
df = last_entity.
|
|
81
|
+
df = last_entity.physical.views.to_pandas()
|
|
82
82
|
df.drop(columns=["neatId"], errors="ignore", inplace=True)
|
|
83
83
|
return df
|
|
84
84
|
|
cognite/neat/session/_mapping.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
from cognite.neat.core.
|
|
2
|
-
from cognite.neat.core.
|
|
3
|
-
from cognite.neat.core._rules.transformers import (
|
|
1
|
+
from cognite.neat.core._data_model.models.mapping import load_classic_to_core_mapping
|
|
2
|
+
from cognite.neat.core._data_model.transformers import (
|
|
4
3
|
AsParentPropertyId,
|
|
5
4
|
ChangeViewPrefix,
|
|
6
5
|
IncludeReferenced,
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
PhysicalDataModelMapper,
|
|
7
|
+
VerifiedDataModelTransformer,
|
|
9
8
|
)
|
|
9
|
+
from cognite.neat.core._issues import IssueList
|
|
10
10
|
|
|
11
11
|
from ._state import SessionState
|
|
12
12
|
from .exceptions import NeatSessionError, session_class_wrapper
|
|
@@ -45,18 +45,20 @@ class DataModelMappingAPI:
|
|
|
45
45
|
if self._state.rule_store.empty:
|
|
46
46
|
raise NeatSessionError("No rules to map")
|
|
47
47
|
last_entity = self._state.rule_store.provenance[-1].target_entity
|
|
48
|
-
if last_entity.
|
|
48
|
+
if last_entity.physical is None:
|
|
49
49
|
raise NeatSessionError("Data model not converted to DMS. Try running `neat.convert('dms')` first.")
|
|
50
|
-
rules = last_entity.
|
|
50
|
+
rules = last_entity.physical
|
|
51
51
|
if self._state.client is None:
|
|
52
52
|
raise NeatSessionError("Client is required to map classic to core")
|
|
53
53
|
|
|
54
|
-
transformers: list[
|
|
54
|
+
transformers: list[VerifiedDataModelTransformer] = []
|
|
55
55
|
if company_prefix:
|
|
56
56
|
transformers.append(ChangeViewPrefix("Classic", company_prefix))
|
|
57
57
|
transformers.extend(
|
|
58
58
|
[
|
|
59
|
-
|
|
59
|
+
PhysicalDataModelMapper(
|
|
60
|
+
load_classic_to_core_mapping(company_prefix, rules.metadata.space, rules.metadata.version)
|
|
61
|
+
),
|
|
60
62
|
IncludeReferenced(self._state.client),
|
|
61
63
|
]
|
|
62
64
|
)
|
cognite/neat/session/_prepare.py
CHANGED
|
@@ -4,17 +4,17 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
from rdflib import URIRef
|
|
6
6
|
|
|
7
|
-
from cognite.neat.core.
|
|
7
|
+
from cognite.neat.core._data_model.transformers import PrefixEntities, StandardizeNaming
|
|
8
|
+
from cognite.neat.core._data_model.transformers._converters import StandardizeSpaceAndVersion
|
|
9
|
+
from cognite.neat.core._instances.transformers import (
|
|
8
10
|
ConnectionToLiteral,
|
|
9
11
|
ConvertLiteral,
|
|
10
12
|
LiteralToEntity,
|
|
11
13
|
RelationshipAsEdgeTransformer,
|
|
12
14
|
)
|
|
13
|
-
from cognite.neat.core.
|
|
15
|
+
from cognite.neat.core._instances.transformers._rdfpath import MakeConnectionOnExactMatch
|
|
14
16
|
from cognite.neat.core._issues import IssueList
|
|
15
17
|
from cognite.neat.core._issues.errors import NeatValueError
|
|
16
|
-
from cognite.neat.core._rules.transformers import PrefixEntities, StandardizeNaming
|
|
17
|
-
from cognite.neat.core._rules.transformers._converters import StandardizeSpaceAndVersion
|
|
18
18
|
from cognite.neat.core._utils.text import humanize_collection
|
|
19
19
|
from cognite.neat.session._experimental import ExperimentalFlags
|
|
20
20
|
|
cognite/neat/session/_read.py
CHANGED
|
@@ -9,15 +9,23 @@ from cognite.neat.core._constants import (
|
|
|
9
9
|
CLASSIC_CDF_NAMESPACE,
|
|
10
10
|
get_default_prefixes_and_namespaces,
|
|
11
11
|
)
|
|
12
|
-
from cognite.neat.core.
|
|
13
|
-
from cognite.neat.core.
|
|
14
|
-
from cognite.neat.core.
|
|
15
|
-
from cognite.neat.core.
|
|
12
|
+
from cognite.neat.core._data_model import catalog, importers
|
|
13
|
+
from cognite.neat.core._data_model.importers import BaseImporter
|
|
14
|
+
from cognite.neat.core._data_model.models.entities._single_value import ViewEntity
|
|
15
|
+
from cognite.neat.core._data_model.transformers import ClassicPrepareCore
|
|
16
|
+
from cognite.neat.core._data_model.transformers._converters import (
|
|
17
|
+
ToEnterpriseModel,
|
|
18
|
+
_SubsetEditableCDMRules,
|
|
19
|
+
)
|
|
20
|
+
from cognite.neat.core._instances import examples as instances_examples
|
|
21
|
+
from cognite.neat.core._instances import extractors
|
|
22
|
+
from cognite.neat.core._instances.extractors._classic_cdf._base import InstanceIdPrefix
|
|
23
|
+
from cognite.neat.core._instances.transformers import (
|
|
16
24
|
ConvertLiteral,
|
|
17
25
|
LiteralToEntity,
|
|
18
26
|
Transformers,
|
|
19
27
|
)
|
|
20
|
-
from cognite.neat.core.
|
|
28
|
+
from cognite.neat.core._instances.transformers._prune_graph import (
|
|
21
29
|
AttachPropertyFromTargetToSource,
|
|
22
30
|
PruneDeadEndEdges,
|
|
23
31
|
PruneInstancesOfUnknownType,
|
|
@@ -26,14 +34,6 @@ from cognite.neat.core._graph.transformers._prune_graph import (
|
|
|
26
34
|
from cognite.neat.core._issues import IssueList
|
|
27
35
|
from cognite.neat.core._issues.errors import NeatValueError
|
|
28
36
|
from cognite.neat.core._issues.warnings import MissingCogniteClientWarning
|
|
29
|
-
from cognite.neat.core._rules import catalog, importers
|
|
30
|
-
from cognite.neat.core._rules.importers import BaseImporter
|
|
31
|
-
from cognite.neat.core._rules.models.entities._single_value import ViewEntity
|
|
32
|
-
from cognite.neat.core._rules.transformers import ClassicPrepareCore
|
|
33
|
-
from cognite.neat.core._rules.transformers._converters import (
|
|
34
|
-
ToEnterpriseModel,
|
|
35
|
-
_SubsetEditableCDMRules,
|
|
36
|
-
)
|
|
37
37
|
from cognite.neat.core._utils.reader import NeatReader
|
|
38
38
|
from cognite.neat.session._experimental import ExperimentalFlags
|
|
39
39
|
|
|
@@ -164,7 +164,7 @@ class CDFReadAPI(BaseReadAPI):
|
|
|
164
164
|
if issues.has_errors:
|
|
165
165
|
return issues
|
|
166
166
|
|
|
167
|
-
cdm_rules = self._state.rule_store.
|
|
167
|
+
cdm_rules = self._state.rule_store.last_verified_data_model
|
|
168
168
|
|
|
169
169
|
issues.extend(
|
|
170
170
|
self._state.rule_transform(
|
|
@@ -593,7 +593,7 @@ class YamlReadAPI(BaseReadAPI):
|
|
|
593
593
|
path = reader.materialize_path()
|
|
594
594
|
importer: BaseImporter
|
|
595
595
|
if format == "neat":
|
|
596
|
-
importer = importers.
|
|
596
|
+
importer = importers.DictImporter.from_yaml_file(path, source_name=f"{reader!s}")
|
|
597
597
|
elif format == "toolkit":
|
|
598
598
|
dms_importer = importers.DMSImporter.from_path(path, self._state.client)
|
|
599
599
|
if dms_importer.issue_list.has_warning_type(MissingCogniteClientWarning):
|
cognite/neat/session/_set.py
CHANGED
|
@@ -3,11 +3,11 @@ from cognite.client import data_modeling as dm
|
|
|
3
3
|
|
|
4
4
|
from cognite.neat.core._client import NeatClient
|
|
5
5
|
from cognite.neat.core._constants import COGNITE_MODELS
|
|
6
|
-
from cognite.neat.core.
|
|
6
|
+
from cognite.neat.core._data_model.models import PhysicalDataModel
|
|
7
|
+
from cognite.neat.core._data_model.transformers import SetIDDMSModel
|
|
8
|
+
from cognite.neat.core._instances.transformers import SetType
|
|
7
9
|
from cognite.neat.core._issues import IssueList
|
|
8
10
|
from cognite.neat.core._issues.errors import NeatValueError
|
|
9
|
-
from cognite.neat.core._rules.models import DMSRules
|
|
10
|
-
from cognite.neat.core._rules.transformers import SetIDDMSModel
|
|
11
11
|
from cognite.neat.core._utils.text import humanize_collection
|
|
12
12
|
|
|
13
13
|
from ._state import SessionState
|
|
@@ -41,8 +41,8 @@ class SetAPI:
|
|
|
41
41
|
"""
|
|
42
42
|
if self._state.rule_store.empty:
|
|
43
43
|
raise NeatSessionError("No rules to set the data model ID.")
|
|
44
|
-
rules = self._state.rule_store.provenance[-1].target_entity.
|
|
45
|
-
if isinstance(rules,
|
|
44
|
+
rules = self._state.rule_store.provenance[-1].target_entity.physical
|
|
45
|
+
if isinstance(rules, PhysicalDataModel):
|
|
46
46
|
if rules.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"
|
cognite/neat/session/_show.py
CHANGED
|
@@ -7,7 +7,7 @@ from IPython.display import HTML, display
|
|
|
7
7
|
from pyvis.network import Network as PyVisNetwork # type: ignore
|
|
8
8
|
|
|
9
9
|
from cognite.neat.core._constants import IN_NOTEBOOK, IN_PYODIDE
|
|
10
|
-
from cognite.neat.core.
|
|
10
|
+
from cognite.neat.core._data_model.analysis._base import DataModelAnalysis
|
|
11
11
|
from cognite.neat.core._utils.io_ import to_directory_compatible
|
|
12
12
|
from cognite.neat.core._utils.rdf_ import remove_namespace_from_uri, uri_display_name
|
|
13
13
|
from cognite.neat.session.exceptions import NeatSessionError
|
|
@@ -99,13 +99,13 @@ class ShowDataModelAPI(ShowBaseAPI):
|
|
|
99
99
|
raise NeatSessionError("No data model available. Try using [bold].read[/bold] to read a data model.")
|
|
100
100
|
|
|
101
101
|
last_target = self._state.rule_store.provenance[-1].target_entity
|
|
102
|
-
rules = last_target.
|
|
103
|
-
analysis =
|
|
102
|
+
rules = last_target.physical or last_target.conceptual
|
|
103
|
+
analysis = DataModelAnalysis(physical=last_target.physical, conceptual=last_target.conceptual)
|
|
104
104
|
|
|
105
|
-
if last_target.
|
|
106
|
-
di_graph = analysis.
|
|
105
|
+
if last_target.physical is not None:
|
|
106
|
+
di_graph = analysis._physical_di_graph(format="data-model")
|
|
107
107
|
else:
|
|
108
|
-
di_graph = analysis.
|
|
108
|
+
di_graph = analysis._conceptual_di_graph(format="data-model")
|
|
109
109
|
|
|
110
110
|
identifier = to_directory_compatible(str(rules.metadata.identifier))
|
|
111
111
|
name = f"{identifier}.html"
|
|
@@ -123,13 +123,13 @@ class ShowDataModelImplementsAPI(ShowBaseAPI):
|
|
|
123
123
|
raise NeatSessionError("No data model available. Try using [bold].read[/bold] to read a data model.")
|
|
124
124
|
|
|
125
125
|
last_target = self._state.rule_store.provenance[-1].target_entity
|
|
126
|
-
rules = last_target.
|
|
127
|
-
analysis =
|
|
126
|
+
rules = last_target.physical or last_target.conceptual
|
|
127
|
+
analysis = DataModelAnalysis(physical=last_target.physical, conceptual=last_target.conceptual)
|
|
128
128
|
|
|
129
|
-
if last_target.
|
|
130
|
-
di_graph = analysis.
|
|
129
|
+
if last_target.physical is not None:
|
|
130
|
+
di_graph = analysis._physical_di_graph(format="implements")
|
|
131
131
|
else:
|
|
132
|
-
di_graph = analysis.
|
|
132
|
+
di_graph = analysis._conceptual_di_graph(format="implements")
|
|
133
133
|
identifier = to_directory_compatible(str(rules.metadata.identifier))
|
|
134
134
|
name = f"{identifier}_implements.html"
|
|
135
135
|
return self._generate_visualization(di_graph, name)
|
cognite/neat/session/_state.py
CHANGED
|
@@ -4,14 +4,14 @@ from typing import Literal, cast
|
|
|
4
4
|
from rdflib import URIRef
|
|
5
5
|
|
|
6
6
|
from cognite.neat.core._client import NeatClient
|
|
7
|
-
from cognite.neat.core.
|
|
8
|
-
from cognite.neat.core.
|
|
9
|
-
from cognite.neat.core.
|
|
10
|
-
|
|
11
|
-
from cognite.neat.core._rules.transformers import (
|
|
12
|
-
VerifiedRulesTransformer,
|
|
7
|
+
from cognite.neat.core._data_model.importers import BaseImporter, InferenceImporter
|
|
8
|
+
from cognite.neat.core._data_model.models import ConceptualDataModel, PhysicalDataModel
|
|
9
|
+
from cognite.neat.core._data_model.transformers import (
|
|
10
|
+
VerifiedDataModelTransformer,
|
|
13
11
|
)
|
|
14
|
-
from cognite.neat.core.
|
|
12
|
+
from cognite.neat.core._instances.extractors import KnowledgeGraphExtractor
|
|
13
|
+
from cognite.neat.core._issues import IssueList
|
|
14
|
+
from cognite.neat.core._store import NeatDataModelStore, NeatInstanceStore
|
|
15
15
|
from cognite.neat.core._utils.upload import UploadResultList
|
|
16
16
|
|
|
17
17
|
from .exceptions import NeatSessionError, _session_method_wrapper
|
|
@@ -25,12 +25,12 @@ class SessionState:
|
|
|
25
25
|
client: NeatClient | None = None,
|
|
26
26
|
) -> None:
|
|
27
27
|
self.instances = InstancesState(store_type, storage_path=storage_path)
|
|
28
|
-
self.rule_store =
|
|
29
|
-
self.last_reference:
|
|
28
|
+
self.rule_store = NeatDataModelStore()
|
|
29
|
+
self.last_reference: PhysicalDataModel | ConceptualDataModel | None = None
|
|
30
30
|
self.client = client
|
|
31
31
|
self.quoted_source_identifiers = False
|
|
32
32
|
|
|
33
|
-
def rule_transform(self, *transformer:
|
|
33
|
+
def rule_transform(self, *transformer: VerifiedDataModelTransformer) -> IssueList:
|
|
34
34
|
if not transformer:
|
|
35
35
|
raise NeatSessionError("No transformers provided.")
|
|
36
36
|
start = self.rule_store.provenance[-1].target_entity.display_name
|
|
@@ -41,7 +41,7 @@ class SessionState:
|
|
|
41
41
|
return issues
|
|
42
42
|
|
|
43
43
|
def rule_import(self, importer: BaseImporter, enable_manual_edit: bool = False) -> IssueList:
|
|
44
|
-
issues = self.rule_store.
|
|
44
|
+
issues = self.rule_store.import_data_model(
|
|
45
45
|
importer,
|
|
46
46
|
client=self.client,
|
|
47
47
|
enable_manual_edit=enable_manual_edit,
|
|
@@ -81,10 +81,10 @@ 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 has_information_rules is True and self.rule_store.
|
|
84
|
+
if has_information_rules is True and self.rule_store.try_get_last_conceptual_data_model is None:
|
|
85
85
|
condition.add(f"{activity} expects information rules in NEAT session")
|
|
86
86
|
suggestion.add("Read in information rules to neat session")
|
|
87
|
-
if has_dms_rules is False and self.rule_store.
|
|
87
|
+
if has_dms_rules is False and self.rule_store.try_get_last_physical_data_model is not None:
|
|
88
88
|
condition.add(f"{activity} expects no DMS data model in NEAT session")
|
|
89
89
|
suggestion.add("You already have a DMS data model in the session")
|
|
90
90
|
try_again = False
|
|
@@ -121,18 +121,18 @@ class InstancesState:
|
|
|
121
121
|
self.neat_prefix_by_type_uri: dict[URIRef, str] = {}
|
|
122
122
|
|
|
123
123
|
# Ensure that error handling is done in the constructor
|
|
124
|
-
self.store:
|
|
124
|
+
self.store: NeatInstanceStore = _session_method_wrapper(self._create_store, "NeatSession")()
|
|
125
125
|
|
|
126
126
|
if self.storage_path:
|
|
127
127
|
print("Remember to close neat session .close() once you are done to avoid oxigraph lock.")
|
|
128
128
|
|
|
129
|
-
def _create_store(self) ->
|
|
129
|
+
def _create_store(self) -> NeatInstanceStore:
|
|
130
130
|
if self.store_type == "oxigraph":
|
|
131
131
|
if self.storage_path:
|
|
132
132
|
self.storage_path.mkdir(parents=True, exist_ok=True)
|
|
133
|
-
return
|
|
133
|
+
return NeatInstanceStore.from_oxi_local_store(storage_dir=self.storage_path)
|
|
134
134
|
else:
|
|
135
|
-
return
|
|
135
|
+
return NeatInstanceStore.from_memory_store()
|
|
136
136
|
|
|
137
137
|
@property
|
|
138
138
|
def empty(self) -> bool:
|
cognite/neat/session/_subset.py
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import warnings
|
|
2
2
|
|
|
3
|
-
from cognite.neat.core.
|
|
4
|
-
|
|
5
|
-
ClassEntity,
|
|
3
|
+
from cognite.neat.core._data_model.models.entities._single_value import (
|
|
4
|
+
ConceptEntity,
|
|
6
5
|
ViewEntity,
|
|
7
6
|
)
|
|
8
|
-
from cognite.neat.core.
|
|
7
|
+
from cognite.neat.core._data_model.transformers import (
|
|
8
|
+
SubsetConceptualDataModel,
|
|
9
|
+
SubsetPhysicalDataModel,
|
|
10
|
+
)
|
|
11
|
+
from cognite.neat.core._issues._base import IssueList
|
|
9
12
|
from cognite.neat.session._experimental import ExperimentalFlags
|
|
10
13
|
|
|
11
14
|
from ._state import SessionState
|
|
@@ -52,8 +55,8 @@ class SubsetAPI:
|
|
|
52
55
|
warnings.filterwarnings("default")
|
|
53
56
|
ExperimentalFlags.data_model_subsetting.warn()
|
|
54
57
|
|
|
55
|
-
dms = self._state.rule_store.provenance[-1].target_entity.
|
|
56
|
-
information = self._state.rule_store.provenance[-1].target_entity.
|
|
58
|
+
dms = self._state.rule_store.provenance[-1].target_entity.physical
|
|
59
|
+
information = self._state.rule_store.provenance[-1].target_entity.conceptual
|
|
57
60
|
|
|
58
61
|
if dms:
|
|
59
62
|
views = {
|
|
@@ -65,16 +68,16 @@ class SubsetAPI:
|
|
|
65
68
|
for concept in concepts
|
|
66
69
|
}
|
|
67
70
|
|
|
68
|
-
issues = self._state.rule_transform(
|
|
71
|
+
issues = self._state.rule_transform(SubsetPhysicalDataModel(views=views))
|
|
69
72
|
if not issues:
|
|
70
|
-
after = len(self._state.rule_store.
|
|
73
|
+
after = len(self._state.rule_store.last_verified_physical_data_model.views)
|
|
71
74
|
|
|
72
75
|
elif information:
|
|
73
|
-
classes = {
|
|
76
|
+
classes = {ConceptEntity(prefix=information.metadata.space, suffix=concept) for concept in concepts}
|
|
74
77
|
|
|
75
|
-
issues = self._state.rule_transform(
|
|
78
|
+
issues = self._state.rule_transform(SubsetConceptualDataModel(concepts=classes))
|
|
76
79
|
if not issues:
|
|
77
|
-
after = len(self._state.rule_store.
|
|
80
|
+
after = len(self._state.rule_store.last_verified_conceptual_data_model.concepts)
|
|
78
81
|
|
|
79
82
|
else:
|
|
80
83
|
raise NeatSessionError("Something went terrible wrong. Please contact the neat team.")
|
|
@@ -4,20 +4,20 @@ from typing import Any, Literal
|
|
|
4
4
|
from cognite.client.data_classes.data_modeling import DataModelIdentifier
|
|
5
5
|
|
|
6
6
|
from cognite.neat.core._constants import BASE_MODEL
|
|
7
|
-
from cognite.neat.core.
|
|
8
|
-
from cognite.neat.core.
|
|
9
|
-
from cognite.neat.core.
|
|
10
|
-
from cognite.neat.core.
|
|
11
|
-
from cognite.neat.core.
|
|
12
|
-
from cognite.neat.core.
|
|
13
|
-
from cognite.neat.core.
|
|
14
|
-
from cognite.neat.core._rules.transformers import (
|
|
7
|
+
from cognite.neat.core._data_model._shared import ImportedDataModel
|
|
8
|
+
from cognite.neat.core._data_model.exporters import ExcelExporter
|
|
9
|
+
from cognite.neat.core._data_model.importers import ExcelImporter
|
|
10
|
+
from cognite.neat.core._data_model.models import UnverifiedConceptualDataModel
|
|
11
|
+
from cognite.neat.core._data_model.models._base_verified import RoleTypes
|
|
12
|
+
from cognite.neat.core._data_model.models.physical import PhysicalValidation
|
|
13
|
+
from cognite.neat.core._data_model.transformers import (
|
|
15
14
|
AddCogniteProperties,
|
|
16
15
|
IncludeReferenced,
|
|
17
16
|
ToDataProductModel,
|
|
18
17
|
ToEnterpriseModel,
|
|
19
|
-
|
|
18
|
+
VerifiedDataModelTransformer,
|
|
20
19
|
)
|
|
20
|
+
from cognite.neat.core._issues import IssueList, catch_issues
|
|
21
21
|
from cognite.neat.core._utils.reader import NeatReader, PathReader
|
|
22
22
|
from cognite.neat.session._experimental import ExperimentalFlags
|
|
23
23
|
|
|
@@ -69,7 +69,7 @@ class TemplateAPI:
|
|
|
69
69
|
- Charts
|
|
70
70
|
|
|
71
71
|
"""
|
|
72
|
-
last_rules = self._state.rule_store.
|
|
72
|
+
last_rules = self._state.rule_store.last_verified_data_model
|
|
73
73
|
issues = self._state.rule_transform(
|
|
74
74
|
ToEnterpriseModel(
|
|
75
75
|
new_model_id=data_model_id,
|
|
@@ -105,11 +105,11 @@ 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
|
-
last_rules = self._state.rule_store.
|
|
109
|
-
view_ids, container_ids =
|
|
110
|
-
self._state.rule_store.
|
|
108
|
+
last_rules = self._state.rule_store.last_verified_data_model
|
|
109
|
+
view_ids, container_ids = PhysicalValidation(
|
|
110
|
+
self._state.rule_store.last_verified_physical_data_model
|
|
111
111
|
).imported_views_and_containers_ids()
|
|
112
|
-
transformers: list[
|
|
112
|
+
transformers: list[VerifiedDataModelTransformer] = []
|
|
113
113
|
client = self._state.client
|
|
114
114
|
if (view_ids or container_ids) and client is None:
|
|
115
115
|
raise NeatSessionError(
|
|
@@ -185,17 +185,17 @@ class TemplateAPI:
|
|
|
185
185
|
output_path = Path(output)
|
|
186
186
|
|
|
187
187
|
with catch_issues() as issues:
|
|
188
|
-
read:
|
|
189
|
-
if read.
|
|
188
|
+
read: ImportedDataModel[UnverifiedConceptualDataModel] = ExcelImporter(path).to_data_model()
|
|
189
|
+
if read.unverified_data_model is not None:
|
|
190
190
|
# If rules are None there will be issues that are already caught.
|
|
191
|
-
if not isinstance(read.
|
|
191
|
+
if not isinstance(read.unverified_data_model, UnverifiedConceptualDataModel):
|
|
192
192
|
raise NeatSessionError(f"The input {reader.name} must contain an InformationInputRules object. ")
|
|
193
193
|
if self._state.client is None:
|
|
194
194
|
raise NeatSessionError("Client must be set in the session to run the extension.")
|
|
195
195
|
modified = AddCogniteProperties(self._state.client, dummy_property).transform(read)
|
|
196
|
-
if modified.
|
|
196
|
+
if modified.unverified_data_model is not None:
|
|
197
197
|
# If rules are None there will be issues that are already caught.
|
|
198
|
-
info = modified.
|
|
198
|
+
info = modified.unverified_data_model.as_verified_data_model()
|
|
199
199
|
|
|
200
200
|
ExcelExporter(styling="maximal").export_to_file(info, output_path)
|
|
201
201
|
issues.action = "Created extension template"
|