cognite-neat 0.70.0__py3-none-any.whl → 0.70.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.
- cognite/neat/_version.py +1 -1
- cognite/neat/rules/exporters/_rules2dms.py +49 -8
- cognite/neat/rules/models/_rules/dms_architect_rules.py +2 -2
- cognite/neat/rules/models/_rules/dms_schema.py +3 -0
- cognite/neat/rules/models/_rules/information_rules.py +13 -9
- {cognite_neat-0.70.0.dist-info → cognite_neat-0.70.1.dist-info}/METADATA +1 -1
- {cognite_neat-0.70.0.dist-info → cognite_neat-0.70.1.dist-info}/RECORD +10 -10
- {cognite_neat-0.70.0.dist-info → cognite_neat-0.70.1.dist-info}/LICENSE +0 -0
- {cognite_neat-0.70.0.dist-info → cognite_neat-0.70.1.dist-info}/WHEEL +0 -0
- {cognite_neat-0.70.0.dist-info → cognite_neat-0.70.1.dist-info}/entry_points.txt +0 -0
cognite/neat/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.70.
|
|
1
|
+
__version__ = "0.70.1"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import warnings
|
|
2
2
|
from collections.abc import Collection, Iterable
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Literal, TypeAlias
|
|
4
|
+
from typing import Literal, TypeAlias, cast
|
|
5
5
|
|
|
6
6
|
from cognite.client import CogniteClient
|
|
7
7
|
from cognite.client.data_classes._base import CogniteResourceList
|
|
@@ -9,7 +9,8 @@ from cognite.client.exceptions import CogniteAPIError
|
|
|
9
9
|
|
|
10
10
|
from cognite.neat.rules._shared import Rules
|
|
11
11
|
from cognite.neat.rules.models._rules import InformationRules
|
|
12
|
-
from cognite.neat.rules.models._rules.
|
|
12
|
+
from cognite.neat.rules.models._rules.base import ExtensionCategory, SheetList
|
|
13
|
+
from cognite.neat.rules.models._rules.dms_architect_rules import DMSContainer, DMSRules
|
|
13
14
|
from cognite.neat.rules.models._rules.dms_schema import DMSSchema, PipelineSchema
|
|
14
15
|
from cognite.neat.utils.cdf_loaders import (
|
|
15
16
|
ContainerLoader,
|
|
@@ -107,14 +108,53 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
107
108
|
|
|
108
109
|
def export(self, rules: Rules) -> DMSSchema:
|
|
109
110
|
if isinstance(rules, DMSRules):
|
|
110
|
-
|
|
111
|
+
dms_rules = rules
|
|
111
112
|
elif isinstance(rules, InformationRules):
|
|
112
|
-
|
|
113
|
-
self.standardize_casing, self.export_pipeline, self.instance_space
|
|
114
|
-
)
|
|
113
|
+
dms_rules = rules.as_dms_architect_rules()
|
|
115
114
|
else:
|
|
116
115
|
raise ValueError(f"{type(rules).__name__} cannot be exported to DMS")
|
|
117
116
|
|
|
117
|
+
is_solution_model = (
|
|
118
|
+
dms_rules.reference and dms_rules.metadata.external_id != dms_rules.reference.metadata.external_id
|
|
119
|
+
)
|
|
120
|
+
is_new_model = dms_rules.reference is None
|
|
121
|
+
if is_new_model or is_solution_model:
|
|
122
|
+
return dms_rules.as_schema(self.standardize_casing, self.export_pipeline, self.instance_space)
|
|
123
|
+
|
|
124
|
+
# This is an extension of an existing model.
|
|
125
|
+
reference_rules = cast(DMSRules, dms_rules.reference).copy(deep=True)
|
|
126
|
+
reference_schema = reference_rules.as_schema(self.standardize_casing, self.export_pipeline)
|
|
127
|
+
|
|
128
|
+
# Todo Move this to an appropriate location
|
|
129
|
+
# Merging Reference with User Rules
|
|
130
|
+
combined_rules = dms_rules.copy(deep=True)
|
|
131
|
+
existing_containers = {container.class_ for container in combined_rules.containers or []}
|
|
132
|
+
if combined_rules.containers is None:
|
|
133
|
+
combined_rules.containers = SheetList[DMSContainer](data=[])
|
|
134
|
+
for container in reference_rules.containers or []:
|
|
135
|
+
if container.class_ not in existing_containers:
|
|
136
|
+
container.reference = None
|
|
137
|
+
combined_rules.containers.append(container)
|
|
138
|
+
existing_views = {view.class_ for view in combined_rules.views}
|
|
139
|
+
for view in reference_rules.views:
|
|
140
|
+
if view.class_ not in existing_views:
|
|
141
|
+
view.reference = None
|
|
142
|
+
combined_rules.views.append(view)
|
|
143
|
+
existing_properties = {(property_.class_, property_.property_) for property_ in combined_rules.properties}
|
|
144
|
+
for property_ in reference_rules.properties:
|
|
145
|
+
if (property_.class_, property_.property_) not in existing_properties:
|
|
146
|
+
property_.reference = None
|
|
147
|
+
combined_rules.properties.append(property_)
|
|
148
|
+
|
|
149
|
+
schema = combined_rules.as_schema(self.standardize_casing, self.export_pipeline, self.instance_space)
|
|
150
|
+
|
|
151
|
+
if dms_rules.metadata.extension in (ExtensionCategory.addition, ExtensionCategory.reshape):
|
|
152
|
+
# We do not freeze views as they might be changed, even for addition,
|
|
153
|
+
# in case, for example, new properties are added. The validation will catch this.
|
|
154
|
+
schema.frozen_ids.update(set(reference_schema.containers.as_ids()))
|
|
155
|
+
schema.frozen_ids.update(set(reference_schema.node_types.as_ids()))
|
|
156
|
+
return schema
|
|
157
|
+
|
|
118
158
|
def export_to_cdf(self, rules: Rules, client: CogniteClient, dry_run: bool = False) -> Iterable[UploadResult]:
|
|
119
159
|
schema = self.export(rules)
|
|
120
160
|
to_export: list[tuple[CogniteResourceList, ResourceLoader]] = []
|
|
@@ -136,7 +176,9 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
136
176
|
redeploy_data_model = False
|
|
137
177
|
|
|
138
178
|
for items, loader in to_export:
|
|
139
|
-
|
|
179
|
+
all_item_ids = loader.get_ids(items)
|
|
180
|
+
skipped = sum(1 for item_id in all_item_ids if item_id in schema.frozen_ids)
|
|
181
|
+
item_ids = [item_id for item_id in all_item_ids if item_id not in schema.frozen_ids]
|
|
140
182
|
cdf_items = loader.retrieve(item_ids)
|
|
141
183
|
cdf_item_by_id = {loader.get_id(item): item for item in cdf_items}
|
|
142
184
|
to_create, to_update, unchanged, to_delete = [], [], [], []
|
|
@@ -163,7 +205,6 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
163
205
|
created = len(to_create)
|
|
164
206
|
failed_created = 0
|
|
165
207
|
|
|
166
|
-
skipped = 0
|
|
167
208
|
if self.existing_handling in ["update", "force"]:
|
|
168
209
|
changed = len(to_update)
|
|
169
210
|
failed_changed = 0
|
|
@@ -211,7 +211,7 @@ class DMSContainer(SheetEntity):
|
|
|
211
211
|
container_id = self.container.as_id(default_space, standardize_casing)
|
|
212
212
|
constraints: dict[str, dm.Constraint] = {}
|
|
213
213
|
for constraint in self.constraint or []:
|
|
214
|
-
requires = dm.RequiresConstraint(constraint.as_id(default_space))
|
|
214
|
+
requires = dm.RequiresConstraint(constraint.as_id(default_space, standardize_casing))
|
|
215
215
|
constraints[f"{constraint.space}_{constraint.external_id}"] = requires
|
|
216
216
|
|
|
217
217
|
return dm.ContainerApply(
|
|
@@ -796,7 +796,7 @@ class _DMSExporter:
|
|
|
796
796
|
parent_views = {parent for view in views for parent in view.implements or []}
|
|
797
797
|
node_type_flag = False
|
|
798
798
|
for view in views:
|
|
799
|
-
ref_containers = view.referenced_containers()
|
|
799
|
+
ref_containers = sorted(view.referenced_containers(), key=lambda c: c.as_tuple())
|
|
800
800
|
has_data = dm.filters.HasData(containers=list(ref_containers)) if ref_containers else None
|
|
801
801
|
node_type = dm.filters.Equals(["node", "type"], {"space": view.space, "externalId": view.external_id})
|
|
802
802
|
if view.as_id() in parent_views:
|
|
@@ -45,6 +45,9 @@ class DMSSchema:
|
|
|
45
45
|
views: dm.ViewApplyList = field(default_factory=lambda: dm.ViewApplyList([]))
|
|
46
46
|
containers: dm.ContainerApplyList = field(default_factory=lambda: dm.ContainerApplyList([]))
|
|
47
47
|
node_types: dm.NodeApplyList = field(default_factory=lambda: dm.NodeApplyList([]))
|
|
48
|
+
# The frozen ids are parts of the schema that should not be modified or deleted.
|
|
49
|
+
# This is used the exporting the schema.
|
|
50
|
+
frozen_ids: set[dm.ViewId | dm.ContainerId | dm.NodeId] = field(default_factory=set)
|
|
48
51
|
|
|
49
52
|
_FIELD_NAME_BY_RESOURCE_TYPE: ClassVar[dict[str, str]] = {
|
|
50
53
|
"container": "containers",
|
|
@@ -304,7 +304,7 @@ class InformationRules(RuleModel):
|
|
|
304
304
|
kwargs = vars(info)
|
|
305
305
|
default_prefix = f"{self.metadata.prefix}:" if self.metadata.prefix else ""
|
|
306
306
|
|
|
307
|
-
field_names = ["Class"] if info.by_alias else ["class_"]
|
|
307
|
+
field_names = ["Class", "Value Type"] if info.by_alias else ["class_", "value_type"]
|
|
308
308
|
properties = []
|
|
309
309
|
for prop in self.properties:
|
|
310
310
|
dumped = prop.model_dump(**kwargs)
|
|
@@ -392,7 +392,7 @@ class _InformationRulesConverter:
|
|
|
392
392
|
class_=cls_.class_,
|
|
393
393
|
view=ViewPropEntity(prefix=cls_.class_.prefix, suffix=cls_.class_.suffix, version=cls_.class_.version),
|
|
394
394
|
description=cls_.description,
|
|
395
|
-
implements=self._get_view_implements(cls_),
|
|
395
|
+
implements=self._get_view_implements(cls_, info_metadata),
|
|
396
396
|
)
|
|
397
397
|
for cls_ in self.information.classes
|
|
398
398
|
]
|
|
@@ -507,15 +507,19 @@ class _InformationRulesConverter:
|
|
|
507
507
|
return ContainerEntity(prefix=prop.class_.prefix, suffix=prop.class_.suffix), prop.property_
|
|
508
508
|
|
|
509
509
|
@classmethod
|
|
510
|
-
def _get_view_implements(cls, cls_: InformationClass) -> list[ViewEntity]:
|
|
511
|
-
if isinstance(cls_.reference, ReferenceEntity):
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
)
|
|
510
|
+
def _get_view_implements(cls, cls_: InformationClass, metadata: InformationMetadata) -> list[ViewEntity]:
|
|
511
|
+
if isinstance(cls_.reference, ReferenceEntity) and cls_.reference.prefix != metadata.prefix:
|
|
512
|
+
# We use the reference for implements if it is in a different namespace
|
|
513
|
+
implements = [
|
|
514
|
+
ViewEntity(prefix=cls_.reference.prefix, suffix=cls_.reference.suffix, version=cls_.reference.version)
|
|
516
515
|
]
|
|
517
516
|
else:
|
|
518
|
-
|
|
517
|
+
implements = []
|
|
518
|
+
|
|
519
|
+
implements.extend(
|
|
520
|
+
[
|
|
519
521
|
ViewEntity(prefix=parent.prefix, suffix=parent.suffix, version=parent.version)
|
|
520
522
|
for parent in cls_.parent or []
|
|
521
523
|
]
|
|
524
|
+
)
|
|
525
|
+
return implements
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
cognite/neat/__init__.py,sha256=v-rRiDOgZ3sQSMQKq0vgUQZvpeOkoHFXissAx6Ktg84,61
|
|
2
|
-
cognite/neat/_version.py,sha256=
|
|
2
|
+
cognite/neat/_version.py,sha256=WVjSRSd2zgGQFanscfNpVjo_q_ShT12r7ukn4JBk-AU,23
|
|
3
3
|
cognite/neat/app/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
cognite/neat/app/api/asgi/metrics.py,sha256=nxFy7L5cChTI0a-zkCiJ59Aq8yLuIJp5c9Dg0wRXtV0,152
|
|
5
5
|
cognite/neat/app/api/configuration.py,sha256=xnKdBE_dtq1nRvKa79YGA_wimI5UhoSRuBQz4LkLzQw,4606
|
|
@@ -113,7 +113,7 @@ cognite/neat/rules/exporter/_validation.py,sha256=CnEer181-EdnWl3yOuZJKOJ80W7H7q
|
|
|
113
113
|
cognite/neat/rules/exporters/__init__.py,sha256=Gn3CjkVKHJF9Po1ZPH4wAJ-sRW9up7b2CpXm-eReV3Q,413
|
|
114
114
|
cognite/neat/rules/exporters/_base.py,sha256=aRCzRjGDoXILkGvASev2UjVvLXrVCRTFiKgYwzJZqAo,1518
|
|
115
115
|
cognite/neat/rules/exporters/_models.py,sha256=f_RbFhoyD27z6Dsk4upYMHp7JHZRCfIvZsEzH5JSvtc,1645
|
|
116
|
-
cognite/neat/rules/exporters/_rules2dms.py,sha256=
|
|
116
|
+
cognite/neat/rules/exporters/_rules2dms.py,sha256=5KUVBYyGr4Q4YVqBs6taTeh8nDVM1L-ABGFTpcaph4c,12129
|
|
117
117
|
cognite/neat/rules/exporters/_rules2excel.py,sha256=uK-aS9sBwXUCFQLIO1jciBQrB4w7ySF6MafDqG23hrQ,9080
|
|
118
118
|
cognite/neat/rules/exporters/_rules2ontology.py,sha256=70T28d1tcT179kt5yOZQlLgAQ67uydz3XbhbA10IRuI,19768
|
|
119
119
|
cognite/neat/rules/exporters/_rules2yaml.py,sha256=HKgFlpgD7U2vWLQC_VdSvkDk19QgeVAd_J8wQ9ZgrN8,3038
|
|
@@ -163,10 +163,10 @@ cognite/neat/rules/models/_rules/_types/_base.py,sha256=EsTqjXUP0zpuQ-Z_BMP-00rJ
|
|
|
163
163
|
cognite/neat/rules/models/_rules/_types/_field.py,sha256=dOVAU1jWCupFVnrYYwLfI-nNUC4rv4vXHMzpiObtWiw,10295
|
|
164
164
|
cognite/neat/rules/models/_rules/_types/_value.py,sha256=I7Ke388M2NOi0U5F9kAzOjE0O4ZXbIxefupgDAjnISM,6079
|
|
165
165
|
cognite/neat/rules/models/_rules/base.py,sha256=9DgtdCmpz84sMFxZB_stWkalVbjA4HQKsTMpSjjOVLU,10635
|
|
166
|
-
cognite/neat/rules/models/_rules/dms_architect_rules.py,sha256=
|
|
167
|
-
cognite/neat/rules/models/_rules/dms_schema.py,sha256
|
|
166
|
+
cognite/neat/rules/models/_rules/dms_architect_rules.py,sha256=aevTRWHscgYBih4DqdMzKPAHpj5NVOrCpld0sTp-5Qk,49379
|
|
167
|
+
cognite/neat/rules/models/_rules/dms_schema.py,sha256=-ru40beGY2WJvf9_sd5eO2Wh8x2qLQ2UmgzExloBWac,30229
|
|
168
168
|
cognite/neat/rules/models/_rules/domain_rules.py,sha256=mOE4M6wOurmnAehxbnxvP9vIVXsFuKSiyMmD1shXKpA,2051
|
|
169
|
-
cognite/neat/rules/models/_rules/information_rules.py,sha256=
|
|
169
|
+
cognite/neat/rules/models/_rules/information_rules.py,sha256=e_SesgvMbzgC9WMFx0b_6qrpOIQvoQ_kXUiXrSYC9RI,20984
|
|
170
170
|
cognite/neat/rules/models/raw_rules.py,sha256=Y7ZVKyvLhX0s6WdwztbFiYFj4EijGEfjtBmv0ibRmmg,12368
|
|
171
171
|
cognite/neat/rules/models/rdfpath.py,sha256=kk1dqxl3n2W_vSQtpSJri2O4nCXnCDZB2lhLsLV1PN0,7344
|
|
172
172
|
cognite/neat/rules/models/rules.py,sha256=ECKrQEtoiQqtR8W-rKMAWmODpHeHhI8Qzf3TwCa3dy8,51063
|
|
@@ -227,8 +227,8 @@ cognite/neat/workflows/steps_registry.py,sha256=PZVoHX4d6Vmjz6XzUFnFFWMCnrVnqkUC
|
|
|
227
227
|
cognite/neat/workflows/tasks.py,sha256=dqlJwKAb0jlkl7abbY8RRz3m7MT4SK8-7cntMWkOYjw,788
|
|
228
228
|
cognite/neat/workflows/triggers.py,sha256=_BLNplzoz0iic367u1mhHMHiUrCwP-SLK6_CZzfODX0,7071
|
|
229
229
|
cognite/neat/workflows/utils.py,sha256=gKdy3RLG7ctRhbCRwaDIWpL9Mi98zm56-d4jfHDqP1E,453
|
|
230
|
-
cognite_neat-0.70.
|
|
231
|
-
cognite_neat-0.70.
|
|
232
|
-
cognite_neat-0.70.
|
|
233
|
-
cognite_neat-0.70.
|
|
234
|
-
cognite_neat-0.70.
|
|
230
|
+
cognite_neat-0.70.1.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
|
|
231
|
+
cognite_neat-0.70.1.dist-info/METADATA,sha256=olXq5x4vGn839BRr4LQBKuE8gsBpqDuiUW57iH9he1k,9321
|
|
232
|
+
cognite_neat-0.70.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
233
|
+
cognite_neat-0.70.1.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
|
|
234
|
+
cognite_neat-0.70.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|