cognite-neat 0.85.11__py3-none-any.whl → 0.85.12__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.85.11"
1
+ __version__ = "0.85.12"
@@ -2,7 +2,7 @@ import json
2
2
  from collections import defaultdict
3
3
  from collections.abc import Iterable, Sequence
4
4
  from pathlib import Path
5
- from typing import Any
5
+ from typing import Any, get_args
6
6
 
7
7
  import yaml
8
8
  from cognite.client import CogniteClient
@@ -20,7 +20,7 @@ from cognite.neat.graph.issues import loader as loader_issues
20
20
  from cognite.neat.graph.stores import NeatGraphStore
21
21
  from cognite.neat.issues import NeatIssue, NeatIssueList
22
22
  from cognite.neat.rules.models import DMSRules
23
- from cognite.neat.rules.models.data_types import _DATA_TYPE_BY_DMS_TYPE
23
+ from cognite.neat.rules.models.data_types import _DATA_TYPE_BY_DMS_TYPE, Json
24
24
  from cognite.neat.utils.upload import UploadResult
25
25
  from cognite.neat.utils.utils import create_sha256_hash
26
26
 
@@ -145,7 +145,9 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
145
145
  issues = NeatIssueList[NeatIssue]()
146
146
  field_definitions: dict[str, tuple[type, Any]] = {}
147
147
  edge_by_property: dict[str, dm.EdgeConnection] = {}
148
+ validators: dict[str, classmethod] = {}
148
149
  direct_relation_by_property: dict[str, dm.DirectRelation] = {}
150
+ json_fields: list[str] = []
149
151
  for prop_name, prop in view.properties.items():
150
152
  if isinstance(prop, dm.EdgeConnection):
151
153
  edge_by_property[prop_name] = prop
@@ -163,6 +165,9 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
163
165
  )
164
166
  )
165
167
  continue
168
+
169
+ if data_type == Json:
170
+ json_fields.append(prop_name)
166
171
  python_type = data_type.python
167
172
  if prop.type.is_list:
168
173
  python_type = list[python_type]
@@ -175,13 +180,29 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
175
180
  field_definitions[prop_name] = (python_type, default_value)
176
181
 
177
182
  def parse_list(cls, value: Any, info: ValidationInfo) -> list[str]:
178
- if isinstance(value, list) and cls.model_fields[info.field_name].annotation is not list:
183
+ if isinstance(value, list) and list.__name__ not in _get_field_value_types(cls, info):
179
184
  if len(value) == 1:
180
185
  return value[0]
181
186
  raise ValueError(f"Got multiple values for {info.field_name}: {value}")
187
+
182
188
  return value
183
189
 
184
- validators: dict[str, classmethod] = {"parse_list": field_validator("*", mode="before")(parse_list)} # type: ignore[dict-item,arg-type]
190
+ def parse_json_string(cls, value: Any, info: ValidationInfo) -> dict:
191
+ if isinstance(value, dict):
192
+ return value
193
+ elif isinstance(value, str):
194
+ try:
195
+ return json.loads(value)
196
+ except json.JSONDecodeError as error:
197
+ raise ValueError(f"Not valid JSON string for {info.field_name}: {value}, error {error}") from error
198
+ else:
199
+ raise ValueError(f"Expect valid JSON string or dict for {info.field_name}: {value}")
200
+
201
+ if json_fields:
202
+ validators["parse_json_string"] = field_validator(*json_fields, mode="before")(parse_json_string) # type: ignore[assignment, arg-type]
203
+
204
+ validators["parse_list"] = field_validator("*", mode="before")(parse_list) # type: ignore[assignment, arg-type]
205
+
185
206
  if direct_relation_by_property:
186
207
 
187
208
  def parse_direct_relation(cls, value: list, info: ValidationInfo) -> dict | list[dict]:
@@ -280,7 +301,10 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
280
301
  result.created.update(item.as_id() for item in e.successful)
281
302
  yield result
282
303
  else:
283
- for instance_type, instances in {"Nodes": upserted.nodes, "Edges": upserted.edges}.items():
304
+ for instance_type, instances in {
305
+ "Nodes": upserted.nodes,
306
+ "Edges": upserted.edges,
307
+ }.items():
284
308
  result = UploadResult[InstanceId](name=instance_type, issues=read_issues)
285
309
  for instance in instances: # type: ignore[attr-defined]
286
310
  if instance.was_modified and instance.created_time == instance.last_updated_time:
@@ -292,6 +316,10 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
292
316
  yield result
293
317
 
294
318
 
319
+ def _get_field_value_types(cls, info):
320
+ return [type_.__name__ for type_ in get_args(cls.model_fields[info.field_name].annotation)]
321
+
322
+
295
323
  def _triples2dictionary(
296
324
  triples: Iterable[tuple[str, str, str]],
297
325
  ) -> dict[str, dict[str, list[str]]]:
@@ -75,7 +75,9 @@ class InferenceImporter(BaseImporter):
75
75
  self.graph = graph
76
76
  self.max_number_of_instance = max_number_of_instance
77
77
  self.prefix = prefix
78
- self.check_for_json_string = check_for_json_string
78
+ self.check_for_json_string = (
79
+ check_for_json_string if graph.store.__class__.__name__ != "OxigraphStore" else False
80
+ )
79
81
 
80
82
  @classmethod
81
83
  def from_graph_store(
@@ -235,6 +237,7 @@ class InferenceImporter(BaseImporter):
235
237
  query.replace("instance_id", instance)
236
238
  ): # type: ignore[misc]
237
239
  property_id = remove_namespace_from_uri(property_uri)
240
+
238
241
  self._add_uri_namespace_to_prefixes(cast(URIRef, property_uri), prefixes)
239
242
  value_type_uri = data_type_uri if data_type_uri else object_type_uri
240
243
 
@@ -237,7 +237,7 @@ class Literal(DataType):
237
237
 
238
238
  class Timeseries(DataType):
239
239
  name = "timeseries"
240
- python = dms.TimeSeriesReference
240
+ python = str
241
241
  dms = dms.TimeSeriesReference
242
242
  graphql = "TimeSeries"
243
243
  xsd = "string"
@@ -246,7 +246,7 @@ class Timeseries(DataType):
246
246
 
247
247
  class File(DataType):
248
248
  name = "file"
249
- python = dms.FileReference
249
+ python = str
250
250
  dms = dms.FileReference
251
251
  graphql = "File"
252
252
  xsd = "string"
@@ -255,7 +255,7 @@ class File(DataType):
255
255
 
256
256
  class Sequence(DataType):
257
257
  name = "sequence"
258
- python = dms.SequenceReference
258
+ python = str
259
259
  dms = dms.SequenceReference
260
260
  graphql = "Sequence"
261
261
  xsd = "string"
@@ -264,7 +264,7 @@ class Sequence(DataType):
264
264
 
265
265
  class Json(DataType):
266
266
  name = "json"
267
- python = dms.Json
267
+ python = dict
268
268
  dms = dms.Json
269
269
  graphql = "Json"
270
270
  xsd = "json"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cognite-neat
3
- Version: 0.85.11
3
+ Version: 0.85.12
4
4
  Summary: Knowledge graph transformation
5
5
  Home-page: https://cognite-neat.readthedocs-hosted.com/
6
6
  License: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  cognite/neat/__init__.py,sha256=AiexNcHdAHFbrrbo9c65gtil1dqx_SGraDH1PSsXjKE,126
2
2
  cognite/neat/_shared.py,sha256=RSaHm2eJceTlvb-hMMe4nHgoHdPYDfN3XcxDXo24k3A,1530
3
- cognite/neat/_version.py,sha256=bVP2BELxIGHP-amVHOwETotJ5zyQqFcbe7c26GvSm-c,24
3
+ cognite/neat/_version.py,sha256=-maJxb8aUZ1rcA-KV9euznsvf6nRe-1WsOW0KTCm1zM,24
4
4
  cognite/neat/app/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  cognite/neat/app/api/asgi/metrics.py,sha256=nxFy7L5cChTI0a-zkCiJ59Aq8yLuIJp5c9Dg0wRXtV0,152
6
6
  cognite/neat/app/api/configuration.py,sha256=2U5M6M252swvQPQyooA1EBzFUZNtcTmuSaywfJDgckM,4232
@@ -72,7 +72,7 @@ cognite/neat/graph/issues/loader.py,sha256=v8YDsehkUT1QUG61JM9BDV_lqowMUnDmGmbay
72
72
  cognite/neat/graph/loaders/__init__.py,sha256=BteVkTklPVUB2W-bbzZug-cEUrx8ZFA-YcQPSxWVpTI,678
73
73
  cognite/neat/graph/loaders/_base.py,sha256=yIXJ7H5VeVb_mqMCM36BYyEOQMbIZcV60RxqD-Xrj-Y,3032
74
74
  cognite/neat/graph/loaders/_rdf2asset.py,sha256=aFby7BwIrW253LEJ4XqGeUuf4jG9VUe8Lg7OlUnXMlM,4493
75
- cognite/neat/graph/loaders/_rdf2dms.py,sha256=2PCL8De02xlEkTmgG299k5tiZcKPnoNzCQfI1AgS2Gg,14060
75
+ cognite/neat/graph/loaders/_rdf2dms.py,sha256=r9SPbJyqLN9wSi6LSoxnQXJ0M9PXxpVd4eeC0Z0bJ4Q,15138
76
76
  cognite/neat/graph/models.py,sha256=AtLgZh2qyRP6NRetjQCy9qLMuTQB0CH52Zsev-qa2sk,149
77
77
  cognite/neat/graph/queries/__init__.py,sha256=BgDd-037kvtWwAoGAy8eORVNMiZ5-E9sIV0txIpeaN4,50
78
78
  cognite/neat/graph/queries/_base.py,sha256=yO1i2HPA2RiXMehANImDPxSkL6QB6LwvD22HvfdFt70,6023
@@ -203,7 +203,7 @@ cognite/neat/rules/importers/_dtdl2rules/_unit_lookup.py,sha256=wW4saKva61Q_i17g
203
203
  cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py,sha256=ysmWUxZ0npwrTB0uiH5jA0v37sfCwowGaYk17IyxPUU,12663
204
204
  cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py,sha256=Psj3C2jembY_Wu7WWJIFIwrMawvjISjeqfBnoRy_csw,6740
205
205
  cognite/neat/rules/importers/_dtdl2rules/spec.py,sha256=tim_MfN1J0F3Oeqk3BMgIA82d_MZvhRuRMsLK3B4PYc,11897
206
- cognite/neat/rules/importers/_inference2rules.py,sha256=U2fNqBtN_NMtFAm7uSiejfxNFWIvUjHv5JriOEI5Z3I,13704
206
+ cognite/neat/rules/importers/_inference2rules.py,sha256=9ndiy36aJSR-I5wTUcC9vb08zWUZshrSTiunplXtt40,13793
207
207
  cognite/neat/rules/importers/_owl2rules/__init__.py,sha256=tdGcrgtozdQyST-pTlxIa4cLBNTLvtk1nNYR4vOdFSw,63
208
208
  cognite/neat/rules/importers/_owl2rules/_owl2classes.py,sha256=dACjYeCa_OhpQgqccI4w478dEINbISUMzpVkCOoRRL8,7384
209
209
  cognite/neat/rules/importers/_owl2rules/_owl2metadata.py,sha256=nwnUaBNAAYMoBre2UmsnkJXUuaqGEpR3U3txDrH2w6g,7527
@@ -232,7 +232,7 @@ cognite/neat/rules/models/asset/_rules.py,sha256=fYp1pMJtioUtT747fo5NX69lgvPiPtH
232
232
  cognite/neat/rules/models/asset/_rules_input.py,sha256=LiT-85CVgDz2ng65CtrRa77r4rnmg3E4Q6DC7-gv0dE,6257
233
233
  cognite/neat/rules/models/asset/_serializer.py,sha256=ixqRf9qEzvChgysRaDX4g_vHVDtRBCsPYC9sOn0-ShE,3365
234
234
  cognite/neat/rules/models/asset/_validation.py,sha256=86ymEgMZpG1eWu53PviUyUFnQBUJmYDZggUDXufBYLI,148
235
- cognite/neat/rules/models/data_types.py,sha256=xAjm8UVEQlSylfkUJWiWP2NaK6dLYRDABF9g8CNWLTc,6076
235
+ cognite/neat/rules/models/data_types.py,sha256=mHTjWh47VzLwrr0w6dRf59LW7pTTGRTgsxvtW9p0JWw,6020
236
236
  cognite/neat/rules/models/dms/__init__.py,sha256=Wzyqzz2ZIjpUbDg04CMuuIAw-f2A02DayNeqO9R-2Hw,491
237
237
  cognite/neat/rules/models/dms/_converter.py,sha256=QaJT0z0Yo4gkG9tHPZkU8idF8PK7c-tDahbyIT-WJQU,5959
238
238
  cognite/neat/rules/models/dms/_exporter.py,sha256=DRL5ahcBEdBltHLA2rzLyUfqG5SZkqINkqmYGDkQVg0,24785
@@ -310,8 +310,8 @@ cognite/neat/workflows/steps_registry.py,sha256=fkTX14ZA7_gkUYfWIlx7A1XbCidvqR23
310
310
  cognite/neat/workflows/tasks.py,sha256=dqlJwKAb0jlkl7abbY8RRz3m7MT4SK8-7cntMWkOYjw,788
311
311
  cognite/neat/workflows/triggers.py,sha256=_BLNplzoz0iic367u1mhHMHiUrCwP-SLK6_CZzfODX0,7071
312
312
  cognite/neat/workflows/utils.py,sha256=gKdy3RLG7ctRhbCRwaDIWpL9Mi98zm56-d4jfHDqP1E,453
313
- cognite_neat-0.85.11.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
314
- cognite_neat-0.85.11.dist-info/METADATA,sha256=dofrglhVYBscSaExRgcBzxsXGN7a1cNkk1srGCk692w,9494
315
- cognite_neat-0.85.11.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
316
- cognite_neat-0.85.11.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
317
- cognite_neat-0.85.11.dist-info/RECORD,,
313
+ cognite_neat-0.85.12.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
314
+ cognite_neat-0.85.12.dist-info/METADATA,sha256=iXaYsEhgfabYjlSz-VmgIBNiey3yu1qop3A0f6ClwAY,9494
315
+ cognite_neat-0.85.12.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
316
+ cognite_neat-0.85.12.dist-info/entry_points.txt,sha256=61FPqiWb25vbqB0KI7znG8nsg_ibLHBvTjYnkPvNFso,50
317
+ cognite_neat-0.85.12.dist-info/RECORD,,