cognite-neat 0.75.9__py3-none-any.whl → 0.76.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.
@@ -0,0 +1,166 @@
1
+ from abc import ABC, abstractmethod
2
+ from collections.abc import Collection
3
+ from functools import total_ordering
4
+ from typing import Any, ClassVar, TypeVar
5
+
6
+ from cognite.client import data_modeling as dm
7
+ from cognite.client.data_classes.data_modeling import ContainerId, NodeId
8
+ from pydantic import BaseModel, model_serializer, model_validator
9
+
10
+ from cognite.neat.rules.models.entities import ContainerEntity, DMSNodeEntity, Entity
11
+
12
+
13
+ @total_ordering
14
+ class WrappedEntity(BaseModel, ABC):
15
+ name: ClassVar[str]
16
+ _inner_cls: ClassVar[type[Entity]]
17
+ inner: list[Entity] | None
18
+
19
+ @classmethod
20
+ def load(cls: "type[T_WrappedEntity]", data: Any) -> "T_WrappedEntity":
21
+ if isinstance(data, cls):
22
+ return data
23
+ return cls.model_validate(data)
24
+
25
+ @model_validator(mode="before")
26
+ def _load(cls, data: Any) -> dict:
27
+ if isinstance(data, dict):
28
+ return data
29
+ elif not isinstance(data, str):
30
+ raise ValueError(f"Cannot load {cls.__name__} from {data}")
31
+ elif not data.casefold().startswith(cls.name.casefold()):
32
+ raise ValueError(f"Expected {cls.name} but got {data}")
33
+ result = cls._parse(data)
34
+ return result
35
+
36
+ @classmethod
37
+ def _parse(cls, data: str) -> dict:
38
+ if data.casefold() == cls.name.casefold():
39
+ return {"inner": None}
40
+ inner = data[len(cls.name) :].removeprefix("(").removesuffix(")")
41
+ return {"inner": [cls._inner_cls.load(entry.strip()) for entry in inner.split(",")]}
42
+
43
+ @model_serializer(when_used="unless-none", return_type=str)
44
+ def as_str(self) -> str:
45
+ return str(self)
46
+
47
+ def __str__(self):
48
+ return self.id
49
+
50
+ @property
51
+ def id(self) -> str:
52
+ inner = self.as_tuple()[1:]
53
+ return f"{self.name}({','.join(inner)})"
54
+
55
+ @property
56
+ def is_empty(self) -> bool:
57
+ return self.inner is None or (isinstance(self.inner, list) and not self.inner)
58
+
59
+ def dump(self) -> str:
60
+ return str(self)
61
+
62
+ def as_tuple(self) -> tuple[str, ...]:
63
+ entities: list[str] = [str(inner) for inner in self.inner or []]
64
+ return self.name, *entities
65
+
66
+ def __lt__(self, other: object) -> bool:
67
+ if not isinstance(other, WrappedEntity):
68
+ return NotImplemented
69
+ return self.as_tuple() < other.as_tuple()
70
+
71
+ def __eq__(self, other: object) -> bool:
72
+ if not isinstance(other, WrappedEntity):
73
+ return NotImplemented
74
+ return self.as_tuple() == other.as_tuple()
75
+
76
+ def __hash__(self) -> int:
77
+ return hash(str(self))
78
+
79
+ def __repr__(self) -> str:
80
+ return self.id
81
+
82
+
83
+ T_WrappedEntity = TypeVar("T_WrappedEntity", bound=WrappedEntity)
84
+
85
+
86
+ class DMSFilter(WrappedEntity):
87
+ @abstractmethod
88
+ def as_dms_filter(self, default: Any | None = None) -> dm.filters.Filter:
89
+ raise NotImplementedError
90
+
91
+ @classmethod
92
+ def from_dms_filter(cls, filter: dm.Filter) -> "DMSFilter":
93
+ dumped = filter.dump()
94
+ if (body := dumped.get(dm.filters.Equals._filter_name)) and (value := body.get("value")):
95
+ space = value.get("space")
96
+ external_id = value.get("externalId")
97
+ if space is not None and external_id is not None:
98
+ return NodeTypeFilter(inner=[DMSNodeEntity(space=space, externalId=external_id)])
99
+ elif (body := dumped.get(dm.filters.In._filter_name)) and (values := body.get("values")):
100
+ return NodeTypeFilter(
101
+ inner=[
102
+ DMSNodeEntity(space=entry["space"], externalId=entry["externalId"])
103
+ for entry in values
104
+ if isinstance(entry, dict) and "space" in entry and "externalId" in entry
105
+ ]
106
+ )
107
+ elif body := dumped.get(dm.filters.HasData._filter_name):
108
+ return HasDataFilter(
109
+ inner=[
110
+ ContainerEntity(space=entry["space"], externalId=entry["externalId"])
111
+ for entry in body
112
+ if isinstance(entry, dict) and "space" in entry and "externalId" in entry
113
+ ]
114
+ )
115
+
116
+ raise ValueError(f"Cannot convert {filter._filter_name} to {cls.__name__}")
117
+
118
+
119
+ class NodeTypeFilter(DMSFilter):
120
+ name: ClassVar[str] = "nodeType"
121
+ _inner_cls: ClassVar[type[DMSNodeEntity]] = DMSNodeEntity
122
+ inner: list[DMSNodeEntity] | None = None # type: ignore[assignment]
123
+
124
+ @property
125
+ def nodes(self) -> list[NodeId]:
126
+ return [node.as_id() for node in self.inner or []]
127
+
128
+ def as_dms_filter(self, default: Collection[NodeId] | None = None) -> dm.Filter:
129
+ if self.inner is not None:
130
+ node_ids = [node.as_id() for node in self.inner]
131
+ elif default is not None:
132
+ node_ids = list(default)
133
+ else:
134
+ raise ValueError("Empty nodeType filter, please provide a default node.")
135
+ if len(node_ids) == 1:
136
+ return dm.filters.Equals(
137
+ ["node", "type"], {"space": node_ids[0].space, "externalId": node_ids[0].external_id}
138
+ )
139
+ else:
140
+ return dm.filters.In(
141
+ ["node", "type"],
142
+ [
143
+ {"space": node.space, "externalId": node.external_id}
144
+ for node in sorted(node_ids, key=lambda node: node.as_tuple())
145
+ ],
146
+ )
147
+
148
+
149
+ class HasDataFilter(DMSFilter):
150
+ name: ClassVar[str] = "hasData"
151
+ _inner_cls: ClassVar[type[ContainerEntity]] = ContainerEntity
152
+ inner: list[ContainerEntity] | None = None # type: ignore[assignment]
153
+
154
+ def as_dms_filter(self, default: Collection[ContainerId] | None = None) -> dm.Filter:
155
+ containers: list[ContainerId]
156
+ if self.inner:
157
+ containers = [container.as_id() for container in self.inner]
158
+ elif default:
159
+ containers = list(default)
160
+ else:
161
+ raise ValueError("Empty hasData filter, please provide a default containers.")
162
+
163
+ return dm.filters.HasData(
164
+ # Sorting to ensure deterministic order
165
+ containers=sorted(containers, key=lambda container: container.as_tuple()) # type: ignore[union-attr]
166
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cognite-neat
3
- Version: 0.75.9
3
+ Version: 0.76.1
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=X-H6VAOk6BxNKKWyApnUjlIZqx4arMZpDacrdykwDYc,23
2
+ cognite/neat/_version.py,sha256=JYMWad1hoQA4r17GzBIhK4in6LVyBr7OqBPAmFHo8cc,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=2U5M6M252swvQPQyooA1EBzFUZNtcTmuSaywfJDgckM,4232
@@ -164,15 +164,15 @@ cognite/neat/rules/examples/wind-energy.owl,sha256=NuomCA9FuuLF0JlSuG3OKqD4VBcHg
164
164
  cognite/neat/rules/exceptions.py,sha256=YLnsbXXJdDSr_szQoioEtOdqDV8PR7RdQjpMP2SWeCs,123868
165
165
  cognite/neat/rules/exporters/__init__.py,sha256=Gn3CjkVKHJF9Po1ZPH4wAJ-sRW9up7b2CpXm-eReV3Q,413
166
166
  cognite/neat/rules/exporters/_base.py,sha256=rJIKvM9CQlwwAOBlmpYepB1Urb-ZLC0xBxS0fE7am-I,1517
167
- cognite/neat/rules/exporters/_models.py,sha256=BX19QXsbWjImCY9NCaOnrlMSs-6qcA5P3QLittrWvGM,1870
168
- cognite/neat/rules/exporters/_rules2dms.py,sha256=KXK_bJp752Zo8E3apHnTZzcZ2sQnmXftazI1mKPEfcQ,14231
169
- cognite/neat/rules/exporters/_rules2excel.py,sha256=vB8Gy6Zwso06nazTnnKe00-5gWH9a4GzO9C2T6MgzK8,13769
167
+ cognite/neat/rules/exporters/_models.py,sha256=vRd0P_YsrZ1eaAGGHfdTeFunaqHdaa0ZtnWiVZBR1nc,1976
168
+ cognite/neat/rules/exporters/_rules2dms.py,sha256=zFb-C4ihWrvud81AbNU2ZbSQ0jHqbYk4x34Zc1zFHyw,16126
169
+ cognite/neat/rules/exporters/_rules2excel.py,sha256=QFRNsd3kt1WLtz5WxI5gFErzS_Y1ScIb-u2QYNtnPAQ,13068
170
170
  cognite/neat/rules/exporters/_rules2ontology.py,sha256=GBpaAjM0X8t02NWE3CRmKKovEiHhvOHdWfbeXP7Hh6c,20139
171
171
  cognite/neat/rules/exporters/_rules2yaml.py,sha256=Irr4CwJ5pLlwiJeOMuGPU-HX9zoYrONyfV9JpRYz6j8,3038
172
172
  cognite/neat/rules/exporters/_validation.py,sha256=zPMwQLw3U2HKFTtdrUMt2e0D-3FfgcaqdYU0DZ9YG_g,4090
173
173
  cognite/neat/rules/importers/__init__.py,sha256=zqNbGpvdVhYkLjWx1i9dJ3FXzYGtuQyTydUYsj-BndQ,408
174
- cognite/neat/rules/importers/_base.py,sha256=syKsI9011tL_ygwvYYFQk_8bf9uc2B4vQVSdQ_IP2DU,4041
175
- cognite/neat/rules/importers/_dms2rules.py,sha256=-f7c-26DTvZH9ehZ8Wf1Oqf4Ae82N_NSJoOY_wrnuQQ,10363
174
+ cognite/neat/rules/importers/_base.py,sha256=ZT9kzmC8TluiMTao1rCVvD1ZK_Rq3WWclzn96ZuQg2U,4280
175
+ cognite/neat/rules/importers/_dms2rules.py,sha256=eSuUYZauRP3Hs3kh5SLUfd-KV_tubWesyxUEgbTdm6w,17827
176
176
  cognite/neat/rules/importers/_dtdl2rules/__init__.py,sha256=CNR-sUihs2mnR1bPMKs3j3L4ds3vFTsrl6YycExZTfU,68
177
177
  cognite/neat/rules/importers/_dtdl2rules/_unit_lookup.py,sha256=wW4saKva61Q_i17guY0dc4OseJDQfqHy_QZBtm0OD6g,12134
178
178
  cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py,sha256=dHWbcP7rLxnLOef69DBR2xDYFIWj_DQPx-IkIWwBZIA,12676
@@ -183,29 +183,30 @@ cognite/neat/rules/importers/_owl2rules/_owl2classes.py,sha256=3qxQlZr-3MLhL0oDH
183
183
  cognite/neat/rules/importers/_owl2rules/_owl2metadata.py,sha256=mqDa0oiKCX2gBEk47rX4r-VzOmsVyK6q_J7wvDOCklA,7804
184
184
  cognite/neat/rules/importers/_owl2rules/_owl2properties.py,sha256=UB7iZZFkoeTsxuM745rl5I4Myp5mrotDgzmjPBBfv8w,7443
185
185
  cognite/neat/rules/importers/_owl2rules/_owl2rules.py,sha256=CN0CK0vXzXwawRH1Sp4FdDmxjChP3IWZYdYb1HEV23s,6931
186
- cognite/neat/rules/importers/_spreadsheet2rules.py,sha256=ndPUOh07_u_nlX790ztO2ny_gVT2SL-gpec0pgT6NMI,11274
186
+ cognite/neat/rules/importers/_spreadsheet2rules.py,sha256=Td5w03RCY7ligcLHrSEiCLMHngwLuwgTSSUruMe3jz8,11397
187
187
  cognite/neat/rules/importers/_yaml2rules.py,sha256=LzcfsdKgU28TPAqxG5q3y09rJbUPbMhBWZRt0Z5bU3k,4299
188
188
  cognite/neat/rules/issues/__init__.py,sha256=Ms6jgCxCezc5IgTOwCFtXQPtoVFfOvdcXj84_rs917I,563
189
- cognite/neat/rules/issues/base.py,sha256=qgoZ3qr35XLtdmkWWewf3sCYOW0sCkJrN9VpFvX-WzY,6158
190
- cognite/neat/rules/issues/dms.py,sha256=uNBRgWOBg25K5yKkUtif8fn1ixG1BvvUooShk9uot4w,15330
191
- cognite/neat/rules/issues/fileread.py,sha256=n-GZaULOJF_MKkBIh1maaOuGZXOvZYw7Y6fDAS0jrBI,4492
189
+ cognite/neat/rules/issues/base.py,sha256=MpqxzJrAEzPUOSdJEkUE1CvJogyWDN_7YJyoAY6sR_o,6242
190
+ cognite/neat/rules/issues/dms.py,sha256=0xBTYa3b3CPFjsdfKv59l3yX8DLTYB1Jo0LWDhfG6oQ,19178
191
+ cognite/neat/rules/issues/fileread.py,sha256=ao199mtvhPSW0IA8ZQZ0RzuLIIipYtL0jp6fLqxb4_c,5748
192
192
  cognite/neat/rules/issues/formatters.py,sha256=_ag2bJ9hncOj8pAGJvTTEPs9kTtxbD7vkqvS9Zcnizc,3385
193
- cognite/neat/rules/issues/importing.py,sha256=GqUywhBD840Fbc4DD5L2I0oEllJ78MTjpmXogVEjihA,7493
194
- cognite/neat/rules/issues/spreadsheet.py,sha256=Iyje5xqgDN3nhpF9hi1Nm-baCXMxOLYVXZ8_jE18zLI,13763
193
+ cognite/neat/rules/issues/importing.py,sha256=p90847g_TbUAXMyxalcEaWXaPygJoSE5E85dQO4syoo,12288
194
+ cognite/neat/rules/issues/spreadsheet.py,sha256=-jMcamtvDIACKiIHtDNafjiMgovVN-VthyqE1FaSy-0,13936
195
195
  cognite/neat/rules/issues/spreadsheet_file.py,sha256=YCp0Pk_TsiqYuOPdWpjUpre-zvi2c5_MvrC_dxw10YY,4964
196
196
  cognite/neat/rules/models/data_types.py,sha256=lanwkhwG8iHKfjYfia4v2SBTJrMeXOsqaVkVEP2QMXs,6078
197
- cognite/neat/rules/models/entities.py,sha256=riRJXlK9Q_uRqCbk8J-GxOoNwOhu8e8KRIW1Vtao6Zo,15477
197
+ cognite/neat/rules/models/entities.py,sha256=iBG84Jr1qQ7PvkMJUJzJ1oWApeONb1IACixdJSztUhk,16395
198
198
  cognite/neat/rules/models/rdfpath.py,sha256=RoHnfWufjnDtwJh7UUzWKoJz8luvX7Gb5SDQORfkQTE,11030
199
199
  cognite/neat/rules/models/rules/__init__.py,sha256=YHzkEkDzDuPs9N69FP12SAbnOBiLOxk0m5jXH-IQgbY,522
200
- cognite/neat/rules/models/rules/_base.py,sha256=CKFrEFeLROq6IWDb5SfYTRJqsrOm0gvB-MGudMKBQqo,11024
201
- cognite/neat/rules/models/rules/_dms_architect_rules.py,sha256=A7Wh7DLOvJMcibhXdi6F5fQNRfOEOF2jo0NQPGZIAvk,52602
202
- cognite/neat/rules/models/rules/_dms_rules_write.py,sha256=JYo39XvaWsRtsfmgm9U3rThi7eMcS4W0nm6gns72-gM,12810
203
- cognite/neat/rules/models/rules/_dms_schema.py,sha256=BHxp6mhtvK0AFb6LeOHd0vnmrJVXQo78qhmAUOW9e_I,30777
204
- cognite/neat/rules/models/rules/_domain_rules.py,sha256=oa_if8jPSZWN9nS2j-UdxnCSIfjwIWq128cPd_BzLOw,2655
205
- cognite/neat/rules/models/rules/_information_rules.py,sha256=Cc1eB3rLj-WFvKOl45cgANjC_6oaYQE6Rs-Yeg7wLEk,22015
200
+ cognite/neat/rules/models/rules/_base.py,sha256=bFH_HSftl960ROroUMy5jjXdIir6lm3tHK2qJmc-UG8,10876
201
+ cognite/neat/rules/models/rules/_dms_architect_rules.py,sha256=sGlV_hOyQemtUUwYC_fwtihk40PlU7WrlywdagP65fI,58546
202
+ cognite/neat/rules/models/rules/_dms_rules_write.py,sha256=12fkwQY5c0Y6SGM_pU6pEAqjUO2VuB3cPOAVllwUOkQ,13135
203
+ cognite/neat/rules/models/rules/_dms_schema.py,sha256=ySGa0Qe_puGjXg1T-Ec0Kzvobqn60D5toFuSzeLuzW0,35870
204
+ cognite/neat/rules/models/rules/_domain_rules.py,sha256=2S74P9YPPtb6myx8wg3-el9jrEBMH9AOBg9dAfwzlh4,2934
205
+ cognite/neat/rules/models/rules/_information_rules.py,sha256=ni2KSHHG9nBqho50Sn5C7HJRHZCPatNUSM1xQSn_0lI,22447
206
206
  cognite/neat/rules/models/rules/_types/__init__.py,sha256=l1tGxzE7ezNHIL72AoEvNHN2IFuitxOLxiHJG__s6t4,305
207
207
  cognite/neat/rules/models/rules/_types/_base.py,sha256=2GhLUE1ukV8X8SGL_JDxpbWGZyAvOnSqAE6JmDh5wbI,929
208
208
  cognite/neat/rules/models/rules/_types/_field.py,sha256=74WfCSVbTubpK4n4VsysQqCch6VI8IcPqnHQpvNbFZ8,3197
209
+ cognite/neat/rules/models/wrapped_entities.py,sha256=c5GkzOrYrE6SSRzIS2r8OAjhwxXpOoAO1WGc8kwiPPo,6154
209
210
  cognite/neat/utils/__init__.py,sha256=l5Nyqhqo25bcQXCOb_lk01cr-UXsG8cczz_y_I0u6bg,68
210
211
  cognite/neat/utils/auxiliary.py,sha256=E2-YtddzScvN7l7j0kNYIMlfqIUT9NWMqLpcJYPK4rY,309
211
212
  cognite/neat/utils/cdf.py,sha256=dTg8wnm2916yhWT_2Jg9_PlauHCbmnuNgmpqrGU8eO0,711
@@ -263,8 +264,8 @@ cognite/neat/workflows/steps_registry.py,sha256=fkTX14ZA7_gkUYfWIlx7A1XbCidvqR23
263
264
  cognite/neat/workflows/tasks.py,sha256=dqlJwKAb0jlkl7abbY8RRz3m7MT4SK8-7cntMWkOYjw,788
264
265
  cognite/neat/workflows/triggers.py,sha256=_BLNplzoz0iic367u1mhHMHiUrCwP-SLK6_CZzfODX0,7071
265
266
  cognite/neat/workflows/utils.py,sha256=gKdy3RLG7ctRhbCRwaDIWpL9Mi98zm56-d4jfHDqP1E,453
266
- cognite_neat-0.75.9.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
267
- cognite_neat-0.75.9.dist-info/METADATA,sha256=fF2tMkrPlJv7YTy1GCBZ23mBH282qIwbqKN1xOCAfyY,9316
268
- cognite_neat-0.75.9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
269
- cognite_neat-0.75.9.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
270
- cognite_neat-0.75.9.dist-info/RECORD,,
267
+ cognite_neat-0.76.1.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
268
+ cognite_neat-0.76.1.dist-info/METADATA,sha256=WbYTbZfKFf2l9ASMKwMVGYW_otwMLULyqp1K0WfIqOY,9316
269
+ cognite_neat-0.76.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
270
+ cognite_neat-0.76.1.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
271
+ cognite_neat-0.76.1.dist-info/RECORD,,