cognite-neat 0.104.0__py3-none-any.whl → 0.105.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cognite-neat might be problematic. Click here for more details.

Files changed (143) hide show
  1. cognite/neat/_client/_api/data_modeling_loaders.py +83 -23
  2. cognite/neat/_client/_api/schema.py +2 -1
  3. cognite/neat/_client/data_classes/neat_sequence.py +261 -0
  4. cognite/neat/_client/data_classes/schema.py +5 -1
  5. cognite/neat/_client/testing.py +33 -0
  6. cognite/neat/_constants.py +57 -0
  7. cognite/neat/_graph/extractors/_classic_cdf/_base.py +6 -5
  8. cognite/neat/_graph/extractors/_classic_cdf/_sequences.py +225 -11
  9. cognite/neat/_graph/extractors/_mock_graph_generator.py +1 -1
  10. cognite/neat/_graph/loaders/_rdf2dms.py +31 -5
  11. cognite/neat/_graph/transformers/__init__.py +3 -1
  12. cognite/neat/_graph/transformers/_classic_cdf.py +39 -51
  13. cognite/neat/_graph/transformers/_rdfpath.py +14 -15
  14. cognite/neat/_graph/transformers/_value_type.py +72 -0
  15. cognite/neat/_issues/__init__.py +0 -2
  16. cognite/neat/_issues/_base.py +19 -35
  17. cognite/neat/_issues/warnings/__init__.py +6 -1
  18. cognite/neat/_issues/warnings/_general.py +7 -0
  19. cognite/neat/_issues/warnings/_properties.py +11 -0
  20. cognite/neat/_issues/warnings/_resources.py +11 -0
  21. cognite/neat/_rules/exporters/_rules2dms.py +35 -1
  22. cognite/neat/_rules/exporters/_rules2excel.py +2 -2
  23. cognite/neat/_rules/importers/_dms2rules.py +66 -55
  24. cognite/neat/_rules/models/_base_rules.py +4 -1
  25. cognite/neat/_rules/models/entities/_wrapped.py +10 -5
  26. cognite/neat/_rules/models/mapping/_classic2core.yaml +239 -38
  27. cognite/neat/_rules/transformers/__init__.py +8 -2
  28. cognite/neat/_rules/transformers/_converters.py +271 -188
  29. cognite/neat/_rules/transformers/_mapping.py +75 -59
  30. cognite/neat/_rules/transformers/_verification.py +2 -3
  31. cognite/neat/_session/_inspect.py +3 -1
  32. cognite/neat/_session/_prepare.py +112 -24
  33. cognite/neat/_session/_read.py +33 -70
  34. cognite/neat/_session/_state.py +2 -2
  35. cognite/neat/_session/_to.py +2 -2
  36. cognite/neat/_store/_rules_store.py +4 -8
  37. cognite/neat/_utils/reader/_base.py +27 -0
  38. cognite/neat/_version.py +1 -1
  39. {cognite_neat-0.104.0.dist-info → cognite_neat-0.105.1.dist-info}/METADATA +4 -3
  40. cognite_neat-0.105.1.dist-info/RECORD +179 -0
  41. {cognite_neat-0.104.0.dist-info → cognite_neat-0.105.1.dist-info}/WHEEL +1 -1
  42. cognite/neat/_app/api/__init__.py +0 -0
  43. cognite/neat/_app/api/asgi/metrics.py +0 -4
  44. cognite/neat/_app/api/configuration.py +0 -98
  45. cognite/neat/_app/api/context_manager/__init__.py +0 -3
  46. cognite/neat/_app/api/context_manager/manager.py +0 -16
  47. cognite/neat/_app/api/data_classes/__init__.py +0 -0
  48. cognite/neat/_app/api/data_classes/rest.py +0 -59
  49. cognite/neat/_app/api/explorer.py +0 -66
  50. cognite/neat/_app/api/routers/configuration.py +0 -25
  51. cognite/neat/_app/api/routers/crud.py +0 -102
  52. cognite/neat/_app/api/routers/metrics.py +0 -10
  53. cognite/neat/_app/api/routers/workflows.py +0 -224
  54. cognite/neat/_app/api/utils/__init__.py +0 -0
  55. cognite/neat/_app/api/utils/data_mapping.py +0 -17
  56. cognite/neat/_app/api/utils/logging.py +0 -26
  57. cognite/neat/_app/api/utils/query_templates.py +0 -92
  58. cognite/neat/_app/main.py +0 -17
  59. cognite/neat/_app/monitoring/__init__.py +0 -0
  60. cognite/neat/_app/monitoring/metrics.py +0 -69
  61. cognite/neat/_app/ui/index.html +0 -1
  62. cognite/neat/_app/ui/neat-app/.gitignore +0 -23
  63. cognite/neat/_app/ui/neat-app/README.md +0 -70
  64. cognite/neat/_app/ui/neat-app/build/asset-manifest.json +0 -14
  65. cognite/neat/_app/ui/neat-app/build/favicon.ico +0 -0
  66. cognite/neat/_app/ui/neat-app/build/img/architect-icon.svg +0 -116
  67. cognite/neat/_app/ui/neat-app/build/img/developer-icon.svg +0 -112
  68. cognite/neat/_app/ui/neat-app/build/img/sme-icon.svg +0 -34
  69. cognite/neat/_app/ui/neat-app/build/index.html +0 -1
  70. cognite/neat/_app/ui/neat-app/build/logo192.png +0 -0
  71. cognite/neat/_app/ui/neat-app/build/manifest.json +0 -25
  72. cognite/neat/_app/ui/neat-app/build/robots.txt +0 -3
  73. cognite/neat/_app/ui/neat-app/build/static/css/main.72e3d92e.css +0 -2
  74. cognite/neat/_app/ui/neat-app/build/static/css/main.72e3d92e.css.map +0 -1
  75. cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js +0 -3
  76. cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js.LICENSE.txt +0 -88
  77. cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js.map +0 -1
  78. cognite/neat/_app/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -1
  79. cognite/neat/_app/ui/neat-app/package-lock.json +0 -18306
  80. cognite/neat/_app/ui/neat-app/package.json +0 -62
  81. cognite/neat/_app/ui/neat-app/public/favicon.ico +0 -0
  82. cognite/neat/_app/ui/neat-app/public/img/architect-icon.svg +0 -116
  83. cognite/neat/_app/ui/neat-app/public/img/developer-icon.svg +0 -112
  84. cognite/neat/_app/ui/neat-app/public/img/sme-icon.svg +0 -34
  85. cognite/neat/_app/ui/neat-app/public/index.html +0 -43
  86. cognite/neat/_app/ui/neat-app/public/logo192.png +0 -0
  87. cognite/neat/_app/ui/neat-app/public/manifest.json +0 -25
  88. cognite/neat/_app/ui/neat-app/public/robots.txt +0 -3
  89. cognite/neat/_app/ui/neat-app/src/App.css +0 -38
  90. cognite/neat/_app/ui/neat-app/src/App.js +0 -17
  91. cognite/neat/_app/ui/neat-app/src/App.test.js +0 -8
  92. cognite/neat/_app/ui/neat-app/src/MainContainer.tsx +0 -70
  93. cognite/neat/_app/ui/neat-app/src/components/JsonViewer.tsx +0 -43
  94. cognite/neat/_app/ui/neat-app/src/components/LocalUploader.tsx +0 -124
  95. cognite/neat/_app/ui/neat-app/src/components/OverviewComponentEditorDialog.tsx +0 -63
  96. cognite/neat/_app/ui/neat-app/src/components/StepEditorDialog.tsx +0 -511
  97. cognite/neat/_app/ui/neat-app/src/components/TabPanel.tsx +0 -36
  98. cognite/neat/_app/ui/neat-app/src/components/Utils.tsx +0 -56
  99. cognite/neat/_app/ui/neat-app/src/components/WorkflowDeleteDialog.tsx +0 -60
  100. cognite/neat/_app/ui/neat-app/src/components/WorkflowExecutionReport.tsx +0 -112
  101. cognite/neat/_app/ui/neat-app/src/components/WorkflowImportExportDialog.tsx +0 -67
  102. cognite/neat/_app/ui/neat-app/src/components/WorkflowMetadataDialog.tsx +0 -79
  103. cognite/neat/_app/ui/neat-app/src/index.css +0 -13
  104. cognite/neat/_app/ui/neat-app/src/index.js +0 -13
  105. cognite/neat/_app/ui/neat-app/src/logo.svg +0 -1
  106. cognite/neat/_app/ui/neat-app/src/reportWebVitals.js +0 -13
  107. cognite/neat/_app/ui/neat-app/src/setupTests.js +0 -5
  108. cognite/neat/_app/ui/neat-app/src/types/WorkflowTypes.ts +0 -388
  109. cognite/neat/_app/ui/neat-app/src/views/AboutView.tsx +0 -61
  110. cognite/neat/_app/ui/neat-app/src/views/ConfigView.tsx +0 -184
  111. cognite/neat/_app/ui/neat-app/src/views/GlobalConfigView.tsx +0 -180
  112. cognite/neat/_app/ui/neat-app/src/views/WorkflowView.tsx +0 -570
  113. cognite/neat/_app/ui/neat-app/tsconfig.json +0 -27
  114. cognite/neat/_workflows/__init__.py +0 -17
  115. cognite/neat/_workflows/base.py +0 -590
  116. cognite/neat/_workflows/cdf_store.py +0 -393
  117. cognite/neat/_workflows/examples/Export_DMS/workflow.yaml +0 -89
  118. cognite/neat/_workflows/examples/Export_Semantic_Data_Model/workflow.yaml +0 -66
  119. cognite/neat/_workflows/examples/Import_DMS/workflow.yaml +0 -65
  120. cognite/neat/_workflows/examples/Validate_Rules/workflow.yaml +0 -67
  121. cognite/neat/_workflows/examples/Validate_Solution_Model/workflow.yaml +0 -64
  122. cognite/neat/_workflows/manager.py +0 -292
  123. cognite/neat/_workflows/model.py +0 -203
  124. cognite/neat/_workflows/steps/__init__.py +0 -0
  125. cognite/neat/_workflows/steps/data_contracts.py +0 -109
  126. cognite/neat/_workflows/steps/lib/__init__.py +0 -0
  127. cognite/neat/_workflows/steps/lib/current/__init__.py +0 -6
  128. cognite/neat/_workflows/steps/lib/current/graph_extractor.py +0 -100
  129. cognite/neat/_workflows/steps/lib/current/graph_loader.py +0 -51
  130. cognite/neat/_workflows/steps/lib/current/graph_store.py +0 -48
  131. cognite/neat/_workflows/steps/lib/current/rules_exporter.py +0 -537
  132. cognite/neat/_workflows/steps/lib/current/rules_importer.py +0 -323
  133. cognite/neat/_workflows/steps/lib/current/rules_validator.py +0 -106
  134. cognite/neat/_workflows/steps/lib/io/__init__.py +0 -1
  135. cognite/neat/_workflows/steps/lib/io/io_steps.py +0 -393
  136. cognite/neat/_workflows/steps/step_model.py +0 -79
  137. cognite/neat/_workflows/steps_registry.py +0 -218
  138. cognite/neat/_workflows/tasks.py +0 -18
  139. cognite/neat/_workflows/triggers.py +0 -169
  140. cognite/neat/_workflows/utils.py +0 -19
  141. cognite_neat-0.104.0.dist-info/RECORD +0 -276
  142. {cognite_neat-0.104.0.dist-info → cognite_neat-0.105.1.dist-info}/LICENSE +0 -0
  143. {cognite_neat-0.104.0.dist-info → cognite_neat-0.105.1.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