cognite-neat 0.101.0__py3-none-any.whl → 0.103.0__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.

Files changed (74) hide show
  1. cognite/neat/__init__.py +1 -1
  2. cognite/neat/_app/api/routers/crud.py +1 -1
  3. cognite/neat/_client/__init__.py +1 -1
  4. cognite/neat/_client/_api/data_modeling_loaders.py +1 -1
  5. cognite/neat/_client/_api/schema.py +1 -1
  6. cognite/neat/_constants.py +5 -1
  7. cognite/neat/_graph/_tracking/__init__.py +1 -1
  8. cognite/neat/_graph/extractors/__init__.py +8 -8
  9. cognite/neat/_graph/extractors/_mock_graph_generator.py +2 -3
  10. cognite/neat/_graph/loaders/_base.py +1 -1
  11. cognite/neat/_graph/loaders/_rdf2dms.py +165 -47
  12. cognite/neat/_graph/queries/_base.py +22 -2
  13. cognite/neat/_graph/queries/_shared.py +4 -4
  14. cognite/neat/_graph/transformers/__init__.py +25 -9
  15. cognite/neat/_graph/transformers/_base.py +1 -1
  16. cognite/neat/_graph/transformers/_iodd.py +2 -2
  17. cognite/neat/_graph/transformers/_prune_graph.py +98 -24
  18. cognite/neat/_graph/transformers/_value_type.py +196 -2
  19. cognite/neat/_issues/__init__.py +6 -6
  20. cognite/neat/_issues/_base.py +4 -4
  21. cognite/neat/_issues/errors/__init__.py +22 -22
  22. cognite/neat/_issues/formatters.py +1 -1
  23. cognite/neat/_issues/warnings/__init__.py +20 -18
  24. cognite/neat/_issues/warnings/_properties.py +7 -0
  25. cognite/neat/_issues/warnings/user_modeling.py +2 -2
  26. cognite/neat/_rules/analysis/__init__.py +1 -1
  27. cognite/neat/_rules/catalog/__init__.py +1 -0
  28. cognite/neat/_rules/catalog/hello_world_pump.xlsx +0 -0
  29. cognite/neat/_rules/exporters/__init__.py +5 -5
  30. cognite/neat/_rules/exporters/_rules2excel.py +12 -6
  31. cognite/neat/_rules/importers/__init__.py +4 -4
  32. cognite/neat/_rules/importers/_base.py +7 -3
  33. cognite/neat/_rules/importers/_dms2rules.py +51 -19
  34. cognite/neat/_rules/importers/_rdf/__init__.py +1 -1
  35. cognite/neat/_rules/importers/_rdf/_base.py +2 -2
  36. cognite/neat/_rules/models/__init__.py +5 -5
  37. cognite/neat/_rules/models/_base_rules.py +1 -1
  38. cognite/neat/_rules/models/dms/__init__.py +11 -11
  39. cognite/neat/_rules/models/dms/_validation.py +16 -10
  40. cognite/neat/_rules/models/entities/__init__.py +26 -26
  41. cognite/neat/_rules/models/information/__init__.py +5 -5
  42. cognite/neat/_rules/models/information/_rules.py +3 -3
  43. cognite/neat/_rules/models/mapping/_classic2core.yaml +54 -8
  44. cognite/neat/_rules/transformers/__init__.py +12 -12
  45. cognite/neat/_rules/transformers/_pipelines.py +10 -5
  46. cognite/neat/_session/_base.py +71 -0
  47. cognite/neat/_session/_collector.py +3 -1
  48. cognite/neat/_session/_drop.py +10 -0
  49. cognite/neat/_session/_inspect.py +35 -1
  50. cognite/neat/_session/_mapping.py +5 -0
  51. cognite/neat/_session/_prepare.py +196 -7
  52. cognite/neat/_session/_read.py +180 -20
  53. cognite/neat/_session/_set.py +11 -1
  54. cognite/neat/_session/_show.py +41 -2
  55. cognite/neat/_session/_to.py +58 -10
  56. cognite/neat/_session/engine/__init__.py +1 -1
  57. cognite/neat/_session/engine/_load.py +3 -1
  58. cognite/neat/_store/__init__.py +3 -2
  59. cognite/neat/_store/{_base.py → _graph_store.py} +56 -2
  60. cognite/neat/_store/_provenance.py +11 -1
  61. cognite/neat/_store/_rules_store.py +20 -0
  62. cognite/neat/_utils/auth.py +7 -5
  63. cognite/neat/_utils/reader/__init__.py +1 -1
  64. cognite/neat/_version.py +2 -2
  65. cognite/neat/_workflows/__init__.py +3 -3
  66. cognite/neat/_workflows/steps/lib/current/graph_extractor.py +1 -1
  67. cognite/neat/_workflows/steps/lib/current/rules_exporter.py +1 -1
  68. cognite/neat/_workflows/steps/lib/current/rules_importer.py +2 -2
  69. cognite/neat/_workflows/steps/lib/io/io_steps.py +3 -3
  70. {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/METADATA +1 -1
  71. {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/RECORD +74 -72
  72. {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/LICENSE +0 -0
  73. {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/WHEEL +0 -0
  74. {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,9 @@
1
+ from typing import cast
2
+
1
3
  from rdflib import Graph, Namespace, URIRef
2
- from rdflib.query import ResultRow
3
4
 
5
+ from cognite.neat._constants import DEFAULT_NAMESPACE
6
+ from cognite.neat._shared import Triple
4
7
  from cognite.neat._utils.rdf_ import as_neat_compliant_uri
5
8
  from cognite.neat._utils.text import sentence_or_string_to_camel
6
9
 
@@ -55,12 +58,13 @@ class AttachPropertyFromTargetToSource(BaseTransformer):
55
58
 
56
59
  Args:
57
60
  target_node_type: RDF.type of edge Node
58
- namespace: RDF Namespace to use when querying the graph
59
- target_property: str with name of the property that holds the value attached to the intermediate node
60
- target_property_holding_new_property_name: Optional str of the property name that holds
61
- the new predicate to use when attaching the new property to the source node.
61
+ target_property: URIRef of the property that holds the value attached to the intermediate node
62
+ target_property_holding_new_property: URIRef of the property which value will be new
63
+ property that will be added to the source node
62
64
  delete_target_node: bool if the intermediate Node and Edge between source Node
63
65
  and target property should be deleted. Defaults to False.
66
+ convert_literal_to_uri: bool if the value of the new property should be converted to URIRef. Defaults to False.
67
+ namespace: Namespace to use when converting value to URIRef. Defaults to DEFAULT_NAMESPACE.
64
68
  """
65
69
 
66
70
  description: str = "Attaches a target property from a target node that is connected to a source node."
@@ -82,25 +86,26 @@ class AttachPropertyFromTargetToSource(BaseTransformer):
82
86
  def __init__(
83
87
  self,
84
88
  target_node_type: URIRef,
85
- namespace: Namespace,
86
- target_property: str,
87
- target_property_holding_new_property_name: str | None = None,
89
+ target_property: URIRef,
90
+ target_property_holding_new_property: URIRef | None = None,
88
91
  delete_target_node: bool = False,
92
+ convert_literal_to_uri: bool = False,
93
+ namespace: Namespace | None = None,
89
94
  ):
90
95
  self.target_node_type = target_node_type
91
- self.namespace = namespace
92
- self.target_property = self.namespace[target_property]
96
+ self.target_property = target_property
93
97
  self.delete_target_node = delete_target_node
94
- self.target_property_holding_new_property_name = target_property_holding_new_property_name
98
+ self.target_property_holding_new_property = target_property_holding_new_property
99
+ self.convert_literal_to_uri = convert_literal_to_uri
100
+ self.namespace = namespace or DEFAULT_NAMESPACE
95
101
 
96
102
  def transform(self, graph) -> None:
97
103
  nodes_to_delete: list[tuple] = []
98
104
 
99
- if self.target_property_holding_new_property_name is not None:
100
- target_property_holding_new_property_name = self.namespace[self.target_property_holding_new_property_name]
105
+ if self.target_property_holding_new_property is not None:
101
106
  query = self._query_template_use_case_b.format(
102
107
  target_node_type=self.target_node_type,
103
- target_property_holding_new_property_name=target_property_holding_new_property_name,
108
+ target_property_holding_new_property_name=self.target_property_holding_new_property,
104
109
  target_property=self.target_property,
105
110
  )
106
111
  else:
@@ -116,15 +121,20 @@ class AttachPropertyFromTargetToSource(BaseTransformer):
116
121
  new_predicate_value,
117
122
  new_property_value,
118
123
  ) in graph.query(query):
119
- if self.target_property_holding_new_property_name is not None:
124
+ if self.target_property_holding_new_property is not None:
120
125
  # Ensure new predicate is URI compliant as we are creating a new predicate
121
126
  new_predicate_value_string = sentence_or_string_to_camel(str(new_predicate_value))
122
127
  predicate = as_neat_compliant_uri(self.namespace[new_predicate_value_string])
123
128
  else:
124
129
  predicate = old_predicate
125
-
126
130
  # Create new connection from source node to value
127
- graph.add((source_node, predicate, new_property_value))
131
+ graph.add(
132
+ (
133
+ source_node,
134
+ predicate,
135
+ (self.namespace[new_property_value] if self.convert_literal_to_uri else new_property_value),
136
+ )
137
+ )
128
138
  # Remove old relationship between source node and destination node
129
139
  graph.remove((source_node, old_predicate, target_node))
130
140
 
@@ -158,7 +168,7 @@ class PruneDanglingNodes(BaseTransformer):
158
168
  node_prune_types: list of RDF types to prune from the Graph if they are stand-alone Nodes
159
169
  """
160
170
 
161
- description: str = "Prunes the graph of specified rdf types that do not have connections to other nodes."
171
+ description: str = "Prunes nodes of specific rdf types that do not have any connection to them."
162
172
  _query_template = """
163
173
  SELECT ?subject
164
174
  WHERE {{
@@ -174,10 +184,74 @@ class PruneDanglingNodes(BaseTransformer):
174
184
  self.node_prune_types = node_prune_types
175
185
 
176
186
  def transform(self, graph: Graph) -> None:
177
- for object_type in self.node_prune_types:
178
- nodes_without_neighbours = list(graph.query(self._query_template.format(rdf_type=object_type)))
187
+ for type_ in self.node_prune_types:
188
+ for (subject,) in list(graph.query(self._query_template.format(rdf_type=type_))): # type: ignore
189
+ graph.remove((subject, None, None))
190
+
191
+
192
+ class PruneTypes(BaseTransformer):
193
+ """
194
+ Removes all the instances of specific type
195
+ """
196
+
197
+ description: str = "Prunes nodes of specific rdf types"
198
+ _query_template = """
199
+ SELECT ?subject
200
+ WHERE {{
201
+ ?subject a <{rdf_type}> .
202
+ }}
203
+ """
204
+
205
+ def __init__(
206
+ self,
207
+ node_prune_types: list[URIRef],
208
+ ):
209
+ self.node_prune_types = node_prune_types
210
+
211
+ def transform(self, graph: Graph) -> None:
212
+ for type_ in self.node_prune_types:
213
+ for (subject,) in list(graph.query(self._query_template.format(rdf_type=type_))): # type: ignore
214
+ graph.remove((subject, None, None))
179
215
 
180
- for node in nodes_without_neighbours:
181
- # Remove node and its property triples in the graph
182
- if isinstance(node, ResultRow):
183
- graph.remove((node["subject"], None, None))
216
+
217
+ class PruneDeadEndEdges(BaseTransformer):
218
+ """
219
+ Removes all the triples where object is a node that is not found in graph
220
+ """
221
+
222
+ description: str = "Prunes the graph of specified rdf types that do not have connections to other nodes."
223
+ _query_template = """
224
+ SELECT ?subject ?predicate ?object
225
+ WHERE {
226
+ ?subject ?predicate ?object .
227
+ FILTER (isIRI(?object) && ?predicate != rdf:type)
228
+ FILTER NOT EXISTS {?object ?p ?o .}
229
+
230
+ }
231
+
232
+ """
233
+
234
+ def transform(self, graph: Graph) -> None:
235
+ for triple in graph.query(self._query_template):
236
+ graph.remove(cast(Triple, triple))
237
+
238
+
239
+ class PruneInstancesOfUnknownType(BaseTransformer):
240
+ """
241
+ Removes all the triples where object is a node that is not found in graph
242
+ """
243
+
244
+ description: str = "Prunes the graph of specified rdf types that do not have connections to other nodes."
245
+ _query_template = """
246
+ SELECT DISTINCT ?subject
247
+ WHERE {
248
+ ?subject ?p ?o .
249
+ FILTER NOT EXISTS {?subject a ?object .}
250
+
251
+ }
252
+
253
+ """
254
+
255
+ def transform(self, graph: Graph) -> None:
256
+ for (subject,) in graph.query(self._query_template): # type: ignore
257
+ graph.remove((subject, None, None))
@@ -1,8 +1,17 @@
1
- from rdflib import XSD, Graph, URIRef
1
+ import warnings
2
+ from collections.abc import Callable
3
+ from typing import Any, cast
4
+ from urllib.parse import quote
5
+
6
+ import rdflib
7
+ from rdflib import RDF, XSD, Graph, Namespace, URIRef
2
8
 
3
9
  from cognite.neat._constants import UNKNOWN_TYPE
4
10
  from cognite.neat._graph.queries import Queries
5
- from cognite.neat._utils.rdf_ import remove_namespace_from_uri
11
+ from cognite.neat._issues.warnings import NeatValueWarning, PropertyDataTypeConversionWarning
12
+ from cognite.neat._utils.auxiliary import string_to_ideal_type
13
+ from cognite.neat._utils.collection_ import iterate_progress_bar
14
+ from cognite.neat._utils.rdf_ import get_namespace, remove_namespace_from_uri
6
15
 
7
16
  from ._base import BaseTransformer
8
17
 
@@ -64,3 +73,188 @@ class SplitMultiValueProperty(BaseTransformer):
64
73
  graph.remove((s, property_uri, o))
65
74
  new_property = URIRef(f"{property_uri}_{remove_namespace_from_uri(value_type_uri)}")
66
75
  graph.add((s, new_property, o))
76
+
77
+
78
+ class ConvertLiteral(BaseTransformer):
79
+ description: str = "ConvertLiteral is a transformer that improve data typing of a literal value."
80
+ _use_only_once: bool = False
81
+ _need_changes = frozenset({})
82
+
83
+ _count_by_properties = """SELECT (COUNT(?value) AS ?valueCount)
84
+ WHERE {{
85
+ ?instance a <{subject_type}> .
86
+ ?instance <{subject_predicate}> ?value
87
+ FILTER(isLiteral(?value))
88
+ }}"""
89
+
90
+ _count_by_properties_uri = """SELECT (COUNT(?value) AS ?valueCount)
91
+ WHERE {{
92
+ ?instance a <{subject_type}> .
93
+ ?instance <{subject_predicate}> ?value
94
+ FILTER(isIRI(?value))
95
+ }}"""
96
+
97
+ _properties = """SELECT ?instance ?value
98
+ WHERE {{
99
+ ?instance a <{subject_type}> .
100
+ ?instance <{subject_predicate}> ?value
101
+
102
+ FILTER(isLiteral(?value))
103
+
104
+ }}"""
105
+
106
+ def __init__(
107
+ self,
108
+ subject_type: URIRef,
109
+ subject_predicate: URIRef,
110
+ conversion: Callable[[Any], Any] | None = None,
111
+ ) -> None:
112
+ self.subject_type = subject_type
113
+ self.subject_predicate = subject_predicate
114
+ self.conversion = conversion or string_to_ideal_type
115
+ self._type_name = remove_namespace_from_uri(subject_type)
116
+ self._property_name = remove_namespace_from_uri(subject_predicate)
117
+
118
+ def transform(self, graph: Graph) -> None:
119
+ count_connection_query = self._count_by_properties_uri.format(
120
+ subject_type=self.subject_type, subject_predicate=self.subject_predicate
121
+ )
122
+ connection_count_res = list(graph.query(count_connection_query))
123
+ connection_count = int(connection_count_res[0][0]) # type: ignore [index, arg-type]
124
+
125
+ if connection_count > 0:
126
+ warnings.warn(
127
+ NeatValueWarning(
128
+ f"Skipping {connection_count} of {self._type_name}.{self._property_name} "
129
+ f"as these are connections and not data values."
130
+ ),
131
+ stacklevel=2,
132
+ )
133
+
134
+ count_query = self._count_by_properties.format(
135
+ subject_type=self.subject_type, subject_predicate=self.subject_predicate
136
+ )
137
+
138
+ property_count_res = list(graph.query(count_query))
139
+ property_count = int(property_count_res[0][0]) # type: ignore [index, arg-type]
140
+ iterate_query = self._properties.format(
141
+ subject_type=self.subject_type, subject_predicate=self.subject_predicate
142
+ )
143
+
144
+ for instance, literal in iterate_progress_bar( # type: ignore[misc]
145
+ graph.query(iterate_query),
146
+ total=property_count,
147
+ description=f"Converting {self._type_name}.{self._property_name}.",
148
+ ):
149
+ value = cast(rdflib.Literal, literal).toPython()
150
+ try:
151
+ converted_value = self.conversion(value)
152
+ except Exception as e:
153
+ warnings.warn(
154
+ PropertyDataTypeConversionWarning(str(instance), self._type_name, self._property_name, str(e)),
155
+ stacklevel=2,
156
+ )
157
+ continue
158
+
159
+ graph.add((instance, self.subject_predicate, rdflib.Literal(converted_value)))
160
+ graph.remove((instance, self.subject_predicate, literal))
161
+
162
+
163
+ class LiteralToEntity(BaseTransformer):
164
+ description = "Converts a literal value to new entity"
165
+
166
+ _count_properties_of_type = """SELECT (COUNT(?property) AS ?propertyCount)
167
+ WHERE {{
168
+ ?instance a <{subject_type}> .
169
+ ?instance <{subject_predicate}> ?property
170
+ FILTER(isLiteral(?property))
171
+ }}"""
172
+ _count_connections_of_type = """SELECT (COUNT(?property) AS ?propertyCount)
173
+ WHERE {{
174
+ ?instance a <{subject_type}> .
175
+ ?instance <{subject_predicate}> ?property
176
+ FILTER(isIRI(?property))
177
+ }}"""
178
+
179
+ _properties_of_type = """SELECT ?instance ?property
180
+ WHERE {{
181
+ ?instance a <{subject_type}> .
182
+ ?instance <{subject_predicate}> ?property
183
+ FILTER(isLiteral(?property))
184
+ }}"""
185
+
186
+ _count_properties = """SELECT (COUNT(?property) AS ?propertyCount)
187
+ WHERE {{
188
+ ?instance <{subject_predicate}> ?property
189
+ FILTER(isLiteral(?property))
190
+ }}"""
191
+ _count_connections = """SELECT (COUNT(?property) AS ?propertyCount)
192
+ WHERE {{
193
+ ?instance <{subject_predicate}> ?property
194
+ FILTER(isIRI(?property))
195
+ }}"""
196
+ _properties = """SELECT ?instance ?property
197
+ WHERE {{
198
+ ?instance <{subject_predicate}> ?property
199
+ FILTER(isLiteral(?property))
200
+ }}"""
201
+
202
+ def __init__(
203
+ self, subject_type: URIRef | None, subject_predicate: URIRef, entity_type: str, new_property: str | None = None
204
+ ) -> None:
205
+ self.subject_type = subject_type
206
+ self.subject_predicate = subject_predicate
207
+ self.entity_type = entity_type
208
+ self.new_property = new_property
209
+
210
+ def transform(self, graph: Graph) -> None:
211
+ if self.subject_type is None:
212
+ count_query = self._count_properties.format(subject_predicate=self.subject_predicate)
213
+ iterate_query = self._properties.format(subject_predicate=self.subject_predicate)
214
+ connection_count_query = self._count_connections.format(subject_predicate=self.subject_predicate)
215
+ else:
216
+ count_query = self._count_properties_of_type.format(
217
+ subject_type=self.subject_type, subject_predicate=self.subject_predicate
218
+ )
219
+ iterate_query = self._properties_of_type.format(
220
+ subject_type=self.subject_type, subject_predicate=self.subject_predicate
221
+ )
222
+ connection_count_query = self._count_connections_of_type.format(
223
+ subject_type=self.subject_type, subject_predicate=self.subject_predicate
224
+ )
225
+
226
+ connection_count_res = list(graph.query(connection_count_query))
227
+ connection_count = int(connection_count_res[0][0]) # type: ignore [index, arg-type]
228
+ if connection_count > 0:
229
+ warnings.warn(
230
+ NeatValueWarning(
231
+ f"Skipping {connection_count} of {remove_namespace_from_uri(self.subject_predicate)} "
232
+ f"as these are connections and not data values."
233
+ ),
234
+ stacklevel=2,
235
+ )
236
+
237
+ property_count_res = list(graph.query(count_query))
238
+ property_count = int(property_count_res[0][0]) # type: ignore [index, arg-type]
239
+
240
+ instance: URIRef
241
+ description = f"Creating {remove_namespace_from_uri(self.subject_predicate)}."
242
+ if self.subject_type is not None:
243
+ description = (
244
+ f"Creating {remove_namespace_from_uri(self.subject_type)}."
245
+ f"{remove_namespace_from_uri(self.subject_predicate)}."
246
+ )
247
+ for instance, literal in iterate_progress_bar( # type: ignore[misc, assignment]
248
+ graph.query(iterate_query),
249
+ total=property_count,
250
+ description=description,
251
+ ):
252
+ value = cast(rdflib.Literal, literal).toPython()
253
+ namespace = Namespace(get_namespace(instance))
254
+ entity_type = namespace[self.entity_type]
255
+ new_entity = namespace[f"{self.entity_type}_{quote(value)!s}"]
256
+ graph.add((new_entity, RDF.type, entity_type))
257
+ if self.new_property is not None:
258
+ graph.add((new_entity, namespace[self.new_property], rdflib.Literal(value)))
259
+ graph.add((instance, self.subject_predicate, new_entity))
260
+ graph.remove((instance, self.subject_predicate, literal))
@@ -15,14 +15,14 @@ from ._base import (
15
15
  )
16
16
 
17
17
  __all__ = [
18
- "NeatIssue",
19
- "NeatError",
20
- "NeatWarning",
21
18
  "DefaultWarning",
22
- "NeatIssueList",
19
+ "FutureResult",
23
20
  "IssueList",
24
21
  "MultiValueError",
25
- "catch_warnings",
22
+ "NeatError",
23
+ "NeatIssue",
24
+ "NeatIssueList",
25
+ "NeatWarning",
26
26
  "catch_issues",
27
- "FutureResult",
27
+ "catch_warnings",
28
28
  ]
@@ -32,12 +32,12 @@ else:
32
32
 
33
33
 
34
34
  __all__ = [
35
- "NeatIssue",
36
- "NeatError",
37
- "NeatWarning",
38
35
  "DefaultWarning",
39
- "NeatIssueList",
40
36
  "MultiValueError",
37
+ "NeatError",
38
+ "NeatIssue",
39
+ "NeatIssueList",
40
+ "NeatWarning",
41
41
  ]
42
42
 
43
43
  T_Identifier = TypeVar("T_Identifier", bound=Hashable)
@@ -38,40 +38,40 @@ from ._workflow import (
38
38
  )
39
39
 
40
40
  __all__ = [
41
+ "AuthorizationError",
42
+ "CDFMissingClientError",
43
+ "DefaultPydanticError",
44
+ "FileMissingRequiredFieldError",
45
+ "FileNotAFileError",
46
+ "FileNotFoundNeatError",
47
+ "FileReadError",
48
+ "FileTypeUnexpectedError",
41
49
  "NeatError",
42
- "NeatValueError",
43
50
  "NeatImportError",
44
- "RegexViolationError",
45
- "AuthorizationError",
51
+ "NeatTypeError",
52
+ "NeatValueError",
46
53
  "NeatYamlError",
47
- "FileReadError",
48
- "ResourceCreationError",
49
- "FileNotFoundNeatError",
50
- "FileMissingRequiredFieldError",
54
+ "PropertyDefinitionDuplicatedError",
51
55
  "PropertyDefinitionError",
52
- "PropertyTypeNotSupportedError",
56
+ "PropertyMappingDuplicatedError",
53
57
  "PropertyNotFoundError",
54
- "PropertyDefinitionDuplicatedError",
58
+ "PropertyTypeNotSupportedError",
59
+ "RegexViolationError",
55
60
  "ResourceChangedError",
61
+ "ResourceConversionError",
62
+ "ResourceCreationError",
56
63
  "ResourceDuplicatedError",
57
- "ResourceRetrievalError",
58
- "ResourceNotFoundError",
59
64
  "ResourceError",
60
- "ResourceNotDefinedError",
61
65
  "ResourceMissingIdentifierError",
62
- "ResourceConversionError",
63
- "WorkflowConfigurationNotSetError",
66
+ "ResourceNotDefinedError",
67
+ "ResourceNotFoundError",
68
+ "ResourceRetrievalError",
69
+ "ReversedConnectionNotFeasibleError",
70
+ "RowError",
64
71
  "WorkFlowMissingDataError",
72
+ "WorkflowConfigurationNotSetError",
65
73
  "WorkflowStepNotInitializedError",
66
74
  "WorkflowStepOutputError",
67
- "FileTypeUnexpectedError",
68
- "FileNotAFileError",
69
- "DefaultPydanticError",
70
- "PropertyMappingDuplicatedError",
71
- "RowError",
72
- "NeatTypeError",
73
- "ReversedConnectionNotFeasibleError",
74
- "CDFMissingClientError",
75
75
  ]
76
76
 
77
77
  _NEAT_ERRORS_BY_NAME = {error.__name__: error for error in _get_subclasses(NeatError, include_base=True)}
@@ -5,7 +5,7 @@ from pathlib import Path
5
5
 
6
6
  from ._base import NeatError, NeatIssueList, NeatWarning
7
7
 
8
- __all__ = ["Formatter", "BasicHTML", "FORMATTER_BY_NAME"]
8
+ __all__ = ["FORMATTER_BY_NAME", "BasicHTML", "Formatter"]
9
9
 
10
10
 
11
11
  class Formatter(ABC):
@@ -26,6 +26,7 @@ from ._models import (
26
26
  UserModelingWarning,
27
27
  )
28
28
  from ._properties import (
29
+ PropertyDataTypeConversionWarning,
29
30
  PropertyDefinitionDuplicatedWarning,
30
31
  PropertyNotFoundWarning,
31
32
  PropertyOverwritingWarning,
@@ -43,38 +44,39 @@ from ._resources import (
43
44
  )
44
45
 
45
46
  __all__ = [
47
+ "BreakingModelingPrincipleWarning",
48
+ "CDFAuthWarning",
49
+ "CDFMaxIterationsWarning",
50
+ "CDFNotSupportedWarning",
46
51
  "DefaultWarning",
47
- "FileReadWarning",
48
- "FileMissingRequiredFieldWarning",
49
52
  "FileItemNotSupportedWarning",
53
+ "FileMissingRequiredFieldWarning",
54
+ "FileReadWarning",
50
55
  "FileTypeUnexpectedWarning",
51
56
  "NeatValueWarning",
57
+ "NotSupportedHasDataFilterLimitWarning",
58
+ "NotSupportedViewContainerLimitWarning",
52
59
  "NotSupportedWarning",
53
- "UserModelingWarning",
54
- "CDFNotSupportedWarning",
55
- "BreakingModelingPrincipleWarning",
60
+ "PrincipleMatchingSpaceAndVersionWarning",
61
+ "PrincipleOneModelOneSpaceWarning",
62
+ "PrincipleSolutionBuildsOnEnterpriseWarning",
63
+ "PropertyDataTypeConversionWarning",
56
64
  "PropertyDefinitionDuplicatedWarning",
57
- "PropertyTypeNotSupportedWarning",
58
65
  "PropertyNotFoundWarning",
59
- "PropertyValueTypeUndefinedWarning",
60
66
  "PropertyOverwritingWarning",
61
67
  "PropertySkippedWarning",
62
- "ResourceNeatWarning",
63
- "ResourcesDuplicatedWarning",
68
+ "PropertyTypeNotSupportedWarning",
69
+ "PropertyValueTypeUndefinedWarning",
64
70
  "RegexViolationWarning",
71
+ "ResourceNeatWarning",
65
72
  "ResourceNotFoundWarning",
66
- "ResourceTypeNotSupportedWarning",
67
- "ResourceRetrievalWarning",
68
73
  "ResourceRegexViolationWarning",
69
- "PrincipleOneModelOneSpaceWarning",
70
- "PrincipleMatchingSpaceAndVersionWarning",
71
- "PrincipleSolutionBuildsOnEnterpriseWarning",
72
- "NotSupportedViewContainerLimitWarning",
73
- "NotSupportedHasDataFilterLimitWarning",
74
+ "ResourceRetrievalWarning",
75
+ "ResourceTypeNotSupportedWarning",
76
+ "ResourcesDuplicatedWarning",
74
77
  "UndefinedViewWarning",
75
- "CDFAuthWarning",
78
+ "UserModelingWarning",
76
79
  "user_modeling",
77
- "CDFMaxIterationsWarning",
78
80
  ]
79
81
 
80
82
  _NEAT_WARNINGS_BY_NAME = {warning.__name__: warning for warning in _get_subclasses(NeatWarning, include_base=True)}
@@ -70,3 +70,10 @@ class PropertySkippedWarning(PropertyWarning[T_Identifier]):
70
70
  which is skipped. {reason}."""
71
71
 
72
72
  reason: str
73
+
74
+
75
+ @dataclass(unsafe_hash=True)
76
+ class PropertyDataTypeConversionWarning(PropertyWarning[T_Identifier]):
77
+ """The {resource_type} with identifier {identifier} failed to convert the property {property_name}: {error}"""
78
+
79
+ error: str
@@ -12,12 +12,12 @@ from cognite.neat._constants import DMS_CONTAINER_PROPERTY_SIZE_LIMIT
12
12
  from ._models import UserModelingWarning
13
13
 
14
14
  __all__ = [
15
+ "ContainerPropertyLimitWarning",
15
16
  "DirectRelationMissingSourceWarning",
16
17
  "EmptyContainerWarning",
17
18
  "HasDataFilterOnNoPropertiesViewWarning",
18
- "NodeTypeFilterOnParentViewWarning",
19
19
  "HasDataFilterOnViewWithReferencesWarning",
20
- "ContainerPropertyLimitWarning",
20
+ "NodeTypeFilterOnParentViewWarning",
21
21
  "NotNeatSupportedFilterWarning",
22
22
  "ParentInDifferentSpaceWarning",
23
23
  ]
@@ -1,4 +1,4 @@
1
1
  from ._dms import DMSAnalysis
2
2
  from ._information import InformationAnalysis
3
3
 
4
- __all__ = ["InformationAnalysis", "DMSAnalysis"]
4
+ __all__ = ["DMSAnalysis", "InformationAnalysis"]
@@ -4,3 +4,4 @@ from pathlib import Path
4
4
 
5
5
  _CATALOG = Path(__file__).parent
6
6
  imf_attributes = _CATALOG / "info-rules-imf.xlsx"
7
+ hello_world_pump = _CATALOG / "hello_world_pump.xlsx"
@@ -7,15 +7,15 @@ from ._rules2yaml import YAMLExporter
7
7
 
8
8
  __all__ = [
9
9
  "BaseExporter",
10
- "DMSExporter",
11
10
  "CDFExporter",
12
- "SemanticDataModelExporter",
13
- "OWLExporter",
11
+ "DMSExporter",
12
+ "ExcelExporter",
14
13
  "GraphExporter",
14
+ "InstanceTemplateExporter",
15
+ "OWLExporter",
15
16
  "SHACLExporter",
16
- "ExcelExporter",
17
+ "SemanticDataModelExporter",
17
18
  "YAMLExporter",
18
- "InstanceTemplateExporter",
19
19
  ]
20
20
 
21
21