cognite-neat 0.72.1__py3-none-any.whl → 0.72.2__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/app/api/routers/core.py +32 -2
- cognite/neat/rules/issues/dms.py +43 -0
- cognite/neat/rules/models/_rules/dms_architect_rules.py +22 -10
- {cognite_neat-0.72.1.dist-info → cognite_neat-0.72.2.dist-info}/METADATA +1 -1
- {cognite_neat-0.72.1.dist-info → cognite_neat-0.72.2.dist-info}/RECORD +9 -9
- {cognite_neat-0.72.1.dist-info → cognite_neat-0.72.2.dist-info}/LICENSE +0 -0
- {cognite_neat-0.72.1.dist-info → cognite_neat-0.72.2.dist-info}/WHEEL +0 -0
- {cognite_neat-0.72.1.dist-info → cognite_neat-0.72.2.dist-info}/entry_points.txt +0 -0
cognite/neat/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.72.
|
|
1
|
+
__version__ = "0.72.2"
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import shutil
|
|
3
3
|
import tempfile
|
|
4
|
+
from copy import deepcopy
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import cast
|
|
6
7
|
|
|
7
8
|
from fastapi import APIRouter, UploadFile
|
|
8
9
|
|
|
10
|
+
from cognite.neat.app.api.configuration import NEAT_APP
|
|
9
11
|
from cognite.neat.rules import exporters, importers
|
|
10
12
|
from cognite.neat.rules.models._rules import DMSRules
|
|
11
13
|
from cognite.neat.rules.models._rules.base import RoleTypes
|
|
@@ -55,8 +57,36 @@ async def convert_data_model_to_rules(file: UploadFile):
|
|
|
55
57
|
@router.post("/api/core/rules2dms")
|
|
56
58
|
async def convert_rules_to_dms(rules: DMSRules):
|
|
57
59
|
dms_schema = exporters.DMSExporter().export(rules)
|
|
60
|
+
containers = {f"{container.space}:{container.external_id}": container.dump() for container in dms_schema.containers}
|
|
61
|
+
views = {f"{view.space}:{view.external_id}": view.dump() for view in dms_schema.views}
|
|
62
|
+
|
|
63
|
+
if views and containers:
|
|
64
|
+
_to_visualization_compliant_views(views, containers)
|
|
58
65
|
|
|
59
66
|
return {
|
|
60
|
-
"views":
|
|
61
|
-
"containers":
|
|
67
|
+
"views": list(views.values()) if views else None,
|
|
68
|
+
"containers": list(containers.values()) if containers else None,
|
|
62
69
|
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _to_visualization_compliant_views(views, containers):
|
|
73
|
+
for view in views.values():
|
|
74
|
+
for property in view["properties"].values():
|
|
75
|
+
# needs coping information from container:
|
|
76
|
+
if property.get("container", None) and property["container"]["type"] == "container":
|
|
77
|
+
container_id = f"{property['container']['space']}:{property['container']['externalId']}"
|
|
78
|
+
container_property_def = deepcopy(
|
|
79
|
+
containers[container_id]["properties"][property["containerPropertyIdentifier"]]
|
|
80
|
+
)
|
|
81
|
+
property["type"] = container_property_def["type"]
|
|
82
|
+
container_property_def.pop("type")
|
|
83
|
+
property.update(container_property_def)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@router.post("/api/core/publish-rules")
|
|
87
|
+
async def publish_rules_as_data_model(rules: DMSRules):
|
|
88
|
+
if NEAT_APP.cdf_client:
|
|
89
|
+
uploaded = exporters.DMSExporter().export_to_cdf(rules, NEAT_APP.cdf_client)
|
|
90
|
+
return {"uploaded": uploaded}
|
|
91
|
+
else:
|
|
92
|
+
return {"uploaded": []}
|
cognite/neat/rules/issues/dms.py
CHANGED
|
@@ -24,6 +24,8 @@ __all__ = [
|
|
|
24
24
|
"EmptyContainerWarning",
|
|
25
25
|
"UnsupportedRelationWarning",
|
|
26
26
|
"MultipleReferenceWarning",
|
|
27
|
+
"HasDataFilterOnNoPropertiesViewWarning",
|
|
28
|
+
"NodeTypeFilterOnParentViewWarning",
|
|
27
29
|
]
|
|
28
30
|
|
|
29
31
|
|
|
@@ -329,3 +331,44 @@ class MultipleReferenceWarning(DMSSchemaWarning):
|
|
|
329
331
|
output["view_id"] = self.view_id.dump()
|
|
330
332
|
output["implements"] = [view.dump() for view in self.implements]
|
|
331
333
|
return output
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
@dataclass(frozen=True)
|
|
337
|
+
class HasDataFilterOnNoPropertiesViewWarning(DMSSchemaWarning):
|
|
338
|
+
description = "Attempting to set a HasData filter on a view without properties."
|
|
339
|
+
fix = "Add properties to the view or use a node type filter"
|
|
340
|
+
error_name: ClassVar[str] = "HasDataFilterOnNoPropertiesViewWarning"
|
|
341
|
+
view_id: dm.ViewId
|
|
342
|
+
|
|
343
|
+
def message(self) -> str:
|
|
344
|
+
return (
|
|
345
|
+
f"Cannot set hasData filter on view {self.view_id} as it does not have properties in any containers. "
|
|
346
|
+
"Using a node type filter instead."
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
def dump(self) -> dict[str, Any]:
|
|
350
|
+
output = super().dump()
|
|
351
|
+
output["view_id"] = self.view_id.dump()
|
|
352
|
+
return output
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
@dataclass(frozen=True)
|
|
356
|
+
class NodeTypeFilterOnParentViewWarning(DMSSchemaWarning):
|
|
357
|
+
description = (
|
|
358
|
+
"Setting a node type filter on a parent view. This is no "
|
|
359
|
+
"recommended as parent views are typically used for multiple type of nodes."
|
|
360
|
+
)
|
|
361
|
+
fix = "Use a HasData filter instead"
|
|
362
|
+
error_name: ClassVar[str] = "NodeTypeFilterOnParentViewWarning"
|
|
363
|
+
view_id: dm.ViewId
|
|
364
|
+
|
|
365
|
+
def message(self) -> str:
|
|
366
|
+
return (
|
|
367
|
+
f"Setting a node type filter on parent view {self.view_id}. This is not recommended as "
|
|
368
|
+
"parent views are typically used for multiple types of nodes."
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
def dump(self) -> dict[str, Any]:
|
|
372
|
+
output = super().dump()
|
|
373
|
+
output["view_id"] = self.view_id.dump()
|
|
374
|
+
return output
|
|
@@ -243,6 +243,7 @@ class DMSView(SheetEntity):
|
|
|
243
243
|
view: ViewType = Field(alias="View")
|
|
244
244
|
implements: ViewListType | None = Field(None, alias="Implements")
|
|
245
245
|
reference: ReferenceType = Field(alias="Reference", default=None)
|
|
246
|
+
filter_: Literal["hasData", "nodeType"] | None = Field(None, alias="Filter")
|
|
246
247
|
in_model: bool = Field(True, alias="InModel")
|
|
247
248
|
|
|
248
249
|
def as_view(self, default_space: str, default_version: str, standardize_casing: bool = True) -> dm.ViewApply:
|
|
@@ -677,6 +678,11 @@ class _DMSExporter:
|
|
|
677
678
|
views = dm.ViewApplyList(
|
|
678
679
|
[dms_view.as_view(default_space, default_version, self.standardize_casing) for dms_view in dms_views]
|
|
679
680
|
)
|
|
681
|
+
dms_view_by_id = {
|
|
682
|
+
dms_view.view.as_id(False, default_space, default_version, self.standardize_casing): dms_view
|
|
683
|
+
for dms_view in dms_views
|
|
684
|
+
}
|
|
685
|
+
|
|
680
686
|
for view in views:
|
|
681
687
|
view_id = view.as_id()
|
|
682
688
|
view.properties = {}
|
|
@@ -796,24 +802,30 @@ class _DMSExporter:
|
|
|
796
802
|
|
|
797
803
|
node_types = dm.NodeApplyList([])
|
|
798
804
|
parent_views = {parent for view in views for parent in view.implements or []}
|
|
799
|
-
node_type_flag = False
|
|
800
805
|
for view in views:
|
|
801
806
|
ref_containers = sorted(view.referenced_containers(), key=lambda c: c.as_tuple())
|
|
802
807
|
has_data = dm.filters.HasData(containers=list(ref_containers)) if ref_containers else None
|
|
803
808
|
node_type = dm.filters.Equals(["node", "type"], {"space": view.space, "externalId": view.external_id})
|
|
809
|
+
dms_view = dms_view_by_id.get(view.as_id())
|
|
804
810
|
if view.as_id() in parent_views:
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
# Child filter without container properties
|
|
808
|
-
if node_type_flag:
|
|
809
|
-
# Transformations do not yet support setting node type.
|
|
811
|
+
if dms_view and dms_view.filter_ == "nodeType":
|
|
812
|
+
warnings.warn(issues.dms.NodeTypeFilterOnParentViewWarning(view.as_id()), stacklevel=2)
|
|
810
813
|
view.filter = node_type
|
|
811
814
|
node_types.append(dm.NodeApply(space=view.space, external_id=view.external_id, sources=[]))
|
|
815
|
+
else:
|
|
816
|
+
view.filter = has_data
|
|
817
|
+
elif has_data is None:
|
|
818
|
+
# Child filter without container properties
|
|
819
|
+
if dms_view and dms_view.filter_ == "hasData":
|
|
820
|
+
warnings.warn(issues.dms.HasDataFilterOnNoPropertiesViewWarning(view.as_id()), stacklevel=2)
|
|
821
|
+
view.filter = node_type
|
|
822
|
+
node_types.append(dm.NodeApply(space=view.space, external_id=view.external_id, sources=[]))
|
|
812
823
|
else:
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
824
|
+
if dms_view and (dms_view.filter_ == "hasData" or dms_view.filter_ is None):
|
|
825
|
+
# Default option
|
|
826
|
+
view.filter = has_data
|
|
827
|
+
elif dms_view and dms_view.filter_ == "nodeType":
|
|
828
|
+
view.filter = node_type
|
|
817
829
|
node_types.append(dm.NodeApply(space=view.space, external_id=view.external_id, sources=[]))
|
|
818
830
|
else:
|
|
819
831
|
view.filter = has_data
|
|
@@ -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=TB9NfKJN3p__h60nooN7qSNFiqOO_zE_B3dfGb0-uXQ,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
|
|
@@ -10,7 +10,7 @@ cognite/neat/app/api/data_classes/configuration.py,sha256=oBnnX6Zam7TOstiLpQbi3G
|
|
|
10
10
|
cognite/neat/app/api/data_classes/rest.py,sha256=yVWqFkBCDCGooOWaE5nun4No8B-PBa6svdenIjBINdo,1675
|
|
11
11
|
cognite/neat/app/api/explorer.py,sha256=OlLI-RbQGjXEuDgtmFfBuTXfnRVemTJDKbL9VvXLr6Y,1891
|
|
12
12
|
cognite/neat/app/api/routers/configuration.py,sha256=tFiEbtFHNVehMwM8T-IvnWpDOL_y-wCt-wd5w-Z4PQk,554
|
|
13
|
-
cognite/neat/app/api/routers/core.py,sha256=
|
|
13
|
+
cognite/neat/app/api/routers/core.py,sha256=ZU7sZ1QgFtrNHR-Y6DVzxLZSIJoZZeCvlXLgp2oO46U,3583
|
|
14
14
|
cognite/neat/app/api/routers/crud.py,sha256=Cnvw77JWCs_wzeoQYdWwGfFns8LgtYmsYWgKPtud3BA,4646
|
|
15
15
|
cognite/neat/app/api/routers/data_exploration.py,sha256=XlpEbggy1mK1XmwVtLZmrXWulTzdaGQaKAyHs3H04qU,13653
|
|
16
16
|
cognite/neat/app/api/routers/metrics.py,sha256=S_bUQk_GjfQq7WbEhSVdow4MUYBZ_bZNafzgcKogXK8,210
|
|
@@ -149,7 +149,7 @@ cognite/neat/rules/importers/_spreadsheet2rules.py,sha256=GVkTtWnQkM8nXkPAOs2Upx
|
|
|
149
149
|
cognite/neat/rules/importers/_yaml2rules.py,sha256=sIaYY3Zo--v1cXSu65n4ZPv47cS-5InvSbpkw3Ahov4,4198
|
|
150
150
|
cognite/neat/rules/issues/__init__.py,sha256=Ms6jgCxCezc5IgTOwCFtXQPtoVFfOvdcXj84_rs917I,563
|
|
151
151
|
cognite/neat/rules/issues/base.py,sha256=dS4lmbW9VQ8awgOIB-Ah9z9LdNbCa-fPd8tbyPb8sM4,5856
|
|
152
|
-
cognite/neat/rules/issues/dms.py,sha256=
|
|
152
|
+
cognite/neat/rules/issues/dms.py,sha256=WB8N6MPbLFxdScJLGGY_zdErcrEXJnAsMladMB5aKa4,12722
|
|
153
153
|
cognite/neat/rules/issues/fileread.py,sha256=n-GZaULOJF_MKkBIh1maaOuGZXOvZYw7Y6fDAS0jrBI,4492
|
|
154
154
|
cognite/neat/rules/issues/formatters.py,sha256=_pSogWtfkt2JK0PZgWQffbj2On8vumFNshxOKAi5fYw,3346
|
|
155
155
|
cognite/neat/rules/issues/importing.py,sha256=GqUywhBD840Fbc4DD5L2I0oEllJ78MTjpmXogVEjihA,7493
|
|
@@ -163,7 +163,7 @@ 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=ubyWmU6neyNxx17fqcciIjyB-CIpYNUuM97Xh2sVrYo,6308
|
|
165
165
|
cognite/neat/rules/models/_rules/base.py,sha256=9DgtdCmpz84sMFxZB_stWkalVbjA4HQKsTMpSjjOVLU,10635
|
|
166
|
-
cognite/neat/rules/models/_rules/dms_architect_rules.py,sha256=
|
|
166
|
+
cognite/neat/rules/models/_rules/dms_architect_rules.py,sha256=2JbQm-5rWQLpuZJbov5pKigddE_GslmxhA18GiNXWms,50201
|
|
167
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
169
|
cognite/neat/rules/models/_rules/information_rules.py,sha256=kETaZ3HsPw0EFXIeU-YhfEZeK4FhAh5RvNQAWbrcE-E,21026
|
|
@@ -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.72.
|
|
231
|
-
cognite_neat-0.72.
|
|
232
|
-
cognite_neat-0.72.
|
|
233
|
-
cognite_neat-0.72.
|
|
234
|
-
cognite_neat-0.72.
|
|
230
|
+
cognite_neat-0.72.2.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
|
|
231
|
+
cognite_neat-0.72.2.dist-info/METADATA,sha256=1k5nxYBvZSbu3_bbjMgjMq21jCOvMv3LlwE8fUIcAO4,9321
|
|
232
|
+
cognite_neat-0.72.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
233
|
+
cognite_neat-0.72.2.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
|
|
234
|
+
cognite_neat-0.72.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|