cognite-neat 0.96.0__py3-none-any.whl → 0.96.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.

@@ -19,7 +19,17 @@ def _is_in_notebook() -> bool:
19
19
  return True
20
20
 
21
21
 
22
- IN_NOTEBOOK = _is_in_notebook()
22
+ def _is_in_browser() -> bool:
23
+ try:
24
+ from pyodide.ffi import IN_BROWSER # type: ignore [import-not-found]
25
+ except ModuleNotFoundError:
26
+ return False
27
+ return IN_BROWSER
28
+
29
+
30
+ IN_PYODIDE = _is_in_browser()
31
+ IN_NOTEBOOK = _is_in_notebook() or IN_PYODIDE
32
+
23
33
 
24
34
  PACKAGE_DIRECTORY = Path(neat.__file__).parent
25
35
  COGNITE_MODELS = (
@@ -346,7 +346,7 @@ class DMSImporter(BaseImporter[DMSInputRules]):
346
346
  property_=prop_id,
347
347
  description=prop.description,
348
348
  name=prop.name,
349
- connection=self._get_connection_type(prop_id, prop, view_entity.as_id()),
349
+ connection=self._get_connection_type(prop),
350
350
  value_type=str(value_type),
351
351
  is_list=self._get_is_list(prop),
352
352
  nullable=self._get_nullable(prop),
@@ -367,19 +367,13 @@ class DMSImporter(BaseImporter[DMSInputRules]):
367
367
  return self._all_containers_by_id[prop.container].properties[prop.container_property_identifier]
368
368
 
369
369
  def _get_connection_type(
370
- self, prop_id: str, prop: ViewPropertyApply, view_id: dm.ViewId
370
+ self, prop: ViewPropertyApply
371
371
  ) -> Literal["direct"] | ReverseConnectionEntity | EdgeEntity | None:
372
- if isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "outwards":
372
+ if isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply):
373
373
  properties = ViewEntity.from_id(prop.edge_source) if prop.edge_source is not None else None
374
- return EdgeEntity(properties=properties, type=DMSNodeEntity.from_reference(prop.type), direction="outwards")
375
- elif isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "inwards":
376
- if reverse_prop := self._find_reverse_edge(prop_id, prop, view_id):
377
- return ReverseConnectionEntity(property=reverse_prop)
378
- else:
379
- properties = ViewEntity.from_id(prop.source) if prop.edge_source is not None else None
380
- return EdgeEntity(
381
- properties=properties, type=DMSNodeEntity.from_reference(prop.type), direction="inwards"
382
- )
374
+ return EdgeEntity(
375
+ properties=properties, type=DMSNodeEntity.from_reference(prop.type), direction=prop.direction
376
+ )
383
377
  elif isinstance(prop, SingleReverseDirectRelationApply | MultiReverseDirectRelationApply):
384
378
  return ReverseConnectionEntity(property=prop.through.property)
385
379
  elif isinstance(prop, dm.MappedPropertyApply) and isinstance(
@@ -565,7 +565,7 @@ class _DMSExporter:
565
565
  return edge_cls(
566
566
  type=cls._create_edge_type_from_prop(prop),
567
567
  source=source_view_id,
568
- direction="outwards",
568
+ direction=prop.connection.direction,
569
569
  name=prop.name,
570
570
  description=prop.description,
571
571
  edge_source=edge_source,
@@ -580,7 +580,6 @@ class _DMSExporter:
580
580
  "If this error occurs it is a bug in NEAT, please report"
581
581
  f"Debug Info, Invalid valueType reverse connection: {prop.model_dump_json()}"
582
582
  )
583
- edge_source = None
584
583
  reverse_prop = next(
585
584
  (
586
585
  prop
@@ -589,13 +588,6 @@ class _DMSExporter:
589
588
  ),
590
589
  None,
591
590
  )
592
- if (
593
- reverse_prop
594
- and isinstance(reverse_prop.connection, EdgeEntity)
595
- and reverse_prop.connection.properties is not None
596
- ):
597
- edge_source = reverse_prop.connection.properties.as_id()
598
-
599
591
  if reverse_prop is None:
600
592
  warnings.warn(
601
593
  PropertyNotFoundWarning(
@@ -608,30 +600,17 @@ class _DMSExporter:
608
600
  stacklevel=2,
609
601
  )
610
602
 
611
- if reverse_prop is None or isinstance(reverse_prop.connection, EdgeEntity):
612
- inwards_edge_cls = (
613
- dm.MultiEdgeConnectionApply if prop.is_list in [True, None] else SingleEdgeConnectionApply
614
- )
615
- return inwards_edge_cls(
616
- type=cls._create_edge_type_from_prop(reverse_prop or prop),
617
- source=source_view_id,
618
- name=prop.name,
619
- description=prop.description,
620
- direction="inwards",
621
- edge_source=edge_source,
622
- )
623
- elif reverse_prop and reverse_prop.connection == "direct":
624
- reverse_direct_cls = (
625
- dm.MultiReverseDirectRelationApply
626
- if prop.is_list in [True, None]
627
- else SingleReverseDirectRelationApply
628
- )
629
- return reverse_direct_cls(
603
+ if reverse_prop and reverse_prop.connection == "direct":
604
+ args: dict[str, Any] = dict(
630
605
  source=source_view_id,
631
606
  through=dm.PropertyId(source=source_view_id, property=reverse_prop_id),
632
607
  name=prop.name,
633
608
  description=prop.description,
634
609
  )
610
+ if prop.is_list in [True, None]:
611
+ return dm.MultiReverseDirectRelationApply(**args)
612
+ else:
613
+ return SingleReverseDirectRelationApply(**args)
635
614
  else:
636
615
  return None
637
616
 
@@ -1,12 +1,16 @@
1
1
  from typing import Literal, cast
2
2
 
3
3
  from cognite.client import CogniteClient
4
+ from cognite.client import data_modeling as dm
4
5
 
5
6
  from cognite.neat import _version
6
7
  from cognite.neat._issues import IssueList
7
8
  from cognite.neat._rules import importers
8
9
  from cognite.neat._rules._shared import ReadRules
10
+ from cognite.neat._rules.importers._rdf._base import DEFAULT_NON_EXISTING_NODE_TYPE
9
11
  from cognite.neat._rules.models import DMSRules
12
+ from cognite.neat._rules.models.data_types import AnyURI
13
+ from cognite.neat._rules.models.entities._single_value import UnknownEntity
10
14
  from cognite.neat._rules.models.information._rules import InformationRules
11
15
  from cognite.neat._rules.models.information._rules_input import InformationInputRules
12
16
  from cognite.neat._rules.transformers import ConvertToRules, VerifyAnyRules
@@ -51,7 +55,7 @@ class NeatSession:
51
55
  self._state.store.add_rules(output.rules)
52
56
  self._state.issue_lists.append(output.issues)
53
57
  if output.issues:
54
- print("You can inspect the issues with the .inspect attribute.")
58
+ print("You can inspect the issues with the .inspect.issues(...) method.")
55
59
  return output.issues
56
60
 
57
61
  def convert(self, target: Literal["dms"]) -> None:
@@ -62,15 +66,34 @@ class NeatSession:
62
66
 
63
67
  def infer(
64
68
  self,
65
- space: str = "inference_space",
66
- external_id: str = "InferredDataModel",
67
- version: str = "v1",
69
+ model_id: dm.DataModelId | tuple[str, str, str] = (
70
+ "neat_space",
71
+ "NeatInferredDataModel",
72
+ "v1",
73
+ ),
74
+ non_existing_node_type: UnknownEntity | AnyURI = DEFAULT_NON_EXISTING_NODE_TYPE,
68
75
  ) -> IssueList:
69
- input_rules: ReadRules = importers.InferenceImporter.from_graph_store(self._state.store).to_rules()
76
+ """Data model inference from instances.
70
77
 
71
- cast(InformationInputRules, input_rules.rules).metadata.prefix = space
72
- cast(InformationInputRules, input_rules.rules).metadata.name = external_id
73
- cast(InformationInputRules, input_rules.rules).metadata.version = version
78
+ Args:
79
+ model_id: The ID of the inferred data model.
80
+ non_existing_node_type: The type of node to use when type of node is not possible to determine.
81
+ """
82
+
83
+ model_id = dm.DataModelId.load(model_id)
84
+
85
+ input_rules: ReadRules = importers.InferenceImporter.from_graph_store(
86
+ store=self._state.store,
87
+ non_existing_node_type=non_existing_node_type,
88
+ ).to_rules()
89
+
90
+ if model_id.space:
91
+ cast(InformationInputRules, input_rules.rules).metadata.prefix = model_id.space
92
+ if model_id.external_id:
93
+ cast(InformationInputRules, input_rules.rules).metadata.name = model_id.external_id
94
+
95
+ if model_id.version:
96
+ cast(InformationInputRules, input_rules.rules).metadata.version = model_id.version
74
97
 
75
98
  self.read.rdf._store_rules(self._state.store, input_rules, "Data Model Inference")
76
99
  return input_rules.issues
@@ -3,9 +3,10 @@ import random
3
3
  from typing import Any, cast
4
4
 
5
5
  import networkx as nx
6
+ from IPython.display import HTML, display
6
7
  from pyvis.network import Network as PyVisNetwork # type: ignore
7
8
 
8
- from cognite.neat._constants import IN_NOTEBOOK
9
+ from cognite.neat._constants import IN_NOTEBOOK, IN_PYODIDE
9
10
  from cognite.neat._rules._constants import EntityTypes
10
11
  from cognite.neat._rules.models.dms._rules import DMSRules
11
12
  from cognite.neat._rules.models.entities._single_value import ClassEntity, ViewEntity
@@ -31,6 +32,9 @@ class ShowBaseAPI:
31
32
  self._state = state
32
33
 
33
34
  def _generate_visualization(self, di_graph: nx.DiGraph, name: str) -> Any:
35
+ if not IN_NOTEBOOK:
36
+ raise NeatSessionError("Visualization is only available in Jupyter notebooks!")
37
+
34
38
  net = PyVisNetwork(
35
39
  notebook=IN_NOTEBOOK,
36
40
  cdn_resources="remote",
@@ -50,7 +54,12 @@ class ShowBaseAPI:
50
54
  )
51
55
 
52
56
  net.from_nx(di_graph)
53
- return net.show(name)
57
+ if IN_PYODIDE:
58
+ net.write_html(name)
59
+ return display(HTML(name))
60
+
61
+ else:
62
+ return net.show(name)
54
63
 
55
64
 
56
65
  @intercept_session_exceptions
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
- from typing import Any, overload
2
+ from typing import Any, Literal, overload
3
3
 
4
4
  from cognite.client import CogniteClient
5
5
 
@@ -61,11 +61,17 @@ class CDFToAPI:
61
61
 
62
62
  return loader.load_into_cdf(self._client)
63
63
 
64
- def data_model(self):
64
+ def data_model(self, existing_handling: Literal["fail", "skip", "update", "force"] = "skip"):
65
+ """Export the verified DMS data model to CDF.
66
+
67
+ Args:
68
+ existing_handling: How to handle if component of data model exists. Defaults to "skip".
69
+
70
+ """
65
71
  if not self._state.last_verified_dms_rules:
66
72
  raise ValueError("No verified DMS data model available")
67
73
 
68
- exporter = exporters.DMSExporter()
74
+ exporter = exporters.DMSExporter(existing_handling=existing_handling)
69
75
 
70
76
  if not self._client:
71
77
  raise ValueError("No client provided!")
cognite/neat/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.96.0"
1
+ __version__ = "0.96.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cognite-neat
3
- Version: 0.96.0
3
+ Version: 0.96.2
4
4
  Summary: Knowledge graph transformation
5
5
  Home-page: https://cognite-neat.readthedocs-hosted.com/
6
6
  License: Apache-2.0
@@ -72,7 +72,7 @@ cognite/neat/_app/ui/neat-app/src/views/GlobalConfigView.tsx,sha256=1NMOby21Arrf
72
72
  cognite/neat/_app/ui/neat-app/src/views/WorkflowView.tsx,sha256=dU6xZip3MVaVzKAF23Cu6qZTl2Dn_evO-RTDAVGfONg,18451
73
73
  cognite/neat/_app/ui/neat-app/tsconfig.json,sha256=sw7AweQXRyJAIQ8Beft_380Q8zBr54pG1P_wutdPAIQ,664
74
74
  cognite/neat/_config.py,sha256=f9Py4SEHwYYquIg-k1rC7MbXBLENXQauoZtLyUbWvJQ,10118
75
- cognite/neat/_constants.py,sha256=rd61fuEEJcbyDIqSl5lh6QE7MBVqJiDmbfYUPptREPo,1649
75
+ cognite/neat/_constants.py,sha256=_A-rsl18bPZCJmTSZ5jBvhO2k7kJrb2G9Hae1DEmuQ4,1888
76
76
  cognite/neat/_graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
77
  cognite/neat/_graph/_shared.py,sha256=WTDR46N3V8GZRZaqXcqR_IJnlMCQU7aT9xUmr_jBwFE,927
78
78
  cognite/neat/_graph/_tracking/__init__.py,sha256=pYj7c-YAUIP4hvN-4mlWnwaeZFerzL9_gM-oZhex7cE,91
@@ -152,7 +152,7 @@ cognite/neat/_rules/exporters/_rules2yaml.py,sha256=O9vnzDHf1ep1Qu0po0GVjgu945HN
152
152
  cognite/neat/_rules/exporters/_validation.py,sha256=DVJGdNNU2WtAFgUg0h4SWVhveRErEPOcYdT65y5toV0,682
153
153
  cognite/neat/_rules/importers/__init__.py,sha256=z682_ktGKDjr52DIL6cPvOercZS6-TYD_ZDo-MGqtck,1207
154
154
  cognite/neat/_rules/importers/_base.py,sha256=S-9Mi_58IvrIZ3oZaPRFnRWVIVhewcqGp8tng3q6kbw,2982
155
- cognite/neat/_rules/importers/_dms2rules.py,sha256=Hpjn8fPmH8f_Jnxx9RnS6nlqe-2JH1haiLy0ygg3nXU,22904
155
+ cognite/neat/_rules/importers/_dms2rules.py,sha256=Q3L4N5b4-Db24EL-sttPBpVRWpvnRI-Tx_hSV86pTPo,22291
156
156
  cognite/neat/_rules/importers/_dtdl2rules/__init__.py,sha256=CNR-sUihs2mnR1bPMKs3j3L4ds3vFTsrl6YycExZTfU,68
157
157
  cognite/neat/_rules/importers/_dtdl2rules/_unit_lookup.py,sha256=wW4saKva61Q_i17guY0dc4OseJDQfqHy_QZBtm0OD6g,12134
158
158
  cognite/neat/_rules/importers/_dtdl2rules/dtdl_converter.py,sha256=BwClXc1ONzWacXbdoG5741Vj7knhJL1rRgyHh0X194Y,11911
@@ -185,7 +185,7 @@ cognite/neat/_rules/models/asset/_rules_input.py,sha256=-8s79O1DnwNQNPjJhcdzBlJv
185
185
  cognite/neat/_rules/models/asset/_validation.py,sha256=6u86qLlr1ehG1I5kIZhfCYTqUenuxUu9n_d7yWMUrS0,2021
186
186
  cognite/neat/_rules/models/data_types.py,sha256=ACQjS9vs7EjaNSO8R1kHiiNYbdeVQLCvxJYfZhWF8mM,9620
187
187
  cognite/neat/_rules/models/dms/__init__.py,sha256=CUqUlVjz4yZX_-61F-2ofSoV7N9MlSYx2N7vM-omp7E,640
188
- cognite/neat/_rules/models/dms/_exporter.py,sha256=dZAl5439p2K6LsA4yNpwCsEgNsxVkGjcmV9JGL3JAYE,30345
188
+ cognite/neat/_rules/models/dms/_exporter.py,sha256=u9lLHwa6DUsh-xlaSbuU1YV5-xvbXObAocWvsRphGfc,29438
189
189
  cognite/neat/_rules/models/dms/_rules.py,sha256=JCYss9Nqf2tloyZj4gZktaW_45gMCjw7aLf5XeD_kRk,19980
190
190
  cognite/neat/_rules/models/dms/_rules_input.py,sha256=MjkkoEa5lRzQE0NUJ7TyQsrelWSoyGCCDFjMVG5pQvc,11530
191
191
  cognite/neat/_rules/models/dms/_schema.py,sha256=HSmSDvOm5S0x4Vb9tH9Jvd5i9tXiiM08E_Sdu6q_iA8,50783
@@ -212,14 +212,14 @@ cognite/neat/_rules/transformers/_mapping.py,sha256=RWHKPMaP3JdeCNvoDGu9ZGHxfyeI
212
212
  cognite/neat/_rules/transformers/_pipelines.py,sha256=-E5Hgitnr6ee8R9_3sqtjmWIPJ0w1xaLErG6Fo6ExVU,2603
213
213
  cognite/neat/_rules/transformers/_verification.py,sha256=330I1i3Va7Nau3DK3bTgEEGSHppmLvT-1yBMocDxV1A,4694
214
214
  cognite/neat/_session/__init__.py,sha256=fxQ5URVlUnmEGYyB8Baw7IDq-uYacqkigbc4b-Pr9Fw,58
215
- cognite/neat/_session/_base.py,sha256=3NB1yA7HsCIv5bN7b6IU6GsH0CDTzuHNjzokuL5jWKk,3691
215
+ cognite/neat/_session/_base.py,sha256=b4hEcSde7n8_bW3DQ8sdRTo77O5GI5RWEuZ4QbkMOgA,4596
216
216
  cognite/neat/_session/_inspect.py,sha256=bucP5w2LKhmzijT222Nm6t0JOZ9K0qOFbK94mCJOTGo,2809
217
217
  cognite/neat/_session/_prepare.py,sha256=6mtJ6OkslSxWhe-xOIB569ml1RHeFUktuFWhrKzZ6Q8,4940
218
218
  cognite/neat/_session/_read.py,sha256=XVfns7ItV41znQQfEYLGi_U3eB2BtnIhkNXtcXte5b4,5563
219
219
  cognite/neat/_session/_set.py,sha256=DRvM5xAJLSs5DibdXFqs1h7yyepXSnHUwcPtfdsmx2w,874
220
- cognite/neat/_session/_show.py,sha256=Mwo1uFIeR58y3gmXPvZkbjg6wqBM08tMzpgJSPNykLw,8217
220
+ cognite/neat/_session/_show.py,sha256=eeS0XRaPtY3GzELWcAQEvQkuMqO706Fcbqgvmt94lFg,8506
221
221
  cognite/neat/_session/_state.py,sha256=U3zPbKvTDAz7rd1yXdkWayY1p_5FJ6-0DIEw6fTD_vA,3292
222
- cognite/neat/_session/_to.py,sha256=3StR71QNEb8JKW-O2iI3aNTlT-wRRaabDg6dovMHWRw,2238
222
+ cognite/neat/_session/_to.py,sha256=wz43PLhAR7FCntrhrIFr4e2jXhm9VKT7Qum3_IuELno,2536
223
223
  cognite/neat/_session/_wizard.py,sha256=Rdld2eZ-Q5BYbmAwW8FlfAYebdlw_P6L6V2WSDk-dHI,1306
224
224
  cognite/neat/_session/exceptions.py,sha256=tVearBcnz7gq0Wn5f7qssCUML_4oxrEvTCj6QnIcCxo,1265
225
225
  cognite/neat/_shared.py,sha256=RSaHm2eJceTlvb-hMMe4nHgoHdPYDfN3XcxDXo24k3A,1530
@@ -242,7 +242,7 @@ cognite/neat/_utils/text.py,sha256=PvTEsEjaTu8SE8yYaKUrce4msboMj933dK7-0Eey_rE,3
242
242
  cognite/neat/_utils/time_.py,sha256=O30LUiDH9TdOYz8_a9pFqTtJdg8vEjC3qHCk8xZblG8,345
243
243
  cognite/neat/_utils/upload.py,sha256=X5GGWHswnW0BrL2ulmm5MnKKtn-t1C8Ps3gb9Byc914,4016
244
244
  cognite/neat/_utils/xml_.py,sha256=FQkq84u35MUsnKcL6nTMJ9ajtG9D5i1u4VBnhGqP2DQ,1710
245
- cognite/neat/_version.py,sha256=B-kjJajURz8O11CWqC3d4KQ5aeL4lukk9XP51Xbpo8o,23
245
+ cognite/neat/_version.py,sha256=h03CgwGcpDkIDSAlWJ_jyHT6Sh8R1n3OUcU2J2058f0,23
246
246
  cognite/neat/_workflows/__init__.py,sha256=S0fZq7kvoqDKodHu1UIPsqcpdvXoefUWRPt1lqeQkQs,420
247
247
  cognite/neat/_workflows/base.py,sha256=O1pcmfbme2gIVF2eOGrKZSUDmhZc8L9rI8UfvLN2YAM,26839
248
248
  cognite/neat/_workflows/cdf_store.py,sha256=3pebnATPo6In4-1srpa3wzstynTOi3T6hwFX5uaie4c,18050
@@ -271,8 +271,8 @@ cognite/neat/_workflows/tasks.py,sha256=dr2xuIb8P5e5e9p_fjzRlvDbKsre2xGYrkc3wnRx
271
271
  cognite/neat/_workflows/triggers.py,sha256=u69xOsaTtM8_WD6ZeIIBB-XKwvlZmPHAsZQh_TnyHcM,7073
272
272
  cognite/neat/_workflows/utils.py,sha256=gKdy3RLG7ctRhbCRwaDIWpL9Mi98zm56-d4jfHDqP1E,453
273
273
  cognite/neat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
274
- cognite_neat-0.96.0.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
275
- cognite_neat-0.96.0.dist-info/METADATA,sha256=uq_pivza7rnpyQzxjrD5VUDkY3gCC-RH_8XdfHQZZ_k,9573
276
- cognite_neat-0.96.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
277
- cognite_neat-0.96.0.dist-info/entry_points.txt,sha256=SsQlnl8SNMSSjE3acBI835JYFtsIinLSbVmHmMEXv6E,51
278
- cognite_neat-0.96.0.dist-info/RECORD,,
274
+ cognite_neat-0.96.2.dist-info/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
275
+ cognite_neat-0.96.2.dist-info/METADATA,sha256=BMCBJIE-W3M9MnQGoSxVZ0v3Wg2O8DcErGcN-0irhIQ,9573
276
+ cognite_neat-0.96.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
277
+ cognite_neat-0.96.2.dist-info/entry_points.txt,sha256=SsQlnl8SNMSSjE3acBI835JYFtsIinLSbVmHmMEXv6E,51
278
+ cognite_neat-0.96.2.dist-info/RECORD,,