cognite-neat 0.104.0__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 +1 -1
- cognite/neat/_graph/loaders/_rdf2dms.py +13 -2
- cognite/neat/_graph/transformers/__init__.py +3 -1
- cognite/neat/_graph/transformers/_classic_cdf.py +2 -1
- cognite/neat/_graph/transformers/_value_type.py +72 -0
- cognite/neat/_issues/__init__.py +0 -2
- cognite/neat/_issues/_base.py +19 -35
- cognite/neat/_issues/warnings/__init__.py +4 -1
- cognite/neat/_issues/warnings/_general.py +7 -0
- cognite/neat/_issues/warnings/_resources.py +11 -0
- cognite/neat/_rules/exporters/_rules2dms.py +35 -1
- cognite/neat/_rules/exporters/_rules2excel.py +2 -2
- cognite/neat/_rules/importers/_dms2rules.py +66 -55
- cognite/neat/_rules/models/_base_rules.py +4 -1
- cognite/neat/_rules/models/entities/_wrapped.py +10 -5
- cognite/neat/_rules/models/mapping/_classic2core.yaml +239 -38
- cognite/neat/_rules/transformers/__init__.py +8 -2
- cognite/neat/_rules/transformers/_converters.py +271 -188
- cognite/neat/_rules/transformers/_mapping.py +75 -59
- cognite/neat/_rules/transformers/_verification.py +2 -3
- cognite/neat/_session/_inspect.py +3 -1
- cognite/neat/_session/_prepare.py +112 -24
- cognite/neat/_session/_read.py +33 -70
- cognite/neat/_session/_state.py +2 -2
- cognite/neat/_session/_to.py +2 -2
- cognite/neat/_store/_rules_store.py +4 -8
- cognite/neat/_utils/reader/_base.py +27 -0
- cognite/neat/_version.py +1 -1
- {cognite_neat-0.104.0.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.104.0.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/_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 -323
- 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.104.0.dist-info/RECORD +0 -276
- {cognite_neat-0.104.0.dist-info → cognite_neat-0.105.0.dist-info}/LICENSE +0 -0
- {cognite_neat-0.104.0.dist-info → cognite_neat-0.105.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from typing import Any, ClassVar
|
|
3
|
-
|
|
4
|
-
from cognite.client import CogniteClient
|
|
5
|
-
|
|
6
|
-
from cognite.neat._client import NeatClient
|
|
7
|
-
from cognite.neat._issues.errors import WorkflowStepNotInitializedError
|
|
8
|
-
from cognite.neat._issues.formatters import FORMATTER_BY_NAME
|
|
9
|
-
from cognite.neat._rules import importers
|
|
10
|
-
from cognite.neat._rules.models import DMSRules, InformationRules, RoleTypes
|
|
11
|
-
from cognite.neat._rules.models.entities import DataModelEntity, DMSUnknownEntity
|
|
12
|
-
from cognite.neat._rules.transformers import DMSToInformation, InformationToDMS, VerifyAnyRules
|
|
13
|
-
from cognite.neat._workflows.model import FlowMessage, StepExecutionStatus
|
|
14
|
-
from cognite.neat._workflows.steps.data_contracts import MultiRuleData
|
|
15
|
-
from cognite.neat._workflows.steps.step_model import Configurable, Step
|
|
16
|
-
|
|
17
|
-
CATEGORY = __name__.split(".")[-1].replace("_", " ").title()
|
|
18
|
-
|
|
19
|
-
__all__ = [
|
|
20
|
-
"DMSToRules",
|
|
21
|
-
"ExcelToRules",
|
|
22
|
-
"IMFToRules",
|
|
23
|
-
"OntologyToRules",
|
|
24
|
-
"RulesInferenceFromRdfFile",
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class ExcelToRules(Step):
|
|
29
|
-
"""This step import rules from the Excel file and validates it."""
|
|
30
|
-
|
|
31
|
-
description = "This step imports rules from an excel file "
|
|
32
|
-
version = "private-beta"
|
|
33
|
-
category = CATEGORY
|
|
34
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
35
|
-
Configurable(
|
|
36
|
-
name="File name",
|
|
37
|
-
value="",
|
|
38
|
-
label="Full file name of the rules file in the rules folder. \
|
|
39
|
-
If not provided, step will attempt to get file name from payload \
|
|
40
|
-
of 'File Uploader' step (if exist)",
|
|
41
|
-
),
|
|
42
|
-
Configurable(
|
|
43
|
-
name="Report formatter",
|
|
44
|
-
value=next(iter(FORMATTER_BY_NAME.keys())),
|
|
45
|
-
label="The format of the report for the validation of the rules",
|
|
46
|
-
options=list(FORMATTER_BY_NAME),
|
|
47
|
-
),
|
|
48
|
-
Configurable(
|
|
49
|
-
name="Role",
|
|
50
|
-
value="infer",
|
|
51
|
-
label="For what role Rules are intended?",
|
|
52
|
-
options=["infer", *RoleTypes.__members__.keys()],
|
|
53
|
-
),
|
|
54
|
-
]
|
|
55
|
-
|
|
56
|
-
def run(self, flow_message: FlowMessage) -> (FlowMessage, MultiRuleData): # type: ignore[syntax, override]
|
|
57
|
-
if self.configs is None or self.data_store_path is None:
|
|
58
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
59
|
-
|
|
60
|
-
file_name = self.configs.get("File name", None)
|
|
61
|
-
full_path = flow_message.payload.get("full_path", None) if flow_message.payload else None
|
|
62
|
-
|
|
63
|
-
if file_name:
|
|
64
|
-
rules_file_path = Path(self.data_store_path) / "rules" / file_name
|
|
65
|
-
elif full_path:
|
|
66
|
-
rules_file_path = full_path
|
|
67
|
-
else:
|
|
68
|
-
error_text = "Expected either 'File name' in the step config or 'File uploader' step uploading Excel Rules."
|
|
69
|
-
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
70
|
-
|
|
71
|
-
# if role is None, it will be inferred from the rules file
|
|
72
|
-
role = self.configs.get("Role")
|
|
73
|
-
role_enum: RoleTypes | None = None
|
|
74
|
-
if role != "infer" and role is not None:
|
|
75
|
-
role_enum = RoleTypes[role]
|
|
76
|
-
|
|
77
|
-
excel_importer = importers.ExcelImporter(rules_file_path) # type: ignore[var-annotated]
|
|
78
|
-
read_rules = excel_importer.to_rules()
|
|
79
|
-
rules = VerifyAnyRules[Any]().transform(read_rules)
|
|
80
|
-
result: DMSRules | InformationRules
|
|
81
|
-
if role_enum is RoleTypes.dms and isinstance(rules, InformationRules):
|
|
82
|
-
result = InformationToDMS().transform(rules)
|
|
83
|
-
elif role_enum is RoleTypes.dms and isinstance(rules, DMSRules):
|
|
84
|
-
result = rules
|
|
85
|
-
elif role_enum is RoleTypes.information and isinstance(rules, InformationRules):
|
|
86
|
-
result = rules
|
|
87
|
-
elif role_enum is RoleTypes.information and isinstance(rules, DMSRules):
|
|
88
|
-
result = DMSToInformation().transform(rules)
|
|
89
|
-
else:
|
|
90
|
-
raise ValueError(f"Role {role_enum} is not supported for rules of type {type(rules)}")
|
|
91
|
-
|
|
92
|
-
output_text = "Rules validation passed successfully!"
|
|
93
|
-
|
|
94
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
class OntologyToRules(Step):
|
|
98
|
-
"""This step import rules from the ontology file (owl) and validates it."""
|
|
99
|
-
|
|
100
|
-
description = "This step imports rules from an ontology file "
|
|
101
|
-
version = "private-beta"
|
|
102
|
-
category = CATEGORY
|
|
103
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
104
|
-
Configurable(
|
|
105
|
-
name="File name",
|
|
106
|
-
value="",
|
|
107
|
-
label="Full file name of the ontology file in the rules folder. \
|
|
108
|
-
If not provided, step will attempt to get file name from payload \
|
|
109
|
-
of 'File Uploader' step (if exist)",
|
|
110
|
-
),
|
|
111
|
-
Configurable(
|
|
112
|
-
name="Report formatter",
|
|
113
|
-
value=next(iter(FORMATTER_BY_NAME.keys())),
|
|
114
|
-
label="The format of the report for the validation of the rules",
|
|
115
|
-
options=list(FORMATTER_BY_NAME),
|
|
116
|
-
),
|
|
117
|
-
Configurable(
|
|
118
|
-
name="Role",
|
|
119
|
-
value="infer",
|
|
120
|
-
label="For what role Rules are intended?",
|
|
121
|
-
options=["infer", *RoleTypes.__members__.keys()],
|
|
122
|
-
),
|
|
123
|
-
]
|
|
124
|
-
|
|
125
|
-
def run(self, flow_message: FlowMessage) -> (FlowMessage, MultiRuleData): # type: ignore[syntax, override]
|
|
126
|
-
if self.configs is None or self.data_store_path is None:
|
|
127
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
128
|
-
|
|
129
|
-
file_name = self.configs.get("File name", None)
|
|
130
|
-
full_path = flow_message.payload.get("full_path", None) if flow_message.payload else None
|
|
131
|
-
|
|
132
|
-
if file_name:
|
|
133
|
-
rules_file_path = self.config.rules_store_path / file_name
|
|
134
|
-
elif full_path:
|
|
135
|
-
rules_file_path = full_path
|
|
136
|
-
else:
|
|
137
|
-
error_text = "Expected either 'File name' in the step config or 'File uploader' step uploading Excel Rules."
|
|
138
|
-
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
139
|
-
|
|
140
|
-
ontology_importer = importers.OWLImporter.from_file(filepath=rules_file_path)
|
|
141
|
-
result = ontology_importer.to_rules().rules.as_verified_rules()
|
|
142
|
-
output_text = "Rules validation passed successfully!"
|
|
143
|
-
|
|
144
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result.rules)
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
class IMFToRules(Step):
|
|
148
|
-
"""This step import rules from the IMF-types and validates them."""
|
|
149
|
-
|
|
150
|
-
description = "This step imports rules from an RDF file "
|
|
151
|
-
version = "private-beta"
|
|
152
|
-
category = CATEGORY
|
|
153
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
154
|
-
Configurable(
|
|
155
|
-
name="File name",
|
|
156
|
-
value="",
|
|
157
|
-
label="""Full file name of the RDF-file containing the IMF-types in the rules folder.
|
|
158
|
-
If not provided, step will attempt to get file name from payload
|
|
159
|
-
of 'File Uploader' step (if exist)""",
|
|
160
|
-
),
|
|
161
|
-
Configurable(
|
|
162
|
-
name="Report formatter",
|
|
163
|
-
value=next(iter(FORMATTER_BY_NAME.keys())),
|
|
164
|
-
label="The format of the report for the validation of the rules",
|
|
165
|
-
options=list(FORMATTER_BY_NAME),
|
|
166
|
-
),
|
|
167
|
-
Configurable(
|
|
168
|
-
name="Role",
|
|
169
|
-
value="infer",
|
|
170
|
-
label="For what role Rules are intended?",
|
|
171
|
-
options=["infer", *RoleTypes.__members__.keys()],
|
|
172
|
-
),
|
|
173
|
-
]
|
|
174
|
-
|
|
175
|
-
def run(self, flow_message: FlowMessage) -> (FlowMessage, MultiRuleData): # type: ignore[syntax, override]
|
|
176
|
-
if self.configs is None or self.data_store_path is None:
|
|
177
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
178
|
-
|
|
179
|
-
file_name = self.configs.get("File name", None)
|
|
180
|
-
|
|
181
|
-
full_path = flow_message.payload.get("full_path", None) if flow_message.payload else None
|
|
182
|
-
|
|
183
|
-
if file_name:
|
|
184
|
-
rules_file_path = self.config.rules_store_path / file_name
|
|
185
|
-
|
|
186
|
-
elif full_path:
|
|
187
|
-
rules_file_path = full_path
|
|
188
|
-
else:
|
|
189
|
-
error_text = "Expected either 'File name' in the step config or 'File uploader' step uploading Excel Rules."
|
|
190
|
-
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
191
|
-
|
|
192
|
-
ontology_importer = importers.IMFImporter.from_file(rules_file_path)
|
|
193
|
-
result = ontology_importer.to_rules().rules.as_verified_rules()
|
|
194
|
-
|
|
195
|
-
output_text = "Rules validation passed successfully!"
|
|
196
|
-
|
|
197
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result.rules)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
class DMSToRules(Step):
|
|
201
|
-
"""This step imports rules from CDF Data Model"""
|
|
202
|
-
|
|
203
|
-
description = "This step imports rules from CDF Data Model"
|
|
204
|
-
version = "private-beta"
|
|
205
|
-
category = CATEGORY
|
|
206
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
207
|
-
Configurable(
|
|
208
|
-
name="Data model id",
|
|
209
|
-
value="",
|
|
210
|
-
label="The ID of the Data Model to import. Written at 'my_space:my_data_model(version=1)'",
|
|
211
|
-
type="string",
|
|
212
|
-
required=True,
|
|
213
|
-
),
|
|
214
|
-
Configurable(
|
|
215
|
-
name="Reference data model id",
|
|
216
|
-
value="",
|
|
217
|
-
label="The ID of the Reference Data Model to import. Written at 'my_space:my_data_model(version=1)'. "
|
|
218
|
-
"This is typically an enterprise data model when you want to import a solution model",
|
|
219
|
-
type="string",
|
|
220
|
-
),
|
|
221
|
-
Configurable(
|
|
222
|
-
name="Report formatter",
|
|
223
|
-
value=next(iter(FORMATTER_BY_NAME.keys())),
|
|
224
|
-
label="The format of the report for the validation of the rules",
|
|
225
|
-
options=list(FORMATTER_BY_NAME),
|
|
226
|
-
),
|
|
227
|
-
Configurable(
|
|
228
|
-
name="Role",
|
|
229
|
-
value="infer",
|
|
230
|
-
label="For what role Rules are intended?",
|
|
231
|
-
options=["infer", *RoleTypes.__members__.keys()],
|
|
232
|
-
),
|
|
233
|
-
]
|
|
234
|
-
|
|
235
|
-
def run(self, cdf_client: CogniteClient) -> (FlowMessage, MultiRuleData): # type: ignore[syntax, override]
|
|
236
|
-
if self.configs is None or self.data_store_path is None:
|
|
237
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
238
|
-
|
|
239
|
-
datamodel_id_str = self.configs.get("Data model id")
|
|
240
|
-
if datamodel_id_str is None:
|
|
241
|
-
error_text = "Expected input payload to contain 'Data model id' key."
|
|
242
|
-
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
243
|
-
|
|
244
|
-
datamodel_entity = DataModelEntity.load(datamodel_id_str)
|
|
245
|
-
if isinstance(datamodel_entity, DMSUnknownEntity):
|
|
246
|
-
error_text = (
|
|
247
|
-
f"Data model id should be in the format 'my_space:my_data_model(version=1)' "
|
|
248
|
-
f"or 'my_space:my_data_model', failed to parse space from {datamodel_id_str}"
|
|
249
|
-
)
|
|
250
|
-
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
251
|
-
|
|
252
|
-
dms_importer = importers.DMSImporter.from_data_model_id(NeatClient(cdf_client), datamodel_entity.as_id())
|
|
253
|
-
|
|
254
|
-
result = dms_importer.to_rules().rules.as_verified_rules() # type: ignore[union-attr]
|
|
255
|
-
|
|
256
|
-
output_text = "Rules import and validation passed successfully!"
|
|
257
|
-
|
|
258
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
class RulesInferenceFromRdfFile(Step):
|
|
262
|
-
"""This step infers rules from the RDF file which contains knowledge graph."""
|
|
263
|
-
|
|
264
|
-
description = "This step infers rules from the RDF file which contains knowledge graph"
|
|
265
|
-
version = "private-beta"
|
|
266
|
-
category = CATEGORY
|
|
267
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
268
|
-
Configurable(
|
|
269
|
-
name="File path",
|
|
270
|
-
value="staging/knowledge_graph.ttl",
|
|
271
|
-
label=("Relative path to the RDF file to be used for inference"),
|
|
272
|
-
),
|
|
273
|
-
Configurable(
|
|
274
|
-
name="Report formatter",
|
|
275
|
-
value=next(iter(FORMATTER_BY_NAME.keys())),
|
|
276
|
-
label="The format of the report for the validation of the rules",
|
|
277
|
-
options=list(FORMATTER_BY_NAME),
|
|
278
|
-
),
|
|
279
|
-
Configurable(
|
|
280
|
-
name="Role",
|
|
281
|
-
value="infer",
|
|
282
|
-
label="For what role Rules are intended?",
|
|
283
|
-
options=["infer", *RoleTypes.__members__.keys()],
|
|
284
|
-
),
|
|
285
|
-
Configurable(
|
|
286
|
-
name="Maximum number of instances to process",
|
|
287
|
-
value="-1",
|
|
288
|
-
label=(
|
|
289
|
-
"Maximum number of instances to process"
|
|
290
|
-
" to infer rules from the RDF file. Default -1 means all instances."
|
|
291
|
-
),
|
|
292
|
-
),
|
|
293
|
-
]
|
|
294
|
-
|
|
295
|
-
def run(self, flow_message: FlowMessage) -> (FlowMessage, MultiRuleData): # type: ignore[syntax, override]
|
|
296
|
-
if self.configs is None or self.data_store_path is None:
|
|
297
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
298
|
-
|
|
299
|
-
file_path = self.configs.get("File path", None)
|
|
300
|
-
full_path = flow_message.payload.get("full_path", None) if flow_message.payload else None
|
|
301
|
-
|
|
302
|
-
try:
|
|
303
|
-
max_number_of_instance = int(self.configs.get("Maximum number of instances to process", -1))
|
|
304
|
-
except ValueError:
|
|
305
|
-
error_text = "Maximum number of instances to process should be an integer value"
|
|
306
|
-
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
307
|
-
|
|
308
|
-
if file_path:
|
|
309
|
-
rdf_file_path = self.data_store_path / Path(file_path)
|
|
310
|
-
elif full_path:
|
|
311
|
-
rdf_file_path = full_path
|
|
312
|
-
else:
|
|
313
|
-
error_text = "Expected either 'File name' in the step config or 'File uploader' step uploading Excel Rules."
|
|
314
|
-
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
315
|
-
|
|
316
|
-
inference_importer = importers.InferenceImporter.from_file(
|
|
317
|
-
rdf_file_path, max_number_of_instance=max_number_of_instance
|
|
318
|
-
)
|
|
319
|
-
result = inference_importer.to_rules().rules.as_verified_rules() # type: ignore[union-attr]
|
|
320
|
-
|
|
321
|
-
output_text = "Rules validation passed successfully!"
|
|
322
|
-
|
|
323
|
-
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(result)
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import time
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import ClassVar
|
|
5
|
-
|
|
6
|
-
from cognite.client import CogniteClient
|
|
7
|
-
|
|
8
|
-
from cognite.neat._client import NeatClient
|
|
9
|
-
from cognite.neat._client._api.data_modeling_loaders import ViewLoader
|
|
10
|
-
from cognite.neat._issues import NeatIssueList
|
|
11
|
-
from cognite.neat._issues.errors import ResourceNotFoundError, WorkflowStepNotInitializedError
|
|
12
|
-
from cognite.neat._issues.formatters import FORMATTER_BY_NAME
|
|
13
|
-
from cognite.neat._rules.models import DMSRules
|
|
14
|
-
from cognite.neat._rules.models.dms import DMSValidation
|
|
15
|
-
from cognite.neat._workflows.model import FlowMessage, StepExecutionStatus
|
|
16
|
-
from cognite.neat._workflows.steps.data_contracts import MultiRuleData
|
|
17
|
-
from cognite.neat._workflows.steps.step_model import Configurable, Step
|
|
18
|
-
|
|
19
|
-
CATEGORY = __name__.split(".")[-1].replace("_", " ").title()
|
|
20
|
-
|
|
21
|
-
__all__ = [
|
|
22
|
-
"ValidateRulesAgainstCDF",
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class ValidateRulesAgainstCDF(Step):
|
|
27
|
-
"""This steps downloads views and containers from CDF and validates the rules against them
|
|
28
|
-
|
|
29
|
-
Note that this only applies to DMSRules
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
description = "This steps downloads views and containers from CDF and validates the rules against them."
|
|
33
|
-
category = CATEGORY
|
|
34
|
-
version = "private-beta"
|
|
35
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
36
|
-
Configurable(
|
|
37
|
-
name="Report Formatter",
|
|
38
|
-
value=next(iter(FORMATTER_BY_NAME.keys())),
|
|
39
|
-
label="The format of the report for the validation of the rules",
|
|
40
|
-
options=list(FORMATTER_BY_NAME),
|
|
41
|
-
),
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
def run(self, rules: MultiRuleData, cdf_client: CogniteClient) -> FlowMessage: # type: ignore[override, syntax]
|
|
45
|
-
if self.configs is None or self.data_store_path is None:
|
|
46
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
47
|
-
|
|
48
|
-
if not isinstance(rules.dms, DMSRules):
|
|
49
|
-
return FlowMessage(
|
|
50
|
-
error_text="DMS rules are missing. This step requires DMS rules to be present.",
|
|
51
|
-
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
52
|
-
)
|
|
53
|
-
dms_rules = rules.dms
|
|
54
|
-
|
|
55
|
-
errors = DMSValidation(dms_rules, NeatClient(cdf_client)).validate()
|
|
56
|
-
|
|
57
|
-
missing_spaces = [
|
|
58
|
-
error.identifier
|
|
59
|
-
for error in errors
|
|
60
|
-
if isinstance(error, ResourceNotFoundError) and error.resource_type == "Space"
|
|
61
|
-
]
|
|
62
|
-
missing_views = [
|
|
63
|
-
error.identifier
|
|
64
|
-
for error in errors
|
|
65
|
-
if isinstance(error, ResourceNotFoundError) and error.resource_type == "View"
|
|
66
|
-
]
|
|
67
|
-
missing_containers = [
|
|
68
|
-
error.identifier
|
|
69
|
-
for error in errors
|
|
70
|
-
if isinstance(error, ResourceNotFoundError) and error.resource_type == "Container"
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
retrieved_spaces = cdf_client.data_modeling.spaces.retrieve(missing_spaces).as_write()
|
|
74
|
-
retrieved_containers = cdf_client.data_modeling.containers.retrieve(missing_containers).as_write()
|
|
75
|
-
# Converting read format of views to write format requires to account for parents (implements)
|
|
76
|
-
# Thus we use the loader to convert the views to write format.
|
|
77
|
-
view_loader = ViewLoader(NeatClient(cdf_client))
|
|
78
|
-
retrieved_views = [
|
|
79
|
-
view_loader.as_write(view) for view in cdf_client.data_modeling.views.retrieve(missing_views)
|
|
80
|
-
]
|
|
81
|
-
logging.info(
|
|
82
|
-
f"Retrieved {len(retrieved_spaces)} spaces, {len(retrieved_containers)} containers, "
|
|
83
|
-
f"and {len(retrieved_views)} views from CDF."
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
schema = dms_rules.as_schema()
|
|
87
|
-
schema.spaces.update({space.space: space for space in retrieved_spaces})
|
|
88
|
-
schema.containers.update({container.as_id(): container for container in retrieved_containers})
|
|
89
|
-
schema.views.update({view.as_id(): view for view in retrieved_views})
|
|
90
|
-
|
|
91
|
-
if errors:
|
|
92
|
-
output_dir = self.data_store_path / Path("staging")
|
|
93
|
-
report_writer = FORMATTER_BY_NAME[self.configs["Report Formatter"]]()
|
|
94
|
-
report_writer.write_to_file(
|
|
95
|
-
NeatIssueList(errors, title=dms_rules.metadata.name or dms_rules.metadata.external_id),
|
|
96
|
-
file_or_dir_path=output_dir,
|
|
97
|
-
)
|
|
98
|
-
report_file = report_writer.default_file_name
|
|
99
|
-
error_text = (
|
|
100
|
-
"<p></p>"
|
|
101
|
-
f'<a href="/data/staging/{report_file}?{time.time()}" '
|
|
102
|
-
f'target="_blank">The rules failed validation against CDF, click here for report</a>'
|
|
103
|
-
)
|
|
104
|
-
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
105
|
-
|
|
106
|
-
return FlowMessage(output_text="Rules validated successfully against CDF")
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .io_steps import * # noqa
|