cognite-neat 0.103.1__py3-none-any.whl → 0.105.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 +83 -23
- cognite/neat/_client/_api/schema.py +2 -1
- cognite/neat/_client/data_classes/neat_sequence.py +261 -0
- cognite/neat/_client/data_classes/schema.py +5 -1
- cognite/neat/_client/testing.py +33 -0
- cognite/neat/_constants.py +56 -0
- cognite/neat/_graph/extractors/_classic_cdf/_base.py +6 -5
- cognite/neat/_graph/extractors/_classic_cdf/_sequences.py +225 -11
- cognite/neat/_graph/extractors/_mock_graph_generator.py +2 -2
- cognite/neat/_graph/loaders/_rdf2dms.py +13 -2
- cognite/neat/_graph/transformers/__init__.py +3 -1
- cognite/neat/_graph/transformers/_base.py +109 -1
- cognite/neat/_graph/transformers/_classic_cdf.py +6 -1
- cognite/neat/_graph/transformers/_prune_graph.py +103 -47
- cognite/neat/_graph/transformers/_rdfpath.py +41 -17
- cognite/neat/_graph/transformers/_value_type.py +188 -151
- cognite/neat/_issues/__init__.py +0 -2
- cognite/neat/_issues/_base.py +54 -43
- cognite/neat/_issues/warnings/__init__.py +4 -1
- cognite/neat/_issues/warnings/_general.py +7 -0
- cognite/neat/_issues/warnings/_resources.py +12 -1
- cognite/neat/_rules/_shared.py +18 -34
- cognite/neat/_rules/exporters/_base.py +28 -2
- cognite/neat/_rules/exporters/_rules2dms.py +39 -1
- cognite/neat/_rules/exporters/_rules2excel.py +13 -2
- 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 +80 -57
- 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 +9 -1
- cognite/neat/_rules/models/dms/_rules.py +4 -0
- cognite/neat/_rules/models/dms/_rules_input.py +9 -0
- cognite/neat/_rules/models/entities/_wrapped.py +10 -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/models/mapping/_classic2core.yaml +239 -38
- cognite/neat/_rules/transformers/__init__.py +13 -6
- cognite/neat/_rules/transformers/_base.py +41 -65
- cognite/neat/_rules/transformers/_converters.py +404 -234
- cognite/neat/_rules/transformers/_mapping.py +93 -72
- cognite/neat/_rules/transformers/_verification.py +50 -38
- cognite/neat/_session/_base.py +32 -121
- cognite/neat/_session/_inspect.py +5 -3
- cognite/neat/_session/_mapping.py +17 -105
- cognite/neat/_session/_prepare.py +138 -268
- cognite/neat/_session/_read.py +39 -195
- cognite/neat/_session/_set.py +6 -30
- cognite/neat/_session/_show.py +40 -21
- cognite/neat/_session/_state.py +49 -107
- cognite/neat/_session/_to.py +44 -33
- cognite/neat/_shared.py +23 -2
- cognite/neat/_store/_provenance.py +3 -82
- cognite/neat/_store/_rules_store.py +368 -10
- cognite/neat/_store/exceptions.py +23 -0
- cognite/neat/_utils/graph_transformations_report.py +36 -0
- cognite/neat/_utils/rdf_.py +8 -0
- cognite/neat/_utils/reader/_base.py +27 -0
- cognite/neat/_utils/spreadsheet.py +5 -4
- cognite/neat/_version.py +1 -1
- {cognite_neat-0.103.1.dist-info → cognite_neat-0.105.0.dist-info}/METADATA +3 -2
- cognite_neat-0.105.0.dist-info/RECORD +179 -0
- {cognite_neat-0.103.1.dist-info → cognite_neat-0.105.0.dist-info}/WHEEL +1 -1
- cognite/neat/_app/api/__init__.py +0 -0
- cognite/neat/_app/api/asgi/metrics.py +0 -4
- cognite/neat/_app/api/configuration.py +0 -98
- cognite/neat/_app/api/context_manager/__init__.py +0 -3
- cognite/neat/_app/api/context_manager/manager.py +0 -16
- cognite/neat/_app/api/data_classes/__init__.py +0 -0
- cognite/neat/_app/api/data_classes/rest.py +0 -59
- cognite/neat/_app/api/explorer.py +0 -66
- cognite/neat/_app/api/routers/configuration.py +0 -25
- cognite/neat/_app/api/routers/crud.py +0 -102
- cognite/neat/_app/api/routers/metrics.py +0 -10
- cognite/neat/_app/api/routers/workflows.py +0 -224
- cognite/neat/_app/api/utils/__init__.py +0 -0
- cognite/neat/_app/api/utils/data_mapping.py +0 -17
- cognite/neat/_app/api/utils/logging.py +0 -26
- cognite/neat/_app/api/utils/query_templates.py +0 -92
- cognite/neat/_app/main.py +0 -17
- cognite/neat/_app/monitoring/__init__.py +0 -0
- cognite/neat/_app/monitoring/metrics.py +0 -69
- cognite/neat/_app/ui/index.html +0 -1
- cognite/neat/_app/ui/neat-app/.gitignore +0 -23
- cognite/neat/_app/ui/neat-app/README.md +0 -70
- cognite/neat/_app/ui/neat-app/build/asset-manifest.json +0 -14
- cognite/neat/_app/ui/neat-app/build/favicon.ico +0 -0
- cognite/neat/_app/ui/neat-app/build/img/architect-icon.svg +0 -116
- cognite/neat/_app/ui/neat-app/build/img/developer-icon.svg +0 -112
- cognite/neat/_app/ui/neat-app/build/img/sme-icon.svg +0 -34
- cognite/neat/_app/ui/neat-app/build/index.html +0 -1
- cognite/neat/_app/ui/neat-app/build/logo192.png +0 -0
- cognite/neat/_app/ui/neat-app/build/manifest.json +0 -25
- cognite/neat/_app/ui/neat-app/build/robots.txt +0 -3
- cognite/neat/_app/ui/neat-app/build/static/css/main.72e3d92e.css +0 -2
- cognite/neat/_app/ui/neat-app/build/static/css/main.72e3d92e.css.map +0 -1
- cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js +0 -3
- cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js.LICENSE.txt +0 -88
- cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js.map +0 -1
- cognite/neat/_app/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -1
- cognite/neat/_app/ui/neat-app/package-lock.json +0 -18306
- cognite/neat/_app/ui/neat-app/package.json +0 -62
- cognite/neat/_app/ui/neat-app/public/favicon.ico +0 -0
- cognite/neat/_app/ui/neat-app/public/img/architect-icon.svg +0 -116
- cognite/neat/_app/ui/neat-app/public/img/developer-icon.svg +0 -112
- cognite/neat/_app/ui/neat-app/public/img/sme-icon.svg +0 -34
- cognite/neat/_app/ui/neat-app/public/index.html +0 -43
- cognite/neat/_app/ui/neat-app/public/logo192.png +0 -0
- cognite/neat/_app/ui/neat-app/public/manifest.json +0 -25
- cognite/neat/_app/ui/neat-app/public/robots.txt +0 -3
- cognite/neat/_app/ui/neat-app/src/App.css +0 -38
- cognite/neat/_app/ui/neat-app/src/App.js +0 -17
- cognite/neat/_app/ui/neat-app/src/App.test.js +0 -8
- cognite/neat/_app/ui/neat-app/src/MainContainer.tsx +0 -70
- cognite/neat/_app/ui/neat-app/src/components/JsonViewer.tsx +0 -43
- cognite/neat/_app/ui/neat-app/src/components/LocalUploader.tsx +0 -124
- cognite/neat/_app/ui/neat-app/src/components/OverviewComponentEditorDialog.tsx +0 -63
- cognite/neat/_app/ui/neat-app/src/components/StepEditorDialog.tsx +0 -511
- cognite/neat/_app/ui/neat-app/src/components/TabPanel.tsx +0 -36
- cognite/neat/_app/ui/neat-app/src/components/Utils.tsx +0 -56
- cognite/neat/_app/ui/neat-app/src/components/WorkflowDeleteDialog.tsx +0 -60
- cognite/neat/_app/ui/neat-app/src/components/WorkflowExecutionReport.tsx +0 -112
- cognite/neat/_app/ui/neat-app/src/components/WorkflowImportExportDialog.tsx +0 -67
- cognite/neat/_app/ui/neat-app/src/components/WorkflowMetadataDialog.tsx +0 -79
- cognite/neat/_app/ui/neat-app/src/index.css +0 -13
- cognite/neat/_app/ui/neat-app/src/index.js +0 -13
- cognite/neat/_app/ui/neat-app/src/logo.svg +0 -1
- cognite/neat/_app/ui/neat-app/src/reportWebVitals.js +0 -13
- cognite/neat/_app/ui/neat-app/src/setupTests.js +0 -5
- cognite/neat/_app/ui/neat-app/src/types/WorkflowTypes.ts +0 -388
- cognite/neat/_app/ui/neat-app/src/views/AboutView.tsx +0 -61
- cognite/neat/_app/ui/neat-app/src/views/ConfigView.tsx +0 -184
- cognite/neat/_app/ui/neat-app/src/views/GlobalConfigView.tsx +0 -180
- cognite/neat/_app/ui/neat-app/src/views/WorkflowView.tsx +0 -570
- cognite/neat/_app/ui/neat-app/tsconfig.json +0 -27
- cognite/neat/_rules/transformers/_pipelines.py +0 -70
- cognite/neat/_workflows/__init__.py +0 -17
- cognite/neat/_workflows/base.py +0 -590
- cognite/neat/_workflows/cdf_store.py +0 -393
- cognite/neat/_workflows/examples/Export_DMS/workflow.yaml +0 -89
- cognite/neat/_workflows/examples/Export_Semantic_Data_Model/workflow.yaml +0 -66
- cognite/neat/_workflows/examples/Import_DMS/workflow.yaml +0 -65
- cognite/neat/_workflows/examples/Validate_Rules/workflow.yaml +0 -67
- cognite/neat/_workflows/examples/Validate_Solution_Model/workflow.yaml +0 -64
- cognite/neat/_workflows/manager.py +0 -292
- cognite/neat/_workflows/model.py +0 -203
- cognite/neat/_workflows/steps/__init__.py +0 -0
- cognite/neat/_workflows/steps/data_contracts.py +0 -109
- cognite/neat/_workflows/steps/lib/__init__.py +0 -0
- cognite/neat/_workflows/steps/lib/current/__init__.py +0 -6
- cognite/neat/_workflows/steps/lib/current/graph_extractor.py +0 -100
- cognite/neat/_workflows/steps/lib/current/graph_loader.py +0 -51
- cognite/neat/_workflows/steps/lib/current/graph_store.py +0 -48
- cognite/neat/_workflows/steps/lib/current/rules_exporter.py +0 -537
- cognite/neat/_workflows/steps/lib/current/rules_importer.py +0 -398
- cognite/neat/_workflows/steps/lib/current/rules_validator.py +0 -106
- cognite/neat/_workflows/steps/lib/io/__init__.py +0 -1
- cognite/neat/_workflows/steps/lib/io/io_steps.py +0 -393
- cognite/neat/_workflows/steps/step_model.py +0 -79
- cognite/neat/_workflows/steps_registry.py +0 -218
- cognite/neat/_workflows/tasks.py +0 -18
- cognite/neat/_workflows/triggers.py +0 -169
- cognite/neat/_workflows/utils.py +0 -19
- cognite_neat-0.103.1.dist-info/RECORD +0 -275
- {cognite_neat-0.103.1.dist-info → cognite_neat-0.105.0.dist-info}/LICENSE +0 -0
- {cognite_neat-0.103.1.dist-info → cognite_neat-0.105.0.dist-info}/entry_points.txt +0 -0
cognite/neat/_session/_read.py
CHANGED
|
@@ -1,23 +1,16 @@
|
|
|
1
|
-
import tempfile
|
|
2
|
-
from datetime import datetime, timezone
|
|
3
|
-
from pathlib import Path
|
|
4
1
|
from typing import Any, Literal, cast
|
|
5
2
|
|
|
6
3
|
from cognite.client.data_classes.data_modeling import DataModelId, DataModelIdentifier
|
|
7
4
|
|
|
8
5
|
from cognite.neat._client import NeatClient
|
|
9
|
-
from cognite.neat._constants import COGNITE_SPACES
|
|
10
6
|
from cognite.neat._graph import examples as instances_examples
|
|
11
7
|
from cognite.neat._graph import extractors
|
|
12
8
|
from cognite.neat._issues import IssueList
|
|
13
9
|
from cognite.neat._issues.errors import NeatValueError
|
|
10
|
+
from cognite.neat._issues.warnings import MissingCogniteClientWarning
|
|
14
11
|
from cognite.neat._rules import catalog, importers
|
|
15
|
-
from cognite.neat._rules._shared import ReadRules
|
|
16
12
|
from cognite.neat._rules.importers import BaseImporter
|
|
17
|
-
from cognite.neat.
|
|
18
|
-
from cognite.neat._store._provenance import Change
|
|
19
|
-
from cognite.neat._store._provenance import Entity as ProvenanceEntity
|
|
20
|
-
from cognite.neat._utils.reader import GitHubReader, HttpFileReader, NeatReader, PathReader
|
|
13
|
+
from cognite.neat._utils.reader import NeatReader
|
|
21
14
|
|
|
22
15
|
from ._state import SessionState
|
|
23
16
|
from ._wizard import NeatObjectType, RDFFileType, XMLFileType, object_wizard, rdf_dm_wizard, xml_format_wizard
|
|
@@ -47,26 +40,6 @@ class BaseReadAPI:
|
|
|
47
40
|
self._verbose = verbose
|
|
48
41
|
self._client = client
|
|
49
42
|
|
|
50
|
-
def _store_rules(self, rules: ReadRules, change: Change) -> IssueList:
|
|
51
|
-
if self._verbose:
|
|
52
|
-
if rules.issues.has_errors:
|
|
53
|
-
print("Data model read failed")
|
|
54
|
-
else:
|
|
55
|
-
print("Data model read passed")
|
|
56
|
-
|
|
57
|
-
if rules.rules:
|
|
58
|
-
self._state.data_model.write(rules, change)
|
|
59
|
-
|
|
60
|
-
return rules.issues
|
|
61
|
-
|
|
62
|
-
def _return_filepath(self, io: Any) -> Path:
|
|
63
|
-
if isinstance(io, str):
|
|
64
|
-
return Path(io)
|
|
65
|
-
elif isinstance(io, Path):
|
|
66
|
-
return io
|
|
67
|
-
else:
|
|
68
|
-
raise NeatValueError(f"Expected str or Path, got {type(io)}")
|
|
69
|
-
|
|
70
43
|
|
|
71
44
|
@session_class_wrapper
|
|
72
45
|
class CDFReadAPI(BaseReadAPI):
|
|
@@ -103,31 +76,8 @@ class CDFReadAPI(BaseReadAPI):
|
|
|
103
76
|
if not data_model_id.version:
|
|
104
77
|
raise NeatSessionError("Data model version is required to read a data model.")
|
|
105
78
|
|
|
106
|
-
# actual reading of data model
|
|
107
|
-
start = datetime.now(timezone.utc)
|
|
108
79
|
importer = importers.DMSImporter.from_data_model_id(self._get_client, data_model_id)
|
|
109
|
-
|
|
110
|
-
end = datetime.now(timezone.utc)
|
|
111
|
-
|
|
112
|
-
# provenance information
|
|
113
|
-
source_entity = ProvenanceEntity.from_data_model_id(data_model_id)
|
|
114
|
-
agent = importer.agent
|
|
115
|
-
activity = ProvenanceActivity(
|
|
116
|
-
was_associated_with=agent,
|
|
117
|
-
ended_at_time=end,
|
|
118
|
-
used=source_entity,
|
|
119
|
-
started_at_time=start,
|
|
120
|
-
)
|
|
121
|
-
target_entity = ProvenanceEntity.from_rules(rules, agent, activity)
|
|
122
|
-
change = Change(
|
|
123
|
-
source_entity=source_entity,
|
|
124
|
-
agent=agent,
|
|
125
|
-
activity=activity,
|
|
126
|
-
target_entity=target_entity,
|
|
127
|
-
description=f"DMS Data model {data_model_id.as_tuple()} read as unverified data model",
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
return self._store_rules(rules, change)
|
|
80
|
+
return self._state.rule_import(importer)
|
|
131
81
|
|
|
132
82
|
|
|
133
83
|
@session_class_wrapper
|
|
@@ -215,24 +165,8 @@ class ExcelReadAPI(BaseReadAPI):
|
|
|
215
165
|
io: file path to the Excel sheet
|
|
216
166
|
"""
|
|
217
167
|
reader = NeatReader.create(io)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
raise NeatValueError("Only file paths are supported for Excel files")
|
|
221
|
-
importer: importers.ExcelImporter = importers.ExcelImporter(reader.path)
|
|
222
|
-
input_rules: ReadRules = importer.to_rules()
|
|
223
|
-
end = datetime.now(timezone.utc)
|
|
224
|
-
|
|
225
|
-
if input_rules.rules:
|
|
226
|
-
change = Change.from_rules_activity(
|
|
227
|
-
input_rules,
|
|
228
|
-
importer.agent,
|
|
229
|
-
start,
|
|
230
|
-
end,
|
|
231
|
-
description=f"Excel file {reader!s} read as unverified data model",
|
|
232
|
-
)
|
|
233
|
-
self._store_rules(input_rules, change)
|
|
234
|
-
self._state.data_model.issue_lists.append(input_rules.issues)
|
|
235
|
-
return input_rules.issues
|
|
168
|
+
path = reader.materialize_path()
|
|
169
|
+
return self._state.rule_import(importers.ExcelImporter(path))
|
|
236
170
|
|
|
237
171
|
|
|
238
172
|
@session_class_wrapper
|
|
@@ -241,85 +175,43 @@ class ExcelExampleAPI(BaseReadAPI):
|
|
|
241
175
|
|
|
242
176
|
@property
|
|
243
177
|
def pump_example(self) -> IssueList:
|
|
244
|
-
"""Reads the
|
|
245
|
-
start = datetime.now(timezone.utc)
|
|
178
|
+
"""Reads the Hello World pump example into the NeatSession."""
|
|
246
179
|
importer: importers.ExcelImporter = importers.ExcelImporter(catalog.hello_world_pump)
|
|
247
|
-
|
|
248
|
-
end = datetime.now(timezone.utc)
|
|
249
|
-
|
|
250
|
-
if input_rules.rules:
|
|
251
|
-
change = Change.from_rules_activity(
|
|
252
|
-
input_rules,
|
|
253
|
-
importer.agent,
|
|
254
|
-
start,
|
|
255
|
-
end,
|
|
256
|
-
description="Pump Example read as unverified data model",
|
|
257
|
-
)
|
|
258
|
-
self._store_rules(input_rules, change)
|
|
259
|
-
self._state.data_model.issue_lists.append(input_rules.issues)
|
|
260
|
-
return input_rules.issues
|
|
180
|
+
return self._state.rule_import(importer)
|
|
261
181
|
|
|
262
182
|
|
|
263
183
|
@session_class_wrapper
|
|
264
184
|
class YamlReadAPI(BaseReadAPI):
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
Args:
|
|
268
|
-
io: file path to the Yaml file in the case of "neat" yaml, or path to a zip folder or directory with several
|
|
269
|
-
Yaml files in the case of "toolkit".
|
|
185
|
+
def __call__(self, io: Any, format: Literal["neat", "toolkit"] = "neat") -> IssueList:
|
|
186
|
+
"""Reads a yaml with either neat rules, or several toolkit yaml files to import Data Model(s) into NeatSession.
|
|
270
187
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
"""
|
|
188
|
+
Args:
|
|
189
|
+
io: File path to the Yaml file in the case of "neat" yaml, or path to a zip folder or directory with several
|
|
190
|
+
Yaml files in the case of "toolkit".
|
|
191
|
+
format: The format of the yaml file(s). Can be either "neat" or "toolkit".
|
|
276
192
|
|
|
277
|
-
|
|
193
|
+
Example:
|
|
194
|
+
```python
|
|
195
|
+
neat.read.yaml("path_to_toolkit_yamls")
|
|
196
|
+
```
|
|
197
|
+
"""
|
|
278
198
|
reader = NeatReader.create(io)
|
|
279
|
-
|
|
280
|
-
raise NeatValueError("Only file paths are supported for YAML files")
|
|
281
|
-
start = datetime.now(timezone.utc)
|
|
199
|
+
path = reader.materialize_path()
|
|
282
200
|
importer: BaseImporter
|
|
283
201
|
if format == "neat":
|
|
284
|
-
importer = importers.YAMLImporter.from_file(reader
|
|
202
|
+
importer = importers.YAMLImporter.from_file(path, source_name=f"{reader!s}")
|
|
285
203
|
elif format == "toolkit":
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
if system_container_ids := [
|
|
294
|
-
container_id for container_id in ref_containers if container_id.space in COGNITE_SPACES
|
|
295
|
-
]:
|
|
296
|
-
if self._client is None:
|
|
297
|
-
raise NeatSessionError(
|
|
298
|
-
"No client provided. You are referencing Cognite containers in your data model, "
|
|
299
|
-
"NEAT needs a client to lookup the container definitions. "
|
|
300
|
-
"Please set the client in the session, NeatSession(client=client)."
|
|
301
|
-
)
|
|
302
|
-
system_containers = self._client.loaders.containers.retrieve(system_container_ids)
|
|
303
|
-
dms_importer.update_referenced_containers(system_containers)
|
|
304
|
-
|
|
204
|
+
dms_importer = importers.DMSImporter.from_path(path, self._client)
|
|
205
|
+
if dms_importer.issue_list.has_warning_type(MissingCogniteClientWarning):
|
|
206
|
+
raise NeatSessionError(
|
|
207
|
+
"No client provided. You are referencing Cognite containers in your data model, "
|
|
208
|
+
"NEAT needs a client to lookup the container definitions. "
|
|
209
|
+
"Please set the client in the session, NeatSession(client=client)."
|
|
210
|
+
)
|
|
305
211
|
importer = dms_importer
|
|
306
212
|
else:
|
|
307
213
|
raise NeatValueError(f"Unsupported YAML format: {format}")
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
end = datetime.now(timezone.utc)
|
|
311
|
-
|
|
312
|
-
if input_rules.rules:
|
|
313
|
-
change = Change.from_rules_activity(
|
|
314
|
-
input_rules,
|
|
315
|
-
importer.agent,
|
|
316
|
-
start,
|
|
317
|
-
end,
|
|
318
|
-
description=f"YAML file {reader!s} read as unverified data model",
|
|
319
|
-
)
|
|
320
|
-
self._store_rules(input_rules, change)
|
|
321
|
-
|
|
322
|
-
return input_rules.issues
|
|
214
|
+
return self._state.rule_import(importer)
|
|
323
215
|
|
|
324
216
|
|
|
325
217
|
@session_class_wrapper
|
|
@@ -342,17 +234,9 @@ class CSVReadAPI(BaseReadAPI):
|
|
|
342
234
|
"""
|
|
343
235
|
|
|
344
236
|
def __call__(self, io: Any, type: str, primary_key: str) -> None:
|
|
345
|
-
reader = NeatReader.create(io)
|
|
346
|
-
if isinstance(reader, HttpFileReader):
|
|
347
|
-
path = Path(tempfile.gettempdir()).resolve() / reader.name
|
|
348
|
-
path.write_text(reader.read_text(), encoding="utf-8", newline="\n")
|
|
349
|
-
elif isinstance(reader, PathReader):
|
|
350
|
-
path = reader.path
|
|
351
|
-
else:
|
|
352
|
-
raise NeatValueError("Only file paths are supported for CSV files")
|
|
353
237
|
engine = import_engine()
|
|
354
238
|
engine.set.format = "csv"
|
|
355
|
-
engine.set.file =
|
|
239
|
+
engine.set.file = NeatReader.create(io).materialize_path()
|
|
356
240
|
engine.set.type = type
|
|
357
241
|
engine.set.primary_key = primary_key
|
|
358
242
|
extractor = engine.create_extractor()
|
|
@@ -374,14 +258,7 @@ class XMLReadAPI(BaseReadAPI):
|
|
|
374
258
|
io: Any,
|
|
375
259
|
format: XMLFileType | None = None,
|
|
376
260
|
) -> None:
|
|
377
|
-
|
|
378
|
-
if isinstance(reader, GitHubReader):
|
|
379
|
-
path = Path(tempfile.gettempdir()).resolve() / reader.name
|
|
380
|
-
path.write_text(reader.read_text())
|
|
381
|
-
elif isinstance(reader, PathReader):
|
|
382
|
-
path = reader.path
|
|
383
|
-
else:
|
|
384
|
-
raise NeatValueError("Only file paths are supported for XML files")
|
|
261
|
+
path = NeatReader.create(io).materialize_path()
|
|
385
262
|
if format is None:
|
|
386
263
|
format = xml_format_wizard()
|
|
387
264
|
|
|
@@ -394,7 +271,7 @@ class XMLReadAPI(BaseReadAPI):
|
|
|
394
271
|
else:
|
|
395
272
|
raise NeatValueError("Only support XML files of DEXPI format at the moment.")
|
|
396
273
|
|
|
397
|
-
def dexpi(self,
|
|
274
|
+
def dexpi(self, io: Any) -> None:
|
|
398
275
|
"""Reads a DEXPI file into the NeatSession.
|
|
399
276
|
|
|
400
277
|
Args:
|
|
@@ -405,13 +282,14 @@ class XMLReadAPI(BaseReadAPI):
|
|
|
405
282
|
neat.read.xml.dexpi("url_or_path_to_dexpi_file")
|
|
406
283
|
```
|
|
407
284
|
"""
|
|
285
|
+
path = NeatReader.create(io).materialize_path()
|
|
408
286
|
engine = import_engine()
|
|
409
287
|
engine.set.format = "dexpi"
|
|
410
288
|
engine.set.file = path
|
|
411
289
|
extractor = engine.create_extractor()
|
|
412
290
|
self._state.instances.store.write(extractor)
|
|
413
291
|
|
|
414
|
-
def aml(self,
|
|
292
|
+
def aml(self, io: Any):
|
|
415
293
|
"""Reads an AML file into NeatSession.
|
|
416
294
|
|
|
417
295
|
Args:
|
|
@@ -422,6 +300,7 @@ class XMLReadAPI(BaseReadAPI):
|
|
|
422
300
|
neat.read.xml.aml("url_or_path_to_aml_file")
|
|
423
301
|
```
|
|
424
302
|
"""
|
|
303
|
+
path = NeatReader.create(io).materialize_path()
|
|
425
304
|
engine = import_engine()
|
|
426
305
|
engine.set.format = "aml"
|
|
427
306
|
engine.set.file = path
|
|
@@ -452,25 +331,9 @@ class RDFReadAPI(BaseReadAPI):
|
|
|
452
331
|
neat.read.rdf.ontology("url_or_path_to_owl_source")
|
|
453
332
|
```
|
|
454
333
|
"""
|
|
455
|
-
start = datetime.now(timezone.utc)
|
|
456
334
|
reader = NeatReader.create(io)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
importer = importers.OWLImporter.from_file(reader.path)
|
|
460
|
-
input_rules: ReadRules = importer.to_rules()
|
|
461
|
-
end = datetime.now(timezone.utc)
|
|
462
|
-
|
|
463
|
-
if input_rules.rules:
|
|
464
|
-
change = Change.from_rules_activity(
|
|
465
|
-
input_rules,
|
|
466
|
-
importer.agent,
|
|
467
|
-
start,
|
|
468
|
-
end,
|
|
469
|
-
description=f"Ontology file {reader!s} read as unverified data model",
|
|
470
|
-
)
|
|
471
|
-
self._store_rules(input_rules, change)
|
|
472
|
-
|
|
473
|
-
return input_rules.issues
|
|
335
|
+
importer = importers.OWLImporter.from_file(reader.materialize_path(), source_name=f"file {reader!s}")
|
|
336
|
+
return self._state.rule_import(importer)
|
|
474
337
|
|
|
475
338
|
def imf(self, io: Any) -> IssueList:
|
|
476
339
|
"""Reads IMF Types provided as SHACL shapes into NeatSession.
|
|
@@ -483,25 +346,9 @@ class RDFReadAPI(BaseReadAPI):
|
|
|
483
346
|
neat.read.rdf.imf("url_or_path_to_imf_source")
|
|
484
347
|
```
|
|
485
348
|
"""
|
|
486
|
-
start = datetime.now(timezone.utc)
|
|
487
349
|
reader = NeatReader.create(io)
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
importer = importers.IMFImporter.from_file(reader.path)
|
|
491
|
-
input_rules: ReadRules = importer.to_rules()
|
|
492
|
-
end = datetime.now(timezone.utc)
|
|
493
|
-
|
|
494
|
-
if input_rules.rules:
|
|
495
|
-
change = Change.from_rules_activity(
|
|
496
|
-
input_rules,
|
|
497
|
-
importer.agent,
|
|
498
|
-
start,
|
|
499
|
-
end,
|
|
500
|
-
description=f"IMF Types file {reader!s} read as unverified data model",
|
|
501
|
-
)
|
|
502
|
-
self._store_rules(input_rules, change)
|
|
503
|
-
|
|
504
|
-
return input_rules.issues
|
|
350
|
+
importer = importers.IMFImporter.from_file(reader.materialize_path(), source_name=f"file {reader!s}")
|
|
351
|
+
return self._state.rule_import(importer)
|
|
505
352
|
|
|
506
353
|
def __call__(
|
|
507
354
|
self,
|
|
@@ -527,10 +374,7 @@ class RDFReadAPI(BaseReadAPI):
|
|
|
527
374
|
|
|
528
375
|
elif type == "instances":
|
|
529
376
|
reader = NeatReader.create(io)
|
|
530
|
-
|
|
531
|
-
raise NeatValueError("Only file paths are supported for RDF files")
|
|
532
|
-
|
|
533
|
-
self._state.instances.store.write(extractors.RdfFileExtractor(reader.path))
|
|
377
|
+
self._state.instances.store.write(extractors.RdfFileExtractor(reader.materialize_path()))
|
|
534
378
|
return IssueList()
|
|
535
379
|
else:
|
|
536
380
|
raise NeatSessionError(f"Expected data model or instances, got {type}")
|
cognite/neat/_session/_set.py
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
from datetime import datetime, timezone
|
|
2
|
-
|
|
3
1
|
from cognite.client import data_modeling as dm
|
|
4
2
|
|
|
5
3
|
from cognite.neat._constants import COGNITE_MODELS
|
|
4
|
+
from cognite.neat._issues import IssueList
|
|
5
|
+
from cognite.neat._rules.models import DMSRules
|
|
6
6
|
from cognite.neat._rules.transformers import SetIDDMSModel
|
|
7
|
-
from cognite.neat._store._provenance import Change
|
|
8
7
|
|
|
9
8
|
from ._state import SessionState
|
|
10
9
|
from .exceptions import NeatSessionError, session_class_wrapper
|
|
@@ -18,7 +17,7 @@ class SetAPI:
|
|
|
18
17
|
self._state = state
|
|
19
18
|
self._verbose = verbose
|
|
20
19
|
|
|
21
|
-
def data_model_id(self, new_model_id: dm.DataModelId | tuple[str, str, str]) ->
|
|
20
|
+
def data_model_id(self, new_model_id: dm.DataModelId | tuple[str, str, str]) -> IssueList:
|
|
22
21
|
"""Sets the data model ID of the latest verified data model. Set the data model id as a tuple of strings
|
|
23
22
|
following the template (<data_model_space>, <data_model_name>, <data_model_version>).
|
|
24
23
|
|
|
@@ -28,34 +27,11 @@ class SetAPI:
|
|
|
28
27
|
neat.set.data_model_id(("my_data_model_space", "My_Data_Model", "v1"))
|
|
29
28
|
```
|
|
30
29
|
"""
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
rules = self._state.rule_store.get_last_successful_entity().result
|
|
31
|
+
if isinstance(rules, DMSRules):
|
|
34
32
|
if rules.metadata.as_data_model_id() in COGNITE_MODELS:
|
|
35
33
|
raise NeatSessionError(
|
|
36
34
|
"Cannot change the data model ID of a Cognite Data Model in NeatSession"
|
|
37
35
|
" due to temporarily issue with the reverse direct relation interpretation"
|
|
38
36
|
)
|
|
39
|
-
|
|
40
|
-
start = datetime.now(timezone.utc)
|
|
41
|
-
transformer = SetIDDMSModel(new_model_id)
|
|
42
|
-
|
|
43
|
-
output = transformer.transform(rules)
|
|
44
|
-
end = datetime.now(timezone.utc)
|
|
45
|
-
|
|
46
|
-
# Provenance
|
|
47
|
-
change = Change.from_rules_activity(
|
|
48
|
-
output.rules,
|
|
49
|
-
transformer.agent,
|
|
50
|
-
start,
|
|
51
|
-
end,
|
|
52
|
-
"Changed data model id",
|
|
53
|
-
self._state.data_model.provenance.source_entity(source_id)
|
|
54
|
-
or self._state.data_model.provenance.target_entity(source_id),
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
self._state.data_model.write(output.rules, change)
|
|
58
|
-
if self._verbose:
|
|
59
|
-
print(f"Data model ID set to {new_model_id}")
|
|
60
|
-
else:
|
|
61
|
-
print("No verified DMS data model available")
|
|
37
|
+
return self._state.rule_transform(SetIDDMSModel(new_model_id))
|
cognite/neat/_session/_show.py
CHANGED
|
@@ -5,7 +5,6 @@ from typing import Any, cast
|
|
|
5
5
|
import networkx as nx
|
|
6
6
|
from IPython.display import HTML, display
|
|
7
7
|
from pyvis.network import Network as PyVisNetwork # type: ignore
|
|
8
|
-
from rdflib import URIRef
|
|
9
8
|
|
|
10
9
|
from cognite.neat._constants import IN_NOTEBOOK, IN_PYODIDE
|
|
11
10
|
from cognite.neat._rules._constants import EntityTypes
|
|
@@ -14,7 +13,7 @@ from cognite.neat._rules.models.entities._single_value import ClassEntity, ViewE
|
|
|
14
13
|
from cognite.neat._rules.models.information._rules import InformationRules
|
|
15
14
|
from cognite.neat._session.exceptions import NeatSessionError
|
|
16
15
|
from cognite.neat._utils.io_ import to_directory_compatible
|
|
17
|
-
from cognite.neat._utils.rdf_ import remove_namespace_from_uri
|
|
16
|
+
from cognite.neat._utils.rdf_ import remove_namespace_from_uri, uri_display_name
|
|
18
17
|
|
|
19
18
|
from ._state import SessionState
|
|
20
19
|
from .exceptions import session_class_wrapper
|
|
@@ -99,12 +98,12 @@ class ShowDataModelAPI(ShowBaseAPI):
|
|
|
99
98
|
self.implements = ShowDataModelImplementsAPI(self._state)
|
|
100
99
|
|
|
101
100
|
def __call__(self) -> Any:
|
|
102
|
-
if not self._state.
|
|
101
|
+
if not self._state.rule_store.has_verified_rules:
|
|
103
102
|
raise NeatSessionError(
|
|
104
103
|
"No verified data model available. Try using [bold].verify()[/bold] to verify data model."
|
|
105
104
|
)
|
|
106
105
|
|
|
107
|
-
rules = self._state.
|
|
106
|
+
rules = self._state.rule_store.last_verified_rule
|
|
108
107
|
|
|
109
108
|
if isinstance(rules, DMSRules):
|
|
110
109
|
di_graph = self._generate_dms_di_graph(rules)
|
|
@@ -188,12 +187,12 @@ class ShowDataModelImplementsAPI(ShowBaseAPI):
|
|
|
188
187
|
self._state = state
|
|
189
188
|
|
|
190
189
|
def __call__(self) -> Any:
|
|
191
|
-
if not self._state.
|
|
190
|
+
if not self._state.rule_store.has_verified_rules:
|
|
192
191
|
raise NeatSessionError(
|
|
193
192
|
"No verified data model available. Try using [bold].verify()[/bold] to verify data model."
|
|
194
193
|
)
|
|
195
194
|
|
|
196
|
-
rules = self._state.
|
|
195
|
+
rules = self._state.rule_store.last_verified_rule
|
|
197
196
|
|
|
198
197
|
if isinstance(rules, DMSRules):
|
|
199
198
|
di_graph = self._generate_dms_di_graph(rules)
|
|
@@ -270,20 +269,21 @@ class ShowDataModelProvenanceAPI(ShowBaseAPI):
|
|
|
270
269
|
self._state = state
|
|
271
270
|
|
|
272
271
|
def __call__(self) -> Any:
|
|
273
|
-
if not self._state.
|
|
272
|
+
if not self._state.rule_store.provenance:
|
|
274
273
|
raise NeatSessionError("No data model available. Try using [bold].read[/bold] to load data model.")
|
|
275
274
|
|
|
276
275
|
di_graph = self._generate_dm_provenance_di_graph_and_types()
|
|
277
|
-
|
|
276
|
+
unique_hash = self._state.rule_store.calculate_provenance_hash(shorten=True)
|
|
277
|
+
return self._generate_visualization(di_graph, name=f"data_model_provenance_{unique_hash}.html")
|
|
278
278
|
|
|
279
279
|
def _generate_dm_provenance_di_graph_and_types(self) -> nx.DiGraph:
|
|
280
280
|
di_graph = nx.DiGraph()
|
|
281
|
-
hex_colored_types = _generate_hex_color_per_type(["Agent", "Entity", "Activity"])
|
|
281
|
+
hex_colored_types = _generate_hex_color_per_type(["Agent", "Entity", "Activity", "Export", "Pruned"])
|
|
282
282
|
|
|
283
|
-
for change in self._state.
|
|
284
|
-
source =
|
|
285
|
-
target =
|
|
286
|
-
agent =
|
|
283
|
+
for change in self._state.rule_store.provenance:
|
|
284
|
+
source = uri_display_name(change.source_entity.id_)
|
|
285
|
+
target = uri_display_name(change.target_entity.id_)
|
|
286
|
+
agent = uri_display_name(change.agent.id_)
|
|
287
287
|
|
|
288
288
|
di_graph.add_node(
|
|
289
289
|
source,
|
|
@@ -312,15 +312,34 @@ class ShowDataModelProvenanceAPI(ShowBaseAPI):
|
|
|
312
312
|
di_graph.add_edge(source, agent, label="used", color="grey")
|
|
313
313
|
di_graph.add_edge(agent, target, label="generated", color="grey")
|
|
314
314
|
|
|
315
|
-
|
|
315
|
+
for source_id, exports in self._state.rule_store.exports_by_source_entity_id.items():
|
|
316
|
+
source_shorten = uri_display_name(source_id)
|
|
317
|
+
for export in exports:
|
|
318
|
+
export_id = uri_display_name(export.target_entity.id_)
|
|
319
|
+
di_graph.add_node(
|
|
320
|
+
export_id,
|
|
321
|
+
label=export_id,
|
|
322
|
+
type="Export",
|
|
323
|
+
title="Export",
|
|
324
|
+
color=hex_colored_types["Export"],
|
|
325
|
+
)
|
|
326
|
+
di_graph.add_edge(source_shorten, export_id, label="exported", color="grey")
|
|
316
327
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
328
|
+
for pruned_lists in self._state.rule_store.pruned_by_source_entity_id.values():
|
|
329
|
+
for prune_path in pruned_lists:
|
|
330
|
+
for change in prune_path:
|
|
331
|
+
source = uri_display_name(change.source_entity.id_)
|
|
332
|
+
target = uri_display_name(change.target_entity.id_)
|
|
333
|
+
di_graph.add_node(
|
|
334
|
+
target,
|
|
335
|
+
label=target,
|
|
336
|
+
type="Pruned",
|
|
337
|
+
title="Pruned",
|
|
338
|
+
color=hex_colored_types["Pruned"],
|
|
339
|
+
)
|
|
340
|
+
di_graph.add_edge(source, target, label="pruned", color="grey")
|
|
341
|
+
|
|
342
|
+
return di_graph
|
|
324
343
|
|
|
325
344
|
|
|
326
345
|
@session_class_wrapper
|