cognite-neat 0.88.2__py3-none-any.whl → 0.88.3__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.
Files changed (97) hide show
  1. cognite/neat/_version.py +1 -1
  2. cognite/neat/graph/__init__.py +0 -3
  3. cognite/neat/graph/loaders/_base.py +3 -3
  4. cognite/neat/graph/loaders/_rdf2asset.py +24 -25
  5. cognite/neat/graph/loaders/_rdf2dms.py +20 -15
  6. cognite/neat/issues/__init__.py +1 -3
  7. cognite/neat/issues/_base.py +259 -70
  8. cognite/neat/issues/errors/__init__.py +72 -0
  9. cognite/neat/issues/errors/_external.py +67 -0
  10. cognite/neat/issues/errors/_general.py +28 -0
  11. cognite/neat/issues/errors/_properties.py +62 -0
  12. cognite/neat/issues/errors/_resources.py +111 -0
  13. cognite/neat/issues/errors/_workflow.py +36 -0
  14. cognite/neat/issues/formatters.py +1 -1
  15. cognite/neat/issues/warnings/__init__.py +66 -0
  16. cognite/neat/issues/warnings/_external.py +40 -0
  17. cognite/neat/issues/warnings/_general.py +29 -0
  18. cognite/neat/issues/warnings/_models.py +92 -0
  19. cognite/neat/issues/warnings/_properties.py +44 -0
  20. cognite/neat/issues/warnings/_resources.py +55 -0
  21. cognite/neat/issues/warnings/user_modeling.py +113 -0
  22. cognite/neat/rules/_shared.py +10 -2
  23. cognite/neat/rules/exporters/_base.py +6 -6
  24. cognite/neat/rules/exporters/_rules2dms.py +18 -11
  25. cognite/neat/rules/exporters/_rules2excel.py +4 -4
  26. cognite/neat/rules/exporters/_rules2ontology.py +74 -51
  27. cognite/neat/rules/exporters/_rules2yaml.py +3 -3
  28. cognite/neat/rules/exporters/_validation.py +11 -96
  29. cognite/neat/rules/importers/_base.py +8 -12
  30. cognite/neat/rules/importers/_dms2rules.py +21 -24
  31. cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py +22 -17
  32. cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py +26 -19
  33. cognite/neat/rules/importers/_dtdl2rules/spec.py +7 -0
  34. cognite/neat/rules/importers/_rdf/_imf2rules/_imf2classes.py +1 -1
  35. cognite/neat/rules/importers/_rdf/_imf2rules/_imf2rules.py +9 -7
  36. cognite/neat/rules/importers/_rdf/_inference2rules.py +8 -8
  37. cognite/neat/rules/importers/_rdf/_owl2rules/_owl2classes.py +1 -0
  38. cognite/neat/rules/importers/_rdf/_owl2rules/_owl2properties.py +1 -0
  39. cognite/neat/rules/importers/_rdf/_owl2rules/_owl2rules.py +4 -4
  40. cognite/neat/rules/importers/_rdf/_shared.py +3 -3
  41. cognite/neat/rules/importers/_spreadsheet2rules.py +35 -22
  42. cognite/neat/rules/importers/_yaml2rules.py +23 -22
  43. cognite/neat/rules/models/_constants.py +2 -1
  44. cognite/neat/rules/models/_rdfpath.py +4 -4
  45. cognite/neat/rules/models/_types/_field.py +5 -10
  46. cognite/neat/rules/models/asset/_rules.py +1 -3
  47. cognite/neat/rules/models/asset/_validation.py +13 -9
  48. cognite/neat/rules/models/dms/_converter.py +2 -4
  49. cognite/neat/rules/models/dms/_exporter.py +30 -8
  50. cognite/neat/rules/models/dms/_rules.py +23 -7
  51. cognite/neat/rules/models/dms/_schema.py +87 -78
  52. cognite/neat/rules/models/dms/_validation.py +104 -65
  53. cognite/neat/rules/models/information/_converter.py +2 -2
  54. cognite/neat/rules/models/information/_rules.py +7 -8
  55. cognite/neat/rules/models/information/_validation.py +47 -24
  56. cognite/neat/rules/transformers/_base.py +15 -0
  57. cognite/neat/utils/auxiliary.py +2 -35
  58. cognite/neat/utils/text.py +17 -0
  59. cognite/neat/workflows/base.py +4 -4
  60. cognite/neat/workflows/cdf_store.py +3 -3
  61. cognite/neat/workflows/steps/data_contracts.py +1 -1
  62. cognite/neat/workflows/steps/lib/current/graph_extractor.py +3 -3
  63. cognite/neat/workflows/steps/lib/current/graph_loader.py +2 -2
  64. cognite/neat/workflows/steps/lib/current/graph_store.py +1 -1
  65. cognite/neat/workflows/steps/lib/current/rules_exporter.py +10 -10
  66. cognite/neat/workflows/steps/lib/current/rules_importer.py +6 -6
  67. cognite/neat/workflows/steps/lib/current/rules_validator.py +5 -6
  68. cognite/neat/workflows/steps/lib/io/io_steps.py +5 -5
  69. cognite/neat/workflows/steps_registry.py +4 -5
  70. {cognite_neat-0.88.2.dist-info → cognite_neat-0.88.3.dist-info}/METADATA +1 -1
  71. {cognite_neat-0.88.2.dist-info → cognite_neat-0.88.3.dist-info}/RECORD +78 -84
  72. cognite/neat/exceptions.py +0 -145
  73. cognite/neat/graph/exceptions.py +0 -90
  74. cognite/neat/issues/errors/external.py +0 -21
  75. cognite/neat/issues/errors/properties.py +0 -75
  76. cognite/neat/issues/errors/resources.py +0 -123
  77. cognite/neat/issues/neat_warnings/__init__.py +0 -2
  78. cognite/neat/issues/neat_warnings/identifier.py +0 -27
  79. cognite/neat/issues/neat_warnings/models.py +0 -22
  80. cognite/neat/issues/neat_warnings/properties.py +0 -77
  81. cognite/neat/issues/neat_warnings/resources.py +0 -125
  82. cognite/neat/rules/issues/__init__.py +0 -22
  83. cognite/neat/rules/issues/base.py +0 -63
  84. cognite/neat/rules/issues/dms.py +0 -549
  85. cognite/neat/rules/issues/fileread.py +0 -197
  86. cognite/neat/rules/issues/ontology.py +0 -298
  87. cognite/neat/rules/issues/spreadsheet.py +0 -563
  88. cognite/neat/rules/issues/spreadsheet_file.py +0 -151
  89. cognite/neat/rules/issues/tables.py +0 -72
  90. cognite/neat/workflows/_exceptions.py +0 -41
  91. /cognite/neat/{issues/errors/schema.py → rules/transformers/__init__.py} +0 -0
  92. /cognite/neat/{graph/stores → store}/__init__.py +0 -0
  93. /cognite/neat/{graph/stores → store}/_base.py +0 -0
  94. /cognite/neat/{graph/stores → store}/_provenance.py +0 -0
  95. {cognite_neat-0.88.2.dist-info → cognite_neat-0.88.3.dist-info}/LICENSE +0 -0
  96. {cognite_neat-0.88.2.dist-info → cognite_neat-0.88.3.dist-info}/WHEEL +0 -0
  97. {cognite_neat-0.88.2.dist-info → cognite_neat-0.88.3.dist-info}/entry_points.txt +0 -0
@@ -1,197 +0,0 @@
1
- from abc import ABC
2
- from dataclasses import dataclass
3
- from pathlib import Path
4
-
5
- from .base import NeatValidationError, ValidationWarning
6
-
7
- __all__ = [
8
- "FileReadWarning",
9
- "InvalidFileFormatWarning",
10
- "UnsupportedSpecWarning",
11
- "UnknownItemWarning",
12
- "FailedLoadWarning",
13
- "BugInImporterWarning",
14
- "FileReadError",
15
- "FileNotFoundError",
16
- "FileNotAFileError",
17
- "InvalidFileFormatError",
18
- "FailedStringLoadError",
19
- ]
20
-
21
-
22
- @dataclass(frozen=True)
23
- class FileReadError(NeatValidationError, ABC):
24
- description = "An error was raised during reading."
25
- fix = "No fix is available."
26
-
27
- filepath: Path
28
-
29
- def dump(self) -> dict[str, str | None]:
30
- output = super().dump()
31
- output["filepath"] = str(self.filepath)
32
- return output
33
-
34
-
35
- @dataclass(frozen=True)
36
- class FileReadWarning(ValidationWarning, ABC):
37
- description = "A warning was raised during reading."
38
- fix = "No fix is available."
39
-
40
- filepath: Path
41
-
42
- def dump(self) -> dict[str, str | None]:
43
- output = super().dump()
44
- output["filepath"] = str(self.filepath)
45
- return output
46
-
47
-
48
- @dataclass(frozen=True)
49
- class InvalidFileFormatWarning(FileReadWarning):
50
- description = "The file format is invalid"
51
- fix = "Check if the file format is supported."
52
-
53
- reason: str
54
-
55
- def message(self) -> str:
56
- return f"Skipping invalid file {self.filepath.name}: {self.reason}"
57
-
58
- def dump(self) -> dict[str, str | None]:
59
- output = super().dump()
60
- output["reason"] = self.reason
61
- return output
62
-
63
-
64
- @dataclass(frozen=True)
65
- class UnsupportedSpecWarning(FileReadWarning):
66
- description = "The spec in the file is not supported"
67
- fix = "Change to an supported spec"
68
-
69
- spec_name: str
70
- version: str | None = None
71
-
72
- def message(self) -> str:
73
- if self.version:
74
- suffix = f"{self.spec_name} v{self.version} is not supported."
75
- else:
76
- suffix = f"{self.spec_name} is not supported."
77
- return f"Skipping file {self.filepath.name}: {suffix}. {self.fix}"
78
-
79
- def dump(self) -> dict[str, str | None]:
80
- output = super().dump()
81
- output["spec_name"] = self.spec_name
82
- output["version"] = self.version
83
- return output
84
-
85
-
86
- @dataclass(frozen=True)
87
- class UnknownItemWarning(FileReadWarning):
88
- description = "The file is missing an implementation"
89
- fix = "Check if the file is supported. If not, contact the neat team on Github."
90
-
91
- reason: str
92
-
93
- def message(self) -> str:
94
- return f"Skipping file {self.filepath.name}: {self.reason}. {self.fix}"
95
-
96
- def dump(self) -> dict[str, str | None]:
97
- output = super().dump()
98
- output["reason"] = self.reason
99
- return output
100
-
101
-
102
- @dataclass(frozen=True)
103
- class FailedLoadWarning(FileReadWarning):
104
- description = "The file content is invalid"
105
- fix = "Check if the file content is valid"
106
-
107
- expected_format: str
108
- error_message: str
109
-
110
- def message(self) -> str:
111
- return (
112
- f"Failed to load {self.filepath.name}. Expected format: {self.expected_format}. Error: {self.error_message}"
113
- )
114
-
115
- def dump(self) -> dict[str, str | None]:
116
- output = super().dump()
117
- output["expected_format"] = self.expected_format
118
- output["error_message"] = self.error_message
119
- return output
120
-
121
-
122
- @dataclass(frozen=True)
123
- class BugInImporterWarning(FileReadWarning):
124
- description = "A bug was raised during reading."
125
- fix = "No fix is available. Contact the neat team on Github"
126
-
127
- importer_name: str
128
- error: str
129
-
130
- def message(self) -> str:
131
- return f"Bug in importer {self.importer_name} when reading {self.filepath.name}: {self.error}"
132
-
133
- def dump(self) -> dict[str, str | None]:
134
- output = super().dump()
135
- output["importer_name"] = self.importer_name
136
- output["error"] = self.error
137
- return output
138
-
139
-
140
- @dataclass(frozen=True)
141
- class FileNotFoundError(FileReadError):
142
- description = "The file was not found"
143
- fix = "Check if the file exists."
144
-
145
- def message(self) -> str:
146
- return f"File {self.filepath} was not found. {self.fix}"
147
-
148
-
149
- @dataclass(frozen=True)
150
- class FileNotAFileError(FileReadError):
151
- description = "The file is not a file"
152
- fix = "Check if the file exists."
153
-
154
- def message(self) -> str:
155
- return f"{self.filepath} is not a file. {self.fix}"
156
-
157
-
158
- @dataclass(frozen=True)
159
- class InvalidFileFormatError(FileReadError):
160
- description = "The file is not in the expected format"
161
- fix = "Check if the file is in the expected format"
162
-
163
- expected_format: list[str]
164
-
165
- def message(self) -> str:
166
- return f"{self.filepath} is not in the expected format. Expected format: {self.expected_format}."
167
-
168
-
169
- @dataclass(frozen=True)
170
- class FailedStringLoadError(NeatValidationError):
171
- description = "The file content is invalid"
172
- fix = "Check if the file content is valid"
173
-
174
- expected_format: str
175
- error_message: str
176
-
177
- def message(self) -> str:
178
- return f"Failed to load string. Expected format: {self.expected_format}. Error: {self.error_message}"
179
-
180
- def dump(self) -> dict[str, str | None]:
181
- output = super().dump()
182
- output["expected_format"] = self.expected_format
183
- output["error_message"] = self.error_message
184
- return output
185
-
186
-
187
- @dataclass(frozen=True)
188
- class NoFilesFoundError(FileReadError):
189
- description = "No files were found in the directory"
190
- fix = "Check if the directory contains files"
191
-
192
- expected_formats: list[str] | None = None
193
-
194
- def message(self) -> str:
195
- if self.expected_formats:
196
- return f"No files were found in {self.filepath.name}. Expected format: {self.expected_formats}. {self.fix}"
197
- return f"No files were found in {self.filepath.name}. {self.fix}"
@@ -1,298 +0,0 @@
1
- from abc import ABC
2
- from dataclasses import dataclass
3
- from typing import ClassVar
4
-
5
- from .base import NeatValidationError, ValidationWarning
6
-
7
- __all__ = [
8
- "OntologyError",
9
- "OntologyWarning",
10
- ]
11
-
12
-
13
- @dataclass(frozen=True)
14
- class OntologyError(NeatValidationError, ABC): ...
15
-
16
-
17
- @dataclass(frozen=True)
18
- class OntologyWarning(ValidationWarning, ABC): ...
19
-
20
-
21
- @dataclass(frozen=True)
22
- class OntologyMultiLabeledPropertyWarning(OntologyWarning):
23
- """This warning occurs when a property is given multiple labels, typically if the
24
- same property is defined for different classes but different name is given
25
-
26
- Args:
27
- property_id: property id that raised warning due to multiple labels
28
- names: list of names of property
29
-
30
- Notes:
31
- This would be automatically fixed by taking the first label (aka name) of the property.
32
- """
33
-
34
- description = (
35
- "This warning occurs when a property is given multiple labels,"
36
- " typically if the same property is defined for different "
37
- "classes but different name is given."
38
- )
39
- fix = "This would be automatically fixed by taking the first label (aka name) of the property."
40
-
41
- property_id: str
42
- names: list[str] | None = None
43
-
44
- def message(self) -> str:
45
- message = (
46
- "Property should have single preferred label (human readable name)."
47
- f"Currently property '{self.property_id}' has multiple preferred labels: {', '.join(self.names or [])} !"
48
- f"Only the first name, i.e. '{self.names[0] if self.names else ''}' will be considered!"
49
- )
50
- message += f"\nDescription: {self.description}"
51
- message += f"\nFix: {self.fix}"
52
- return message
53
-
54
-
55
- @dataclass(frozen=True)
56
- class OntologyMultiDefinitionPropertyWarning(OntologyWarning):
57
- """This warning occurs when a property is given multiple human readable definitions,
58
- typically if the same property is defined for different classes where each definition
59
- is different.
60
-
61
- Args:
62
- property_id: property id that raised warning due to multiple definitions
63
-
64
- Notes:
65
- This would be automatically fixed by concatenating all definitions.
66
- """
67
-
68
- description = (
69
- "This warning occurs when a property is given multiple human readable definitions,"
70
- " typically if the same property is defined for different "
71
- "classes where each definition is different."
72
- )
73
- fix = "This would be automatically fixed by concatenating all definitions."
74
-
75
- property_id: str
76
-
77
- def message(self):
78
- message = (
79
- f"Multiple definitions (aka comments) of property '{self.property_id}' detected."
80
- " Definitions will be concatenated."
81
- )
82
- message += f"\nDescription: {self.description}"
83
- message += f"\nFix: {self.fix}"
84
- return message
85
-
86
-
87
- @dataclass(frozen=True)
88
- class OntologyMultiTypePropertyWarning(OntologyWarning):
89
- """This warning occurs when a same property is define for two object/classes where
90
- its expected value type is different in one definition, e.g. acts as an edge, while in
91
- other definition acts as and attribute
92
-
93
- Args:
94
- property_id: property id that raised warning due to multi type definition
95
- types: list of types of property
96
-
97
- Notes:
98
- If a property takes different value types for different objects, simply define
99
- new property. It is bad practice to have multi type property!
100
- """
101
-
102
- description = (
103
- "This warning occurs when a same property is define for two object/classes where"
104
- " its expected value type is different in one definition, e.g. acts as an edge, while in "
105
- "other definition acts as and attribute"
106
- )
107
- fix = "If a property takes different value types for different objects, simply define new property"
108
-
109
- property_id: str
110
- types: list[str] | None = None
111
-
112
- def message(self) -> str:
113
- message = (
114
- "It is bad practice to have multi type property! "
115
- f"Currently property '{self.property_id}' is defined as multi type property: {', '.join(self.types or [])}"
116
- )
117
- message += f"\nDescription: {self.description}"
118
- message += f"\nFix: {self.fix}"
119
- return message
120
-
121
-
122
- @dataclass(frozen=True)
123
- class OntologyMultiRangePropertyWarning(OntologyWarning):
124
- """This warning occurs when a property takes range of values which consists of union
125
- of multiple value types
126
-
127
- Args:
128
- property_id: property id that raised warning due to multi range definition
129
- range_of_values: list of ranges that property takes
130
-
131
- Notes:
132
- If a property takes different range of values, simply define new property.
133
- """
134
-
135
- description = (
136
- "This warning occurs when a property takes range of values which consists of union of multiple value types."
137
- )
138
- fix = "If a property takes different range of values, simply define new property"
139
- property_id: str
140
- range_of_values: list[str] | None = None
141
-
142
- def message(self) -> str:
143
- message = (
144
- "It is bad practice to have property that take various range of values! "
145
- f"Currently property '{self.property_id}' has multiple ranges: {', '.join(self.range_of_values or [])}"
146
- )
147
- message += f"\nDescription: {self.description}"
148
- message += f"\nFix: {self.fix}"
149
- return message
150
-
151
-
152
- @dataclass(frozen=True)
153
- class OntologyMultiDomainPropertyWarning(OntologyWarning):
154
- """This warning occurs when a property is reused for more than one classes
155
-
156
- Args:
157
- property_id: property id that raised warning due to reuse definition
158
- classes: list of classes that use the same property
159
- verbose: flag that indicates whether to provide enhanced exception message, by default False
160
-
161
- Notes:
162
- No need to fix this, but make sure that property type is consistent across different
163
- classes and that ideally takes the same range of values
164
- """
165
-
166
- description = "This warning occurs when a property is reused for more than one classes."
167
- fix = (
168
- "No need to fix this, but make sure that property type is consistent"
169
- " across different classes and that ideally takes the same range of values"
170
- )
171
- property_id: str
172
- classes: list[str] | None = None
173
-
174
- def message(self) -> str:
175
- message = (
176
- f"Currently property '{self.property_id}' is defined for multiple classes: {', '.join(self.classes or [])}"
177
- )
178
- message += f"\nDescription: {self.description}"
179
- message += f"\nFix: {self.fix}"
180
- return message
181
-
182
-
183
- @dataclass(frozen=True)
184
- class PropertiesDefinedMultipleTimesError(OntologyError):
185
- """This error is raised during export of Transformation Rules to DMS schema when
186
- when properties are defined multiple times for the same class.
187
-
188
- Args:
189
- report: report on properties which are defined multiple times
190
- verbose: flag that indicates whether to provide enhanced exception message, by default False
191
-
192
- Notes:
193
- Make sure to check validation report of Transformation Rules and fix DMS related warnings.
194
- """
195
-
196
- description = (
197
- "This error is raised during export of Transformation Rules to "
198
- "DMS schema when properties are defined multiple times for the same class."
199
- )
200
- fix = "Make sure to check validation report of Transformation Rules and fix DMS related warnings."
201
-
202
- report: str
203
-
204
- def message(self) -> str:
205
- message = f"Following properties defined multiple times for the same class(es): {self.report}"
206
-
207
- message += f"\nDescription: {self.description}"
208
- message += f"\nFix: {self.fix}"
209
- return message
210
-
211
-
212
- @dataclass(frozen=True)
213
- class PropertyDefinitionsNotForSamePropertyError(OntologyError):
214
- """This error is raised if property definitions are not for linked to the same
215
- property id when exporting rules to ontological representation.
216
-
217
- Args:
218
- verbose: flag that indicates whether to provide enhanced exception message, by default False
219
- """
220
-
221
- description = "This error is raised if property definitions are not for linked to the same property id"
222
-
223
- def message(self):
224
- message = "All definitions should have the same property_id! Aborting."
225
-
226
- message += f"\nDescription: {self.description}"
227
- return message
228
-
229
-
230
- @dataclass(frozen=True)
231
- class PrefixMissingError(OntologyError):
232
- """Prefix, which is in the 'Metadata' sheet, is missing.
233
-
234
- Args:
235
- verbose: flag that indicates whether to provide enhanced exception message, by default False
236
-
237
- """
238
-
239
- description = "Prefix is missing from the 'Metadata' sheet."
240
- example = "There is no prefix in the 'Metadata' sheet."
241
- fix = "Specify the prefix if prefix in the 'Metadata' sheet."
242
-
243
- def message(self) -> str:
244
- message = "Missing prefix stored in 'Metadata' sheet."
245
- message += f"\nDescription: {self.description}"
246
- message += f"\nExample: {self.example}"
247
- message += f"\nFix: {self.fix}"
248
- return message
249
-
250
-
251
- @dataclass(frozen=True)
252
- class MissingDataModelPrefixOrNamespaceWarning(ValidationWarning):
253
- """Prefix and/or namespace are missing in the 'Metadata' sheet
254
-
255
- Args:
256
- verbose: flag that indicates whether to provide enhanced exception message, by default False
257
-
258
- Notes:
259
- Add missing prefix and/or namespace in the 'Metadata' sheet
260
- """
261
-
262
- description = "Either prefix or namespace or both are missing in the 'Metadata' sheet"
263
- fix = "Add missing prefix and/or namespace in the 'Metadata' sheet"
264
-
265
- def message(self) -> str:
266
- message = (
267
- "Instances sheet is present but prefix and/or namespace are missing in 'Metadata' sheet."
268
- "Instances sheet will not be processed!"
269
- )
270
- message += f"\nDescription: {self.description}"
271
- message += f"\nFix: {self.fix}"
272
- return message
273
-
274
-
275
- @dataclass(frozen=True)
276
- class MetadataSheetNamespaceNotDefinedError(OntologyError):
277
- """namespace, which is in the 'Metadata' sheet, is not defined
278
-
279
- Args:
280
- namespace: namespace that raised exception
281
- verbose: flag that indicates whether to provide enhanced exception message, by default False
282
-
283
- Notes:
284
- Check if `namespace` in the `Metadata` sheet is properly constructed as valid URL
285
- containing only allowed characters.
286
-
287
- """
288
-
289
- description = "namespace, which is in the 'Metadata' sheet, is missing"
290
- example: ClassVar[str] = "Example of a valid namespace 'http://www.w3.org/ns/sparql#'"
291
- fix = "Define the 'namespace' in the 'Metadata' sheet."
292
-
293
- def message(self) -> str:
294
- message = "Missing namespace in 'Metadata' sheet."
295
- message += f"\nDescription: {self.description}"
296
- message += f"\nExample: {self.example}"
297
- message += f"\nFix: {self.fix}"
298
- return message