cognite-neat 0.88.3__py3-none-any.whl → 0.90.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/_version.py +1 -1
- cognite/neat/constants.py +6 -3
- cognite/neat/graph/extractors/__init__.py +2 -0
- cognite/neat/graph/extractors/_classic_cdf/_base.py +2 -2
- cognite/neat/graph/extractors/_dms.py +158 -0
- cognite/neat/graph/extractors/_mock_graph_generator.py +50 -9
- cognite/neat/graph/loaders/_rdf2dms.py +16 -13
- cognite/neat/graph/models.py +1 -0
- cognite/neat/graph/queries/_base.py +4 -2
- cognite/neat/issues/_base.py +3 -1
- cognite/neat/issues/errors/__init__.py +2 -1
- cognite/neat/issues/errors/_general.py +7 -0
- cognite/neat/issues/warnings/__init__.py +2 -0
- cognite/neat/issues/warnings/_models.py +1 -1
- cognite/neat/issues/warnings/_properties.py +12 -0
- cognite/neat/issues/warnings/user_modeling.py +1 -1
- cognite/neat/rules/_shared.py +49 -6
- cognite/neat/rules/analysis/_base.py +1 -1
- cognite/neat/rules/exporters/_base.py +7 -18
- cognite/neat/rules/exporters/_rules2dms.py +8 -18
- cognite/neat/rules/exporters/_rules2excel.py +5 -12
- cognite/neat/rules/exporters/_rules2ontology.py +9 -19
- cognite/neat/rules/exporters/_rules2yaml.py +3 -6
- cognite/neat/rules/importers/_base.py +7 -52
- cognite/neat/rules/importers/_dms2rules.py +172 -116
- cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py +26 -18
- cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py +14 -30
- cognite/neat/rules/importers/_rdf/_imf2rules/_imf2classes.py +7 -3
- cognite/neat/rules/importers/_rdf/_imf2rules/_imf2metadata.py +3 -3
- cognite/neat/rules/importers/_rdf/_imf2rules/_imf2properties.py +18 -11
- cognite/neat/rules/importers/_rdf/_imf2rules/_imf2rules.py +9 -18
- cognite/neat/rules/importers/_rdf/_inference2rules.py +37 -65
- cognite/neat/rules/importers/_rdf/_owl2rules/_owl2rules.py +9 -20
- cognite/neat/rules/importers/_rdf/_shared.py +1 -1
- cognite/neat/rules/importers/_spreadsheet2rules.py +22 -86
- cognite/neat/rules/importers/_yaml2rules.py +14 -41
- cognite/neat/rules/models/__init__.py +21 -5
- cognite/neat/rules/models/_base_input.py +162 -0
- cognite/neat/rules/models/{_base.py → _base_rules.py} +1 -12
- cognite/neat/rules/models/asset/__init__.py +5 -2
- cognite/neat/rules/models/asset/_rules.py +2 -20
- cognite/neat/rules/models/asset/_rules_input.py +40 -115
- cognite/neat/rules/models/asset/_validation.py +1 -1
- cognite/neat/rules/models/data_types.py +150 -44
- cognite/neat/rules/models/dms/__init__.py +19 -7
- cognite/neat/rules/models/dms/_exporter.py +82 -39
- cognite/neat/rules/models/dms/_rules.py +42 -155
- cognite/neat/rules/models/dms/_rules_input.py +186 -254
- cognite/neat/rules/models/dms/_serializer.py +44 -3
- cognite/neat/rules/models/dms/_validation.py +3 -4
- cognite/neat/rules/models/domain.py +52 -1
- cognite/neat/rules/models/entities/__init__.py +63 -0
- cognite/neat/rules/models/entities/_constants.py +73 -0
- cognite/neat/rules/models/entities/_loaders.py +76 -0
- cognite/neat/rules/models/entities/_multi_value.py +67 -0
- cognite/neat/rules/models/{entities.py → entities/_single_value.py} +74 -232
- cognite/neat/rules/models/entities/_types.py +86 -0
- cognite/neat/rules/models/{wrapped_entities.py → entities/_wrapped.py} +1 -1
- cognite/neat/rules/models/information/__init__.py +10 -2
- cognite/neat/rules/models/information/_rules.py +3 -14
- cognite/neat/rules/models/information/_rules_input.py +57 -204
- cognite/neat/rules/models/information/_validation.py +1 -1
- cognite/neat/rules/transformers/__init__.py +21 -0
- cognite/neat/rules/transformers/_base.py +69 -3
- cognite/neat/rules/{models/information/_converter.py → transformers/_converters.py} +226 -21
- cognite/neat/rules/transformers/_map_onto.py +97 -0
- cognite/neat/rules/transformers/_pipelines.py +61 -0
- cognite/neat/rules/transformers/_verification.py +136 -0
- cognite/neat/store/_base.py +2 -2
- cognite/neat/store/_provenance.py +10 -1
- cognite/neat/utils/cdf/data_classes.py +20 -0
- cognite/neat/utils/regex_patterns.py +6 -0
- cognite/neat/workflows/steps/lib/current/rules_exporter.py +106 -37
- cognite/neat/workflows/steps/lib/current/rules_importer.py +24 -22
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/METADATA +1 -1
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/RECORD +80 -74
- cognite/neat/rules/models/_constants.py +0 -2
- cognite/neat/rules/models/_types/__init__.py +0 -19
- cognite/neat/rules/models/asset/_converter.py +0 -4
- cognite/neat/rules/models/dms/_converter.py +0 -143
- /cognite/neat/rules/models/{_types/_field.py → _types.py} +0 -0
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/LICENSE +0 -0
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/WHEEL +0 -0
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/entry_points.txt +0 -0
|
@@ -268,6 +268,10 @@ class ViewApplyDict(CogniteResourceDict[ViewId, ViewApply]):
|
|
|
268
268
|
def _as_id(cls, resource: ViewApply) -> ViewId:
|
|
269
269
|
return resource.as_id()
|
|
270
270
|
|
|
271
|
+
@classmethod
|
|
272
|
+
def from_iterable(cls, iterable: Iterable[ViewApply]) -> "ViewApplyDict":
|
|
273
|
+
return cls({view.as_id(): view for view in iterable})
|
|
274
|
+
|
|
271
275
|
|
|
272
276
|
class SpaceApplyDict(CogniteResourceDict[str, SpaceApply]):
|
|
273
277
|
_RESOURCE = SpaceApply
|
|
@@ -276,6 +280,10 @@ class SpaceApplyDict(CogniteResourceDict[str, SpaceApply]):
|
|
|
276
280
|
def _as_id(cls, resource: SpaceApply) -> str:
|
|
277
281
|
return resource.space
|
|
278
282
|
|
|
283
|
+
@classmethod
|
|
284
|
+
def from_iterable(cls, iterable: Iterable[SpaceApply]) -> "SpaceApplyDict":
|
|
285
|
+
return cls({space.space: space for space in iterable})
|
|
286
|
+
|
|
279
287
|
|
|
280
288
|
class ContainerApplyDict(CogniteResourceDict[ContainerId, ContainerApply]):
|
|
281
289
|
_RESOURCE = ContainerApply
|
|
@@ -284,6 +292,10 @@ class ContainerApplyDict(CogniteResourceDict[ContainerId, ContainerApply]):
|
|
|
284
292
|
def _as_id(cls, resource: ContainerApply) -> ContainerId:
|
|
285
293
|
return resource.as_id()
|
|
286
294
|
|
|
295
|
+
@classmethod
|
|
296
|
+
def from_iterable(cls, iterable: Iterable[ContainerApply]) -> "ContainerApplyDict":
|
|
297
|
+
return cls({container.as_id(): container for container in iterable})
|
|
298
|
+
|
|
287
299
|
|
|
288
300
|
class DataModelApplyDict(CogniteResourceDict[DataModelId, DataModelApply]):
|
|
289
301
|
_RESOURCE = DataModelApply
|
|
@@ -292,6 +304,10 @@ class DataModelApplyDict(CogniteResourceDict[DataModelId, DataModelApply]):
|
|
|
292
304
|
def _as_id(cls, resource: DataModelApply) -> DataModelId:
|
|
293
305
|
return resource.as_id()
|
|
294
306
|
|
|
307
|
+
@classmethod
|
|
308
|
+
def from_iterable(cls, iterable: Iterable[DataModelApply]) -> "DataModelApplyDict":
|
|
309
|
+
return cls({data_model.as_id(): data_model for data_model in iterable})
|
|
310
|
+
|
|
295
311
|
|
|
296
312
|
class NodeApplyDict(CogniteResourceDict[NodeId, NodeApply]):
|
|
297
313
|
_RESOURCE = NodeApply
|
|
@@ -299,3 +315,7 @@ class NodeApplyDict(CogniteResourceDict[NodeId, NodeApply]):
|
|
|
299
315
|
@classmethod
|
|
300
316
|
def _as_id(cls, resource: NodeApply) -> NodeId:
|
|
301
317
|
return resource.as_id()
|
|
318
|
+
|
|
319
|
+
@classmethod
|
|
320
|
+
def from_iterable(cls, iterable: Iterable[NodeApply]) -> "NodeApplyDict":
|
|
321
|
+
return cls({node.as_id(): node for node in iterable})
|
|
@@ -19,6 +19,12 @@ PROPERTY_ID_COMPLIANCE_REGEX = r"^(\*)|(?!^(Property|property)$)(^[a-zA-Z][a-zA-
|
|
|
19
19
|
VERSION_COMPLIANCE_REGEX = r"^[a-zA-Z0-9]([.a-zA-Z0-9_-]{0,41}[a-zA-Z0-9])?$"
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
# This pattern ignores commas inside brackets
|
|
23
|
+
SPLIT_ON_COMMA_PATTERN = re.compile(r",(?![^(]*\))")
|
|
24
|
+
# This pattern ignores equal signs inside brackets
|
|
25
|
+
SPLIT_ON_EQUAL_PATTERN = re.compile(r"=(?![^(]*\))")
|
|
26
|
+
|
|
27
|
+
|
|
22
28
|
class _Patterns:
|
|
23
29
|
@cached_property
|
|
24
30
|
def more_than_one_alphanumeric(self) -> re.Pattern:
|
|
@@ -5,7 +5,14 @@ from typing import ClassVar, Literal, cast
|
|
|
5
5
|
from cognite.neat.issues.errors import WorkflowStepNotInitializedError
|
|
6
6
|
from cognite.neat.rules import exporters
|
|
7
7
|
from cognite.neat.rules._shared import DMSRules, InformationRules, VerifiedRules
|
|
8
|
-
from cognite.neat.rules.models import RoleTypes
|
|
8
|
+
from cognite.neat.rules.models import AssetRules, RoleTypes
|
|
9
|
+
from cognite.neat.rules.transformers import (
|
|
10
|
+
AssetToInformation,
|
|
11
|
+
DMSToInformation,
|
|
12
|
+
InformationToAsset,
|
|
13
|
+
InformationToDMS,
|
|
14
|
+
RulesPipeline,
|
|
15
|
+
)
|
|
9
16
|
from cognite.neat.workflows.model import FlowMessage, StepExecutionStatus
|
|
10
17
|
from cognite.neat.workflows.steps.data_contracts import CogniteClient, MultiRuleData
|
|
11
18
|
from cognite.neat.workflows.steps.step_model import Configurable, Step
|
|
@@ -75,26 +82,30 @@ class DeleteDataModelFromCDF(Step):
|
|
|
75
82
|
error_text="No DMS Schema components selected for removal! Please select minimum one!",
|
|
76
83
|
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
77
84
|
)
|
|
78
|
-
input_rules = rules.dms or rules.information
|
|
85
|
+
input_rules = rules.dms or rules.information or rules.asset
|
|
79
86
|
if input_rules is None:
|
|
80
87
|
return FlowMessage(
|
|
81
88
|
error_text="Missing DMS or Information rules in the input data! "
|
|
82
89
|
"Please ensure that a DMS or Information rules is provided!",
|
|
83
90
|
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
84
91
|
)
|
|
92
|
+
if isinstance(input_rules, DMSRules):
|
|
93
|
+
dms_rules = input_rules
|
|
94
|
+
elif isinstance(input_rules, InformationRules):
|
|
95
|
+
dms_rules = InformationToDMS().transform(input_rules).rules
|
|
96
|
+
elif isinstance(input_rules, AssetRules):
|
|
97
|
+
dms_rules = RulesPipeline[AssetRules, DMSRules]([AssetToInformation(), InformationToDMS()]).run(input_rules)
|
|
98
|
+
else:
|
|
99
|
+
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
85
100
|
|
|
86
101
|
dms_exporter = exporters.DMSExporter(
|
|
87
102
|
export_components=frozenset(components_to_delete),
|
|
88
|
-
include_space=(
|
|
89
|
-
None
|
|
90
|
-
if multi_space_components_delete
|
|
91
|
-
else {input_rules.metadata.space if isinstance(input_rules, DMSRules) else input_rules.metadata.prefix}
|
|
92
|
-
),
|
|
103
|
+
include_space=(None if multi_space_components_delete else {dms_rules.metadata.space}),
|
|
93
104
|
)
|
|
94
105
|
|
|
95
106
|
report_lines = ["# Data Model Deletion from CDF\n\n"]
|
|
96
107
|
errors = []
|
|
97
|
-
for result in dms_exporter.delete_from_cdf(rules=
|
|
108
|
+
for result in dms_exporter.delete_from_cdf(rules=dms_rules, client=cdf_client, dry_run=dry_run):
|
|
98
109
|
report_lines.append(str(result))
|
|
99
110
|
errors.extend(result.error_messages)
|
|
100
111
|
|
|
@@ -192,14 +203,18 @@ class RulesToDMS(Step):
|
|
|
192
203
|
"Please ensure that a DMS or Information rules is provided!",
|
|
193
204
|
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
194
205
|
)
|
|
206
|
+
if isinstance(input_rules, DMSRules):
|
|
207
|
+
dms_rules = input_rules
|
|
208
|
+
elif isinstance(input_rules, InformationRules):
|
|
209
|
+
dms_rules = InformationToDMS().transform(input_rules).rules
|
|
210
|
+
elif isinstance(input_rules, AssetRules):
|
|
211
|
+
dms_rules = RulesPipeline[AssetRules, DMSRules]([AssetToInformation(), InformationToDMS()]).run(input_rules)
|
|
212
|
+
else:
|
|
213
|
+
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
195
214
|
|
|
196
215
|
dms_exporter = exporters.DMSExporter(
|
|
197
216
|
export_components=frozenset(components_to_create),
|
|
198
|
-
include_space=(
|
|
199
|
-
None
|
|
200
|
-
if multi_space_components_create
|
|
201
|
-
else {input_rules.metadata.space if isinstance(input_rules, DMSRules) else input_rules.metadata.prefix}
|
|
202
|
-
),
|
|
217
|
+
include_space=(None if multi_space_components_create else {dms_rules.metadata.space}),
|
|
203
218
|
existing_handling=existing_components_handling,
|
|
204
219
|
)
|
|
205
220
|
|
|
@@ -212,11 +227,11 @@ class RulesToDMS(Step):
|
|
|
212
227
|
)
|
|
213
228
|
schema_zip = f"{file_name}.zip"
|
|
214
229
|
schema_full_path = output_dir / schema_zip
|
|
215
|
-
dms_exporter.export_to_file(
|
|
230
|
+
dms_exporter.export_to_file(dms_rules, schema_full_path)
|
|
216
231
|
|
|
217
232
|
report_lines = ["# DMS Schema Export to CDF\n\n"]
|
|
218
233
|
errors = []
|
|
219
|
-
for result in dms_exporter.export_to_cdf_iterable(rules=
|
|
234
|
+
for result in dms_exporter.export_to_cdf_iterable(rules=dms_rules, client=cdf_client, dry_run=dry_run):
|
|
220
235
|
report_lines.append(str(result))
|
|
221
236
|
errors.extend(result.error_messages)
|
|
222
237
|
|
|
@@ -296,7 +311,7 @@ class RulesToExcel(Step):
|
|
|
296
311
|
dump_format = self.configs.get("Dump Format", "user")
|
|
297
312
|
styling = cast(exporters.ExcelExporter.Style, self.configs.get("Styling", "default"))
|
|
298
313
|
role = self.configs.get("Output role format")
|
|
299
|
-
output_role = None
|
|
314
|
+
output_role: RoleTypes | None = None
|
|
300
315
|
if role != "input" and role is not None:
|
|
301
316
|
output_role = RoleTypes[role]
|
|
302
317
|
|
|
@@ -310,13 +325,9 @@ class RulesToExcel(Step):
|
|
|
310
325
|
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
311
326
|
)
|
|
312
327
|
|
|
313
|
-
excel_exporter = exporters.ExcelExporter(
|
|
314
|
-
styling=styling,
|
|
315
|
-
output_role=output_role,
|
|
316
|
-
dump_as=dump_format, # type: ignore[arg-type]
|
|
317
|
-
new_model_id=new_model_id,
|
|
318
|
-
)
|
|
328
|
+
excel_exporter = exporters.ExcelExporter(styling=styling, dump_as=dump_format, new_model_id=new_model_id) # type: ignore[arg-type]
|
|
319
329
|
|
|
330
|
+
# Todo - Move the conversion to a separate workflow step.
|
|
320
331
|
rule_instance: VerifiedRules
|
|
321
332
|
if rules.domain:
|
|
322
333
|
rule_instance = rules.domain
|
|
@@ -324,9 +335,42 @@ class RulesToExcel(Step):
|
|
|
324
335
|
rule_instance = rules.information
|
|
325
336
|
elif rules.dms:
|
|
326
337
|
rule_instance = rules.dms
|
|
338
|
+
elif rules.asset:
|
|
339
|
+
rule_instance = rules.asset
|
|
327
340
|
else:
|
|
328
341
|
output_errors = "No rules provided for export!"
|
|
329
342
|
return FlowMessage(error_text=output_errors, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
343
|
+
|
|
344
|
+
if rule_instance.metadata.role is output_role or output_role is None:
|
|
345
|
+
...
|
|
346
|
+
elif output_role is RoleTypes.dms:
|
|
347
|
+
if isinstance(rule_instance, InformationRules):
|
|
348
|
+
rule_instance = InformationToDMS().transform(rule_instance).rules
|
|
349
|
+
elif isinstance(rule_instance, AssetRules):
|
|
350
|
+
rule_instance = RulesPipeline[AssetRules, DMSRules]([AssetToInformation(), InformationToDMS()]).run(
|
|
351
|
+
rule_instance
|
|
352
|
+
)
|
|
353
|
+
else:
|
|
354
|
+
raise NotImplementedError(f"Role {output_role} is not supported for {type(rules).__name__} rules")
|
|
355
|
+
elif output_role is RoleTypes.information:
|
|
356
|
+
if isinstance(rule_instance, DMSRules):
|
|
357
|
+
rule_instance = DMSToInformation().transform(rule_instance).rules
|
|
358
|
+
elif isinstance(rule_instance, AssetRules):
|
|
359
|
+
rule_instance = AssetToInformation().transform(rule_instance).rules
|
|
360
|
+
else:
|
|
361
|
+
raise NotImplementedError(f"Role {output_role} is not supported for {type(rules).__name__} rules")
|
|
362
|
+
elif output_role is RoleTypes.asset:
|
|
363
|
+
if isinstance(rule_instance, InformationRules):
|
|
364
|
+
rule_instance = InformationToAsset().transform(rule_instance).rules
|
|
365
|
+
elif isinstance(rule_instance, DMSRules):
|
|
366
|
+
rule_instance = RulesPipeline[DMSRules, AssetRules]([DMSToInformation(), InformationToAsset()]).run(
|
|
367
|
+
rule_instance
|
|
368
|
+
)
|
|
369
|
+
else:
|
|
370
|
+
raise NotImplementedError(f"Role {output_role} is not supported for {type(rules).__name__} rules")
|
|
371
|
+
else:
|
|
372
|
+
raise NotImplementedError(f"Role {output_role} is not supported for {type(rules).__name__} rules")
|
|
373
|
+
|
|
330
374
|
if output_role is None:
|
|
331
375
|
output_role = rule_instance.metadata.role
|
|
332
376
|
output_dir = self.data_store_path / Path("staging")
|
|
@@ -384,8 +428,16 @@ class RulesToOntology(Step):
|
|
|
384
428
|
)
|
|
385
429
|
storage_path.parent.mkdir(parents=True, exist_ok=True)
|
|
386
430
|
|
|
431
|
+
input_rules = rules.information or rules.dms
|
|
432
|
+
if isinstance(input_rules, DMSRules):
|
|
433
|
+
info_rules = DMSToInformation().transform(input_rules).rules
|
|
434
|
+
elif isinstance(input_rules, InformationRules):
|
|
435
|
+
info_rules = input_rules
|
|
436
|
+
else:
|
|
437
|
+
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
438
|
+
|
|
387
439
|
exporter = exporters.OWLExporter()
|
|
388
|
-
exporter.export_to_file(
|
|
440
|
+
exporter.export_to_file(info_rules, storage_path)
|
|
389
441
|
|
|
390
442
|
relative_file_path = "/".join(storage_path.relative_to(self.data_store_path).parts)
|
|
391
443
|
|
|
@@ -435,8 +487,16 @@ class RulesToSHACL(Step):
|
|
|
435
487
|
)
|
|
436
488
|
storage_path.parent.mkdir(parents=True, exist_ok=True)
|
|
437
489
|
|
|
490
|
+
input_rules = rules.information or rules.dms
|
|
491
|
+
if isinstance(input_rules, DMSRules):
|
|
492
|
+
info_rules = DMSToInformation().transform(input_rules).rules
|
|
493
|
+
elif isinstance(input_rules, InformationRules):
|
|
494
|
+
info_rules = input_rules
|
|
495
|
+
else:
|
|
496
|
+
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
497
|
+
|
|
438
498
|
exporter = exporters.SHACLExporter()
|
|
439
|
-
exporter.export_to_file(
|
|
499
|
+
exporter.export_to_file(info_rules, storage_path)
|
|
440
500
|
|
|
441
501
|
relative_file_path = "/".join(storage_path.relative_to(self.data_store_path).parts)
|
|
442
502
|
|
|
@@ -485,9 +545,15 @@ class RulesToSemanticDataModel(Step):
|
|
|
485
545
|
self.data_store_path / Path(self.configs["File path"]) if self.configs["File path"] else default_path
|
|
486
546
|
)
|
|
487
547
|
storage_path.parent.mkdir(parents=True, exist_ok=True)
|
|
488
|
-
|
|
548
|
+
input_rules = rules.information or rules.dms
|
|
549
|
+
if isinstance(input_rules, DMSRules):
|
|
550
|
+
info_rules = DMSToInformation().transform(input_rules).rules
|
|
551
|
+
elif isinstance(input_rules, InformationRules):
|
|
552
|
+
info_rules = input_rules
|
|
553
|
+
else:
|
|
554
|
+
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
489
555
|
exporter = exporters.SemanticDataModelExporter()
|
|
490
|
-
exporter.export_to_file(
|
|
556
|
+
exporter.export_to_file(info_rules, storage_path)
|
|
491
557
|
|
|
492
558
|
relative_file_path = "/".join(storage_path.relative_to(self.data_store_path).parts)
|
|
493
559
|
|
|
@@ -534,28 +600,31 @@ class RulesToCDFTransformations(Step):
|
|
|
534
600
|
"Please ensure that a DMS or Information rules is provided!",
|
|
535
601
|
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
536
602
|
)
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
)
|
|
540
|
-
|
|
603
|
+
if isinstance(input_rules, DMSRules):
|
|
604
|
+
dms_rules = input_rules
|
|
605
|
+
elif isinstance(input_rules, InformationRules):
|
|
606
|
+
dms_rules = InformationToDMS().transform(input_rules).rules
|
|
607
|
+
elif isinstance(input_rules, AssetRules):
|
|
608
|
+
dms_rules = RulesPipeline[AssetRules, DMSRules]([AssetToInformation(), InformationToDMS()]).run(input_rules)
|
|
609
|
+
else:
|
|
610
|
+
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
611
|
+
|
|
612
|
+
instance_space = self.configs.get("Instance space") or dms_rules.metadata.space
|
|
541
613
|
dry_run = self.configs.get("Dry run", "False") == "True"
|
|
542
614
|
dms_exporter = exporters.DMSExporter(
|
|
543
615
|
export_pipeline=True, instance_space=instance_space, export_components=["spaces"]
|
|
544
616
|
)
|
|
545
617
|
output_dir = self.config.staging_path
|
|
546
618
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
547
|
-
file_name = (
|
|
548
|
-
input_rules.metadata.external_id
|
|
549
|
-
if isinstance(input_rules, DMSRules)
|
|
550
|
-
else input_rules.metadata.name.replace(" ", "_").lower()
|
|
551
|
-
)
|
|
619
|
+
file_name = dms_rules.metadata.external_id.replace(":", "_")
|
|
552
620
|
schema_zip = f"{file_name}_pipeline.zip"
|
|
553
621
|
schema_full_path = output_dir / schema_zip
|
|
554
|
-
|
|
622
|
+
|
|
623
|
+
dms_exporter.export_to_file(dms_rules, schema_full_path)
|
|
555
624
|
|
|
556
625
|
report_lines = ["# DMS Schema Export to CDF\n\n"]
|
|
557
626
|
errors = []
|
|
558
|
-
for result in dms_exporter.export_to_cdf_iterable(rules=
|
|
627
|
+
for result in dms_exporter.export_to_cdf_iterable(rules=dms_rules, client=cdf_client, dry_run=dry_run):
|
|
559
628
|
report_lines.append(str(result))
|
|
560
629
|
errors.extend(result.error_messages)
|
|
561
630
|
|
|
@@ -8,8 +8,10 @@ from cognite.client.data_classes.data_modeling import DataModelId
|
|
|
8
8
|
from cognite.neat.issues.errors import WorkflowStepNotInitializedError
|
|
9
9
|
from cognite.neat.issues.formatters import FORMATTER_BY_NAME
|
|
10
10
|
from cognite.neat.rules import importers
|
|
11
|
+
from cognite.neat.rules._shared import InputRules
|
|
11
12
|
from cognite.neat.rules.models import RoleTypes
|
|
12
13
|
from cognite.neat.rules.models.entities import DataModelEntity, DMSUnknownEntity
|
|
14
|
+
from cognite.neat.rules.transformers import ImporterPipeline
|
|
13
15
|
from cognite.neat.workflows.model import FlowMessage, StepExecutionStatus
|
|
14
16
|
from cognite.neat.workflows.steps.data_contracts import MultiRuleData
|
|
15
17
|
from cognite.neat.workflows.steps.step_model import Configurable, Step
|
|
@@ -70,17 +72,17 @@ class ExcelToRules(Step):
|
|
|
70
72
|
|
|
71
73
|
# if role is None, it will be inferred from the rules file
|
|
72
74
|
role = self.configs.get("Role")
|
|
73
|
-
role_enum = None
|
|
75
|
+
role_enum: RoleTypes | None = None
|
|
74
76
|
if role != "infer" and role is not None:
|
|
75
77
|
role_enum = RoleTypes[role]
|
|
76
78
|
|
|
77
|
-
excel_importer = importers.ExcelImporter(rules_file_path)
|
|
78
|
-
|
|
79
|
+
excel_importer = importers.ExcelImporter[InputRules](rules_file_path)
|
|
80
|
+
result = ImporterPipeline.try_verify(excel_importer, role_enum)
|
|
79
81
|
|
|
80
|
-
if rules is None:
|
|
82
|
+
if result.rules is None:
|
|
81
83
|
output_dir = self.config.staging_path
|
|
82
84
|
report_writer = FORMATTER_BY_NAME[self.configs["Report formatter"]]()
|
|
83
|
-
report_writer.write_to_file(issues, file_or_dir_path=output_dir)
|
|
85
|
+
report_writer.write_to_file(result.issues, file_or_dir_path=output_dir)
|
|
84
86
|
report_file = report_writer.default_file_name
|
|
85
87
|
error_text = (
|
|
86
88
|
"<p></p>"
|
|
@@ -91,7 +93,7 @@ class ExcelToRules(Step):
|
|
|
91
93
|
|
|
92
94
|
output_text = "Rules validation passed successfully!"
|
|
93
95
|
|
|
94
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(rules)
|
|
96
|
+
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result.rules)
|
|
95
97
|
|
|
96
98
|
|
|
97
99
|
class OntologyToRules(Step):
|
|
@@ -144,12 +146,12 @@ class OntologyToRules(Step):
|
|
|
144
146
|
role_enum = RoleTypes[role]
|
|
145
147
|
|
|
146
148
|
ontology_importer = importers.OWLImporter(filepath=rules_file_path)
|
|
147
|
-
|
|
149
|
+
result = ImporterPipeline.try_verify(ontology_importer, role_enum)
|
|
148
150
|
|
|
149
|
-
if rules is None:
|
|
151
|
+
if result.rules is None:
|
|
150
152
|
output_dir = self.config.staging_path
|
|
151
153
|
report_writer = FORMATTER_BY_NAME[self.configs["Report formatter"]]()
|
|
152
|
-
report_writer.write_to_file(issues, file_or_dir_path=output_dir)
|
|
154
|
+
report_writer.write_to_file(result.issues, file_or_dir_path=output_dir)
|
|
153
155
|
report_file = report_writer.default_file_name
|
|
154
156
|
error_text = (
|
|
155
157
|
"<p></p>"
|
|
@@ -160,7 +162,7 @@ class OntologyToRules(Step):
|
|
|
160
162
|
|
|
161
163
|
output_text = "Rules validation passed successfully!"
|
|
162
164
|
|
|
163
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(rules)
|
|
165
|
+
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result.rules)
|
|
164
166
|
|
|
165
167
|
|
|
166
168
|
class IMFToRules(Step):
|
|
@@ -215,12 +217,12 @@ class IMFToRules(Step):
|
|
|
215
217
|
role_enum = RoleTypes[role]
|
|
216
218
|
|
|
217
219
|
ontology_importer = importers.IMFImporter(filepath=rules_file_path)
|
|
218
|
-
|
|
220
|
+
result = ImporterPipeline.try_verify(ontology_importer, role_enum)
|
|
219
221
|
|
|
220
|
-
if rules is None:
|
|
222
|
+
if result.rules is None:
|
|
221
223
|
output_dir = self.config.staging_path
|
|
222
224
|
report_writer = FORMATTER_BY_NAME[self.configs["Report formatter"]]()
|
|
223
|
-
report_writer.write_to_file(issues, file_or_dir_path=output_dir)
|
|
225
|
+
report_writer.write_to_file(result.issues, file_or_dir_path=output_dir)
|
|
224
226
|
report_file = report_writer.default_file_name
|
|
225
227
|
error_text = (
|
|
226
228
|
"<p></p>"
|
|
@@ -231,7 +233,7 @@ class IMFToRules(Step):
|
|
|
231
233
|
|
|
232
234
|
output_text = "Rules validation passed successfully!"
|
|
233
235
|
|
|
234
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(rules)
|
|
236
|
+
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result.rules)
|
|
235
237
|
|
|
236
238
|
|
|
237
239
|
class DMSToRules(Step):
|
|
@@ -305,12 +307,12 @@ class DMSToRules(Step):
|
|
|
305
307
|
if role != "infer" and role is not None:
|
|
306
308
|
role_enum = RoleTypes[role]
|
|
307
309
|
|
|
308
|
-
|
|
310
|
+
result = ImporterPipeline.try_verify(dms_importer, role_enum)
|
|
309
311
|
|
|
310
|
-
if rules is None:
|
|
312
|
+
if result.rules is None:
|
|
311
313
|
output_dir = self.config.staging_path
|
|
312
314
|
report_writer = FORMATTER_BY_NAME[self.configs["Report formatter"]]()
|
|
313
|
-
report_writer.write_to_file(issues, file_or_dir_path=output_dir)
|
|
315
|
+
report_writer.write_to_file(result.issues, file_or_dir_path=output_dir)
|
|
314
316
|
report_file = report_writer.default_file_name
|
|
315
317
|
error_text = (
|
|
316
318
|
"<p></p>"
|
|
@@ -321,7 +323,7 @@ class DMSToRules(Step):
|
|
|
321
323
|
|
|
322
324
|
output_text = "Rules import and validation passed successfully!"
|
|
323
325
|
|
|
324
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(rules)
|
|
326
|
+
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result.rules)
|
|
325
327
|
|
|
326
328
|
|
|
327
329
|
class RulesInferenceFromRdfFile(Step):
|
|
@@ -388,12 +390,12 @@ class RulesInferenceFromRdfFile(Step):
|
|
|
388
390
|
inference_importer = importers.InferenceImporter.from_rdf_file(
|
|
389
391
|
rdf_file_path, max_number_of_instance=max_number_of_instance
|
|
390
392
|
)
|
|
391
|
-
|
|
393
|
+
result = ImporterPipeline.try_verify(inference_importer, role_enum)
|
|
392
394
|
|
|
393
|
-
if rules is None:
|
|
395
|
+
if result.rules is None:
|
|
394
396
|
output_dir = self.config.staging_path
|
|
395
397
|
report_writer = FORMATTER_BY_NAME[self.configs["Report formatter"]]()
|
|
396
|
-
report_writer.write_to_file(issues, file_or_dir_path=output_dir)
|
|
398
|
+
report_writer.write_to_file(result.issues, file_or_dir_path=output_dir)
|
|
397
399
|
report_file = report_writer.default_file_name
|
|
398
400
|
error_text = (
|
|
399
401
|
"<p></p>"
|
|
@@ -404,4 +406,4 @@ class RulesInferenceFromRdfFile(Step):
|
|
|
404
406
|
|
|
405
407
|
output_text = "Rules validation passed successfully!"
|
|
406
408
|
|
|
407
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(rules)
|
|
409
|
+
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result.rules)
|