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,537 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import ClassVar, Literal, cast
|
|
4
|
-
|
|
5
|
-
from cognite.neat._client import NeatClient
|
|
6
|
-
from cognite.neat._issues.errors import WorkflowStepNotInitializedError
|
|
7
|
-
from cognite.neat._rules import exporters
|
|
8
|
-
from cognite.neat._rules._shared import DMSRules, InformationRules, VerifiedRules
|
|
9
|
-
from cognite.neat._rules.models import RoleTypes
|
|
10
|
-
from cognite.neat._rules.transformers import (
|
|
11
|
-
DMSToInformation,
|
|
12
|
-
InformationToDMS,
|
|
13
|
-
)
|
|
14
|
-
from cognite.neat._workflows.model import FlowMessage, StepExecutionStatus
|
|
15
|
-
from cognite.neat._workflows.steps.data_contracts import CogniteClient, MultiRuleData
|
|
16
|
-
from cognite.neat._workflows.steps.step_model import Configurable, Step
|
|
17
|
-
|
|
18
|
-
__all__ = [
|
|
19
|
-
"DeleteDataModelFromCDF",
|
|
20
|
-
"RulesToDMS",
|
|
21
|
-
"RulesToExcel",
|
|
22
|
-
"RulesToOntology",
|
|
23
|
-
"RulesToSHACL",
|
|
24
|
-
"RulesToSemanticDataModel",
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
CATEGORY = __name__.split(".")[-1].replace("_", " ").title()
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class DeleteDataModelFromCDF(Step):
|
|
32
|
-
"""
|
|
33
|
-
This step deletes data model and its components from CDF
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
description = "This step deletes data model and its components from CDF."
|
|
37
|
-
version = "private-beta"
|
|
38
|
-
category = CATEGORY
|
|
39
|
-
|
|
40
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
41
|
-
Configurable(
|
|
42
|
-
name="Dry run",
|
|
43
|
-
value="False",
|
|
44
|
-
label=("Whether to perform a dry run of the deleter. "),
|
|
45
|
-
options=["True", "False"],
|
|
46
|
-
),
|
|
47
|
-
Configurable(
|
|
48
|
-
name="Components",
|
|
49
|
-
type="multi_select",
|
|
50
|
-
value="",
|
|
51
|
-
label="Select which DMS schema component(s) to be deleted from CDF",
|
|
52
|
-
options=["spaces", "containers", "views", "data_models"],
|
|
53
|
-
),
|
|
54
|
-
Configurable(
|
|
55
|
-
name="Multi-space components deletion",
|
|
56
|
-
value="False",
|
|
57
|
-
label=(
|
|
58
|
-
"Whether to delete only components belonging to the data model space"
|
|
59
|
-
" (i.e. space define under Metadata sheet of Rules), "
|
|
60
|
-
"or also additionally delete components outside of the data model space."
|
|
61
|
-
),
|
|
62
|
-
options=["True", "False"],
|
|
63
|
-
),
|
|
64
|
-
]
|
|
65
|
-
|
|
66
|
-
def run(self, rules: MultiRuleData, cdf_client: CogniteClient) -> FlowMessage: # type: ignore[override]
|
|
67
|
-
if self.configs is None or self.data_store_path is None:
|
|
68
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
69
|
-
components_to_delete = {
|
|
70
|
-
cast(Literal["spaces", "data_models", "views", "containers"], key)
|
|
71
|
-
for key, value in self.complex_configs["Components"].items()
|
|
72
|
-
if value
|
|
73
|
-
}
|
|
74
|
-
dry_run = self.configs["Dry run"] == "True"
|
|
75
|
-
multi_space_components_delete: bool = self.configs["Multi-space components deletion"] == "True"
|
|
76
|
-
|
|
77
|
-
if not components_to_delete:
|
|
78
|
-
return FlowMessage(
|
|
79
|
-
error_text="No DMS Schema components selected for removal! Please select minimum one!",
|
|
80
|
-
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
81
|
-
)
|
|
82
|
-
input_rules = rules.dms or rules.information
|
|
83
|
-
if input_rules is None:
|
|
84
|
-
return FlowMessage(
|
|
85
|
-
error_text="Missing DMS or Information rules in the input data! "
|
|
86
|
-
"Please ensure that a DMS or Information rules is provided!",
|
|
87
|
-
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
88
|
-
)
|
|
89
|
-
if isinstance(input_rules, DMSRules):
|
|
90
|
-
dms_rules = input_rules
|
|
91
|
-
elif isinstance(input_rules, InformationRules):
|
|
92
|
-
dms_rules = InformationToDMS().transform(input_rules)
|
|
93
|
-
else:
|
|
94
|
-
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
95
|
-
|
|
96
|
-
dms_exporter = exporters.DMSExporter(
|
|
97
|
-
export_components=frozenset(components_to_delete),
|
|
98
|
-
include_space=(None if multi_space_components_delete else {dms_rules.metadata.space}),
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
report_lines = ["# Data Model Deletion from CDF\n\n"]
|
|
102
|
-
errors = []
|
|
103
|
-
for result in dms_exporter.delete_from_cdf(rules=dms_rules, client=NeatClient(cdf_client), dry_run=dry_run):
|
|
104
|
-
report_lines.append(str(result))
|
|
105
|
-
errors.extend(result.error_messages)
|
|
106
|
-
|
|
107
|
-
report_lines.append("\n\n# ERRORS\n\n")
|
|
108
|
-
report_lines.extend(errors)
|
|
109
|
-
|
|
110
|
-
output_dir = self.config.staging_path
|
|
111
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
112
|
-
report_file = "dms_component_creation_report.txt"
|
|
113
|
-
report_full_path = output_dir / report_file
|
|
114
|
-
report_full_path.write_text("\n".join(report_lines))
|
|
115
|
-
|
|
116
|
-
output_text = (
|
|
117
|
-
"<p></p>"
|
|
118
|
-
"Download Data Model Deletion "
|
|
119
|
-
f'<a href="/data/staging/{report_file}?{time.time()}" '
|
|
120
|
-
f'target="_blank">Report</a>'
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
if errors:
|
|
124
|
-
return FlowMessage(error_text=output_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
125
|
-
else:
|
|
126
|
-
return FlowMessage(output_text=output_text)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
class RulesToDMS(Step):
|
|
130
|
-
"""
|
|
131
|
-
This step exports Rules to DMS Schema components in CDF
|
|
132
|
-
"""
|
|
133
|
-
|
|
134
|
-
description = "This step exports Rules to DMS Schema components in CDF."
|
|
135
|
-
version = "private-beta"
|
|
136
|
-
category = CATEGORY
|
|
137
|
-
|
|
138
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
139
|
-
Configurable(
|
|
140
|
-
name="Dry run",
|
|
141
|
-
value="False",
|
|
142
|
-
label=("Whether to perform a dry run of the export. "),
|
|
143
|
-
options=["True", "False"],
|
|
144
|
-
),
|
|
145
|
-
Configurable(
|
|
146
|
-
name="Components",
|
|
147
|
-
type="multi_select",
|
|
148
|
-
value="",
|
|
149
|
-
label="Select which DMS schema component(s) to export to CDF",
|
|
150
|
-
options=["spaces", "containers", "views", "data_models"],
|
|
151
|
-
),
|
|
152
|
-
Configurable(
|
|
153
|
-
name="Existing component handling",
|
|
154
|
-
value="fail",
|
|
155
|
-
label=(
|
|
156
|
-
"How to handle situation when components being exported in CDF already exist."
|
|
157
|
-
"Fail the step if any component already exists, "
|
|
158
|
-
"Skip the component if it already exists, "
|
|
159
|
-
" or Update the component try to update the component."
|
|
160
|
-
),
|
|
161
|
-
options=["fail", "skip", "update", "force"],
|
|
162
|
-
),
|
|
163
|
-
Configurable(
|
|
164
|
-
name="Multi-space components create",
|
|
165
|
-
value="False",
|
|
166
|
-
label=(
|
|
167
|
-
"Whether to create only components belonging to the data model space"
|
|
168
|
-
" (i.e. space define under Metadata sheet of Rules), "
|
|
169
|
-
"or also additionally components outside of the data model space."
|
|
170
|
-
),
|
|
171
|
-
options=["True", "False"],
|
|
172
|
-
),
|
|
173
|
-
]
|
|
174
|
-
|
|
175
|
-
def run(self, rules: MultiRuleData, cdf_client: CogniteClient) -> FlowMessage: # type: ignore[override]
|
|
176
|
-
if self.configs is None or self.data_store_path is None:
|
|
177
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
178
|
-
existing_components_handling = cast(
|
|
179
|
-
Literal["fail", "update", "skip", "force"], self.configs["Existing component handling"]
|
|
180
|
-
)
|
|
181
|
-
multi_space_components_create: bool = self.configs["Multi-space components create"] == "True"
|
|
182
|
-
components_to_create = {
|
|
183
|
-
cast(Literal["spaces", "data_models", "views", "containers"], key)
|
|
184
|
-
for key, value in self.complex_configs["Components"].items()
|
|
185
|
-
if value
|
|
186
|
-
}
|
|
187
|
-
dry_run = self.configs["Dry run"] == "True"
|
|
188
|
-
|
|
189
|
-
if not components_to_create:
|
|
190
|
-
return FlowMessage(
|
|
191
|
-
error_text="No DMS Schema components selected for upload! Please select minimum one!",
|
|
192
|
-
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
193
|
-
)
|
|
194
|
-
input_rules = rules.dms or rules.information
|
|
195
|
-
if input_rules is None:
|
|
196
|
-
return FlowMessage(
|
|
197
|
-
error_text="Missing DMS or Information rules in the input data! "
|
|
198
|
-
"Please ensure that a DMS or Information rules is provided!",
|
|
199
|
-
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
200
|
-
)
|
|
201
|
-
if isinstance(input_rules, DMSRules):
|
|
202
|
-
dms_rules = input_rules
|
|
203
|
-
elif isinstance(input_rules, InformationRules):
|
|
204
|
-
dms_rules = InformationToDMS().transform(input_rules)
|
|
205
|
-
else:
|
|
206
|
-
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
207
|
-
|
|
208
|
-
dms_exporter = exporters.DMSExporter(
|
|
209
|
-
export_components=frozenset(components_to_create),
|
|
210
|
-
include_space=(None if multi_space_components_create else {dms_rules.metadata.space}),
|
|
211
|
-
existing=existing_components_handling,
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
output_dir = self.config.staging_path
|
|
215
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
216
|
-
file_name = input_rules.metadata.external_id
|
|
217
|
-
schema_zip = f"{file_name}.zip"
|
|
218
|
-
schema_full_path = output_dir / schema_zip
|
|
219
|
-
dms_exporter.export_to_file(dms_rules, schema_full_path)
|
|
220
|
-
|
|
221
|
-
report_lines = ["# DMS Schema Export to CDF\n\n"]
|
|
222
|
-
errors = []
|
|
223
|
-
for result in dms_exporter.export_to_cdf_iterable(
|
|
224
|
-
rules=dms_rules, client=NeatClient(cdf_client), dry_run=dry_run
|
|
225
|
-
):
|
|
226
|
-
report_lines.append(str(result))
|
|
227
|
-
errors.extend(result.error_messages)
|
|
228
|
-
|
|
229
|
-
report_lines.append("\n\n# ERRORS\n\n")
|
|
230
|
-
report_lines.extend(errors)
|
|
231
|
-
|
|
232
|
-
output_dir = self.config.staging_path
|
|
233
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
234
|
-
report_file = "dms_component_creation_report.txt"
|
|
235
|
-
report_full_path = output_dir / report_file
|
|
236
|
-
report_full_path.write_text("\n".join(report_lines))
|
|
237
|
-
|
|
238
|
-
output_text = (
|
|
239
|
-
"<p></p>"
|
|
240
|
-
"Download DMS Export "
|
|
241
|
-
f'<a href="/data/staging/{report_file}?{time.time()}" '
|
|
242
|
-
f'target="_blank">Report</a>'
|
|
243
|
-
"<p></p>"
|
|
244
|
-
"Download DMS exported schema"
|
|
245
|
-
f'- <a href="/data/staging/{schema_zip}?{time.time()}" '
|
|
246
|
-
f'target="_blank">{schema_zip}</a>'
|
|
247
|
-
)
|
|
248
|
-
|
|
249
|
-
if errors:
|
|
250
|
-
return FlowMessage(error_text=output_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
251
|
-
else:
|
|
252
|
-
return FlowMessage(output_text=output_text)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
class RulesToExcel(Step):
|
|
256
|
-
"""This step exports Rules to Excel serialization"""
|
|
257
|
-
|
|
258
|
-
description = "This step exports Rules to Excel serialization."
|
|
259
|
-
version = "private-beta"
|
|
260
|
-
category = CATEGORY
|
|
261
|
-
|
|
262
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
263
|
-
Configurable(
|
|
264
|
-
name="Styling",
|
|
265
|
-
value="default",
|
|
266
|
-
label="Styling of the Excel file",
|
|
267
|
-
options=list(exporters.ExcelExporter.style_options),
|
|
268
|
-
),
|
|
269
|
-
Configurable(
|
|
270
|
-
name="Output role format",
|
|
271
|
-
value="input",
|
|
272
|
-
label="The role to use for the exported spreadsheet. If provided, the rules will be converted to "
|
|
273
|
-
"this role format before being written to excel. If not provided, the role from the input "
|
|
274
|
-
"rules will be used.",
|
|
275
|
-
options=["input", *RoleTypes.__members__.keys()],
|
|
276
|
-
),
|
|
277
|
-
Configurable(
|
|
278
|
-
name="New Data Model ID",
|
|
279
|
-
value="",
|
|
280
|
-
label="If you chose Dump Format 'reference', the provided ID will be use in the new medata sheet. "
|
|
281
|
-
"Expected format 'sp_space:my_external_id'.",
|
|
282
|
-
),
|
|
283
|
-
Configurable(
|
|
284
|
-
name="File path",
|
|
285
|
-
value="",
|
|
286
|
-
label="File path to the generated Excel file.For example: 'staging/exported-rules.xlsx'",
|
|
287
|
-
),
|
|
288
|
-
]
|
|
289
|
-
|
|
290
|
-
def run(self, rules: MultiRuleData) -> FlowMessage: # type: ignore[override, syntax]
|
|
291
|
-
if self.configs is None or self.data_store_path is None:
|
|
292
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
293
|
-
|
|
294
|
-
styling = cast(exporters.ExcelExporter.Style, self.configs.get("Styling", "default"))
|
|
295
|
-
role = self.configs.get("Output role format")
|
|
296
|
-
output_role: RoleTypes | None = None
|
|
297
|
-
if role != "input" and role is not None:
|
|
298
|
-
output_role = RoleTypes[role]
|
|
299
|
-
|
|
300
|
-
new_model_str = self.configs.get("New Data Model ID")
|
|
301
|
-
new_model_id: tuple[str, str] | None = None
|
|
302
|
-
if new_model_str and ":" in new_model_str:
|
|
303
|
-
new_model_id = tuple(new_model_str.split(":", 1)) # type: ignore[assignment]
|
|
304
|
-
elif new_model_str:
|
|
305
|
-
return FlowMessage(
|
|
306
|
-
error_text="New Data Model ID must be in the format 'sp_space:my_external_id'!",
|
|
307
|
-
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
308
|
-
)
|
|
309
|
-
|
|
310
|
-
excel_exporter = exporters.ExcelExporter(styling=styling, new_model_id=new_model_id) # type: ignore[arg-type]
|
|
311
|
-
|
|
312
|
-
# Todo - Move the conversion to a separate workflow step.
|
|
313
|
-
rule_instance: VerifiedRules
|
|
314
|
-
|
|
315
|
-
if rules.information:
|
|
316
|
-
rule_instance = rules.information
|
|
317
|
-
elif rules.dms:
|
|
318
|
-
rule_instance = rules.dms
|
|
319
|
-
else:
|
|
320
|
-
output_errors = "No rules provided for export!"
|
|
321
|
-
return FlowMessage(error_text=output_errors, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)
|
|
322
|
-
|
|
323
|
-
if rule_instance.metadata.role is output_role or output_role is None:
|
|
324
|
-
...
|
|
325
|
-
elif output_role is RoleTypes.dms:
|
|
326
|
-
if isinstance(rule_instance, InformationRules):
|
|
327
|
-
rule_instance = InformationToDMS().transform(rule_instance)
|
|
328
|
-
else:
|
|
329
|
-
raise NotImplementedError(f"Role {output_role} is not supported for {type(rules).__name__} rules")
|
|
330
|
-
elif output_role is RoleTypes.information:
|
|
331
|
-
if isinstance(rule_instance, DMSRules):
|
|
332
|
-
rule_instance = DMSToInformation().transform(rule_instance)
|
|
333
|
-
else:
|
|
334
|
-
raise NotImplementedError(f"Role {output_role} is not supported for {type(rules).__name__} rules")
|
|
335
|
-
else:
|
|
336
|
-
raise NotImplementedError(f"Role {output_role} is not supported for {type(rules).__name__} rules")
|
|
337
|
-
|
|
338
|
-
if output_role is None:
|
|
339
|
-
output_role = rule_instance.metadata.role
|
|
340
|
-
output_dir = self.data_store_path / Path("staging")
|
|
341
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
342
|
-
file_name = f"exported_rules_{output_role.value}.xlsx"
|
|
343
|
-
filepath = output_dir / file_name
|
|
344
|
-
if self.configs.get("File path", ""):
|
|
345
|
-
file_name = self.configs["File path"]
|
|
346
|
-
filepath = Path(self.data_store_path) / Path(file_name)
|
|
347
|
-
else:
|
|
348
|
-
file_name = f"staging/{file_name}"
|
|
349
|
-
|
|
350
|
-
excel_exporter.export_to_file(rule_instance, filepath)
|
|
351
|
-
|
|
352
|
-
output_text = (
|
|
353
|
-
"<p></p>"
|
|
354
|
-
f"Download Excel Exported {output_role.value} rules: "
|
|
355
|
-
f'- <a href="/data/{file_name}?{time.time()}" '
|
|
356
|
-
f'target="_blank">{file_name}</a>'
|
|
357
|
-
)
|
|
358
|
-
|
|
359
|
-
return FlowMessage(output_text=output_text)
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
class RulesToOntology(Step):
|
|
363
|
-
"""
|
|
364
|
-
This step exports Rules to OWL ontology
|
|
365
|
-
"""
|
|
366
|
-
|
|
367
|
-
description = "This step exports Rules to OWL ontology"
|
|
368
|
-
version = "private-beta"
|
|
369
|
-
category = CATEGORY
|
|
370
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
371
|
-
Configurable(
|
|
372
|
-
name="File path",
|
|
373
|
-
value="staging/ontology.ttl",
|
|
374
|
-
label=("Relative path for the ontology file storage, " " It will be auto-created if not provided ! "),
|
|
375
|
-
)
|
|
376
|
-
]
|
|
377
|
-
|
|
378
|
-
def run(self, rules: MultiRuleData) -> FlowMessage: # type: ignore[override, syntax]
|
|
379
|
-
if self.configs is None or self.data_store_path is None:
|
|
380
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
381
|
-
|
|
382
|
-
if not rules.information and not rules.dms:
|
|
383
|
-
return FlowMessage(
|
|
384
|
-
error_text="Rules must be made either by Information Architect or DMS Architect!",
|
|
385
|
-
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
386
|
-
)
|
|
387
|
-
|
|
388
|
-
default_path = self.config.staging_path / _get_default_file_name(rules, "ontology", "ttl")
|
|
389
|
-
|
|
390
|
-
storage_path = (
|
|
391
|
-
self.data_store_path / Path(self.configs["File path"]) if self.configs["File path"] else default_path
|
|
392
|
-
)
|
|
393
|
-
storage_path.parent.mkdir(parents=True, exist_ok=True)
|
|
394
|
-
|
|
395
|
-
input_rules = rules.information or rules.dms
|
|
396
|
-
if isinstance(input_rules, DMSRules):
|
|
397
|
-
info_rules = DMSToInformation().transform(input_rules)
|
|
398
|
-
elif isinstance(input_rules, InformationRules):
|
|
399
|
-
info_rules = input_rules
|
|
400
|
-
else:
|
|
401
|
-
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
402
|
-
|
|
403
|
-
exporter = exporters.OWLExporter()
|
|
404
|
-
exporter.export_to_file(info_rules, storage_path)
|
|
405
|
-
|
|
406
|
-
relative_file_path = "/".join(storage_path.relative_to(self.data_store_path).parts)
|
|
407
|
-
|
|
408
|
-
output_text = (
|
|
409
|
-
"<p></p>"
|
|
410
|
-
"Rules exported as OWL ontology can be downloaded here : "
|
|
411
|
-
f'<a href="/data/{relative_file_path}?{time.time()}" '
|
|
412
|
-
f'target="_blank">{storage_path.stem}.ttl</a>'
|
|
413
|
-
)
|
|
414
|
-
|
|
415
|
-
return FlowMessage(output_text=output_text)
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
class RulesToSHACL(Step):
|
|
419
|
-
"""
|
|
420
|
-
This step exports Rules to SHACL
|
|
421
|
-
"""
|
|
422
|
-
|
|
423
|
-
description = "This step exports Rules to SHACL"
|
|
424
|
-
version = "private-beta"
|
|
425
|
-
category = CATEGORY
|
|
426
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
427
|
-
Configurable(
|
|
428
|
-
name="File path",
|
|
429
|
-
value="staging/shacl.ttl",
|
|
430
|
-
label=(
|
|
431
|
-
"Relative path for the shacl file storage, "
|
|
432
|
-
"must end with .ttl ! It will be auto-created if not provided !"
|
|
433
|
-
),
|
|
434
|
-
)
|
|
435
|
-
]
|
|
436
|
-
|
|
437
|
-
def run(self, rules: MultiRuleData) -> FlowMessage: # type: ignore[override, syntax]
|
|
438
|
-
if self.configs is None or self.data_store_path is None:
|
|
439
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
440
|
-
|
|
441
|
-
if not rules.information and not rules.dms:
|
|
442
|
-
return FlowMessage(
|
|
443
|
-
error_text="Rules must be made either by Information Architect or DMS Architect!",
|
|
444
|
-
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
445
|
-
)
|
|
446
|
-
|
|
447
|
-
default_path = self.config.staging_path / _get_default_file_name(rules, "shacl", "ttl")
|
|
448
|
-
|
|
449
|
-
storage_path = (
|
|
450
|
-
self.data_store_path / Path(self.configs["File path"]) if self.configs["File path"] else default_path
|
|
451
|
-
)
|
|
452
|
-
storage_path.parent.mkdir(parents=True, exist_ok=True)
|
|
453
|
-
|
|
454
|
-
input_rules = rules.information or rules.dms
|
|
455
|
-
if isinstance(input_rules, DMSRules):
|
|
456
|
-
info_rules = DMSToInformation().transform(input_rules)
|
|
457
|
-
elif isinstance(input_rules, InformationRules):
|
|
458
|
-
info_rules = input_rules
|
|
459
|
-
else:
|
|
460
|
-
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
461
|
-
|
|
462
|
-
exporter = exporters.SHACLExporter()
|
|
463
|
-
exporter.export_to_file(info_rules, storage_path)
|
|
464
|
-
|
|
465
|
-
relative_file_path = "/".join(storage_path.relative_to(self.data_store_path).parts)
|
|
466
|
-
|
|
467
|
-
output_text = (
|
|
468
|
-
"<p></p>"
|
|
469
|
-
"Rules exported as SHACL shapes can be downloaded here : "
|
|
470
|
-
f'<a href="/data/{relative_file_path}?{time.time()}" '
|
|
471
|
-
f'target="_blank">{storage_path.stem}.ttl</a>'
|
|
472
|
-
)
|
|
473
|
-
|
|
474
|
-
return FlowMessage(output_text=output_text)
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
class RulesToSemanticDataModel(Step):
|
|
478
|
-
"""
|
|
479
|
-
This step exports Rules to semantic data model
|
|
480
|
-
"""
|
|
481
|
-
|
|
482
|
-
description = "This step exports Rules to semantic data model (ontology + SHACL)"
|
|
483
|
-
version = "private-beta"
|
|
484
|
-
category = CATEGORY
|
|
485
|
-
configurables: ClassVar[list[Configurable]] = [
|
|
486
|
-
Configurable(
|
|
487
|
-
name="File path",
|
|
488
|
-
value="staging/semantic-data-model.ttl",
|
|
489
|
-
label=(
|
|
490
|
-
"Relative path for the semantic data model file storage, "
|
|
491
|
-
"must end with .ttl ! It will be auto-created if not provided !"
|
|
492
|
-
),
|
|
493
|
-
)
|
|
494
|
-
]
|
|
495
|
-
|
|
496
|
-
def run(self, rules: MultiRuleData) -> FlowMessage: # type: ignore[override, syntax]
|
|
497
|
-
if self.configs is None or self.data_store_path is None:
|
|
498
|
-
raise WorkflowStepNotInitializedError(type(self).__name__)
|
|
499
|
-
|
|
500
|
-
if not rules.information and not rules.dms:
|
|
501
|
-
return FlowMessage(
|
|
502
|
-
error_text="Rules must be made either by Information Architect or DMS Architect!",
|
|
503
|
-
step_execution_status=StepExecutionStatus.ABORT_AND_FAIL,
|
|
504
|
-
)
|
|
505
|
-
|
|
506
|
-
default_path = self.config.staging_path / _get_default_file_name(rules, "semantic-data-model", "ttl")
|
|
507
|
-
|
|
508
|
-
storage_path = (
|
|
509
|
-
self.data_store_path / Path(self.configs["File path"]) if self.configs["File path"] else default_path
|
|
510
|
-
)
|
|
511
|
-
storage_path.parent.mkdir(parents=True, exist_ok=True)
|
|
512
|
-
input_rules = rules.information or rules.dms
|
|
513
|
-
if isinstance(input_rules, DMSRules):
|
|
514
|
-
info_rules = DMSToInformation().transform(input_rules)
|
|
515
|
-
elif isinstance(input_rules, InformationRules):
|
|
516
|
-
info_rules = input_rules
|
|
517
|
-
else:
|
|
518
|
-
raise NotImplementedError(f"Unsupported rules type {type(input_rules)}")
|
|
519
|
-
exporter = exporters.SemanticDataModelExporter()
|
|
520
|
-
exporter.export_to_file(info_rules, storage_path)
|
|
521
|
-
|
|
522
|
-
relative_file_path = "/".join(storage_path.relative_to(self.data_store_path).parts)
|
|
523
|
-
|
|
524
|
-
output_text = (
|
|
525
|
-
"<p></p>"
|
|
526
|
-
"Rules exported as semantic data model (OWL + SHACL) can be downloaded here : "
|
|
527
|
-
f'<a href="/data/{relative_file_path}?{time.time()}" '
|
|
528
|
-
f'target="_blank">{storage_path.stem}.ttl</a>'
|
|
529
|
-
)
|
|
530
|
-
|
|
531
|
-
return FlowMessage(output_text=output_text)
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
def _get_default_file_name(rules: MultiRuleData, file_category: str = "ontology", extension: str = "ttl") -> str:
|
|
535
|
-
name = rules.information.metadata.prefix if rules.information else cast(DMSRules, rules.dms).metadata.space
|
|
536
|
-
version = rules.information.metadata.version if rules.information else cast(DMSRules, rules.dms).metadata.version
|
|
537
|
-
return f"{name}-v{version.strip().replace('.', '_')}-{file_category}.{extension}"
|