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 CHANGED
@@ -1 +1 @@
1
- __version__ = "0.72.1"
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": dms_schema.views.dump() if dms_schema.views else None,
61
- "containers": dms_schema.containers.dump() if dms_schema.containers else None,
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": []}
@@ -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
- view.filter = has_data
806
- elif has_data is None:
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
- # Child filter with its own container properties
814
- if node_type_flag:
815
- # Transformations do not yet support setting node type.
816
- view.filter = dm.filters.And(has_data, node_type)
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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cognite-neat
3
- Version: 0.72.1
3
+ Version: 0.72.2
4
4
  Summary: Knowledge graph transformation
5
5
  Home-page: https://cognite-neat.readthedocs-hosted.com/
6
6
  License: Apache-2.0
@@ -1,5 +1,5 @@
1
1
  cognite/neat/__init__.py,sha256=v-rRiDOgZ3sQSMQKq0vgUQZvpeOkoHFXissAx6Ktg84,61
2
- cognite/neat/_version.py,sha256=-bsES2AHa1TNyPmsDMRScqqA4ezbJdvAUS3UylEI4rQ,23
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=OO9M611KG9QAdCVurWQPiU6wj6GVsTzs5DdXlCFA-wI,2191
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=q5Sv81HiRpX4e7B3wzG3kILpbdGNrbYSyTlT3yw1d2A,11167
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=d4WKTyuSWWw6ioOYCnayTQcTWNGv-dys2LU3PBI8Fuc,49465
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.1.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
231
- cognite_neat-0.72.1.dist-info/METADATA,sha256=Ow2IjY4oEmsDS2NTfizqbgKBUapUvhV7WDWxBwIA5Ak,9321
232
- cognite_neat-0.72.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
233
- cognite_neat-0.72.1.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
234
- cognite_neat-0.72.1.dist-info/RECORD,,
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,,