cognite-neat 0.72.0__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.0"
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": []}
@@ -11,7 +11,7 @@ from rdflib import DC, DCTERMS, OWL, RDF, RDFS, SKOS, Graph
11
11
  from cognite.neat.rules.importers._base import BaseImporter, Rules
12
12
  from cognite.neat.rules.issues import IssueList
13
13
  from cognite.neat.rules.models._rules import InformationRules, RoleTypes
14
- from cognite.neat.rules.models.value_types import XSD_VALUE_TYPE_MAPPINGS
14
+ from cognite.neat.rules.models._rules._types import XSD_VALUE_TYPE_MAPPINGS
15
15
 
16
16
  from ._owl2classes import parse_owl_classes
17
17
  from ._owl2metadata import parse_owl_metadata
@@ -136,6 +136,7 @@ def _add_missing_value_types(components: dict) -> dict:
136
136
 
137
137
  # to avoid issue of case sensitivity for xsd types
138
138
  value_types_lower = {v.lower() for v in candidate_value_types}
139
+
139
140
  xsd_types_lower = {x.lower() for x in xsd_types}
140
141
 
141
142
  # Create a mapping from lowercase strings to original strings
@@ -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
@@ -90,6 +90,9 @@ _DATA_TYPES: list[dict] = [
90
90
  {"name": "dateTime", "python": datetime, "GraphQL": "Timestamp", "dms": Timestamp, "SQL": "TIMESTAMP"},
91
91
  {"name": "dateTimeStamp", "python": datetime, "GraphQL": "Timestamp", "dms": Timestamp, "SQL": "TIMESTAMP"},
92
92
  {"name": "date", "python": date, "GraphQL": "String", "dms": Date, "SQL": "DATE"},
93
+ # Some RDF types which are not in XSD
94
+ {"name": "PlainLiteral", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
95
+ {"name": "Literal", "python": str, "GraphQL": "String", "dms": Text, "SQL": "STRING"},
93
96
  # CDF specific types, not in XSD
94
97
  {
95
98
  "name": "timeseries",
@@ -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
@@ -392,6 +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
+ reference=cls_.reference,
395
396
  implements=self._get_view_implements(cls_, info_metadata),
396
397
  )
397
398
  for cls_ in self.information.classes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cognite-neat
3
- Version: 0.72.0
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=oLwc2jwvoU9UISGgw7ct8h1SMKWzWPg21DSMF9jrXj0,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
@@ -144,12 +144,12 @@ cognite/neat/rules/importers/_owl2rules/__init__.py,sha256=tdGcrgtozdQyST-pTlxIa
144
144
  cognite/neat/rules/importers/_owl2rules/_owl2classes.py,sha256=tCEwwJPCdFLodM0q0gXfbyEe0rZvIG4emDTcUzDYRWI,7597
145
145
  cognite/neat/rules/importers/_owl2rules/_owl2metadata.py,sha256=kCTCAbUaUGgSwnH-jgFg01SfxD2VikyPy5L-vgxUjHA,7674
146
146
  cognite/neat/rules/importers/_owl2rules/_owl2properties.py,sha256=KNOrOySUXM9Krg6HEPNtiThlHfSEhd0EoQBtu_lczu8,7319
147
- cognite/neat/rules/importers/_owl2rules/_owl2rules.py,sha256=0QplDQnDslqwZ7B8-TuJWJkC30C7MAGyG81YhHdvasQ,7116
147
+ cognite/neat/rules/importers/_owl2rules/_owl2rules.py,sha256=R8Z6f7f-MbKyr9fgKW5sStKlXxvUeOiS4lotjavIx2E,7119
148
148
  cognite/neat/rules/importers/_spreadsheet2rules.py,sha256=GVkTtWnQkM8nXkPAOs2UpxKnsPHA6898Tb7aTgcDDPM,10573
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
@@ -161,12 +161,12 @@ cognite/neat/rules/models/_rules/__init__.py,sha256=jA4kMOAg4GJZjhCW1ovSjUCv-Top
161
161
  cognite/neat/rules/models/_rules/_types/__init__.py,sha256=Px0uB5fqk-8qH-HRi0ZvgGkLhYcS5A8EJ9QDB2TFwNQ,1299
162
162
  cognite/neat/rules/models/_rules/_types/_base.py,sha256=EsTqjXUP0zpuQ-Z_BMP-00rJBy2A2s-lJHzudIDAfqw,17145
163
163
  cognite/neat/rules/models/_rules/_types/_field.py,sha256=dOVAU1jWCupFVnrYYwLfI-nNUC4rv4vXHMzpiObtWiw,10295
164
- cognite/neat/rules/models/_rules/_types/_value.py,sha256=I7Ke388M2NOi0U5F9kAzOjE0O4ZXbIxefupgDAjnISM,6079
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
- cognite/neat/rules/models/_rules/information_rules.py,sha256=e_SesgvMbzgC9WMFx0b_6qrpOIQvoQ_kXUiXrSYC9RI,20984
169
+ cognite/neat/rules/models/_rules/information_rules.py,sha256=kETaZ3HsPw0EFXIeU-YhfEZeK4FhAh5RvNQAWbrcE-E,21026
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.72.0.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
231
- cognite_neat-0.72.0.dist-info/METADATA,sha256=v4XwOheDrImRLZysw5AyhOLCBBBiOpF2c5lJ4COpHWg,9321
232
- cognite_neat-0.72.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
233
- cognite_neat-0.72.0.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
234
- cognite_neat-0.72.0.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,,