cognite-neat 0.119.9__py3-none-any.whl → 0.121.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 (187) hide show
  1. cognite/neat/__init__.py +3 -2
  2. cognite/neat/_version.py +1 -1
  3. cognite/neat/{_client → core/_client}/_api/data_modeling_loaders.py +5 -5
  4. cognite/neat/{_client → core/_client}/_api/neat_instances.py +1 -1
  5. cognite/neat/{_client → core/_client}/_api/schema.py +9 -5
  6. cognite/neat/{_client → core/_client}/_api_client.py +1 -1
  7. cognite/neat/{_client → core/_client}/data_classes/schema.py +4 -4
  8. cognite/neat/{_client → core/_client}/testing.py +1 -1
  9. cognite/neat/{_constants.py → core/_constants.py} +27 -8
  10. cognite/neat/{_graph → core/_graph}/_tracking/base.py +1 -1
  11. cognite/neat/{_graph → core/_graph}/_tracking/log.py +1 -1
  12. cognite/neat/{_graph → core/_graph}/extractors/__init__.py +1 -1
  13. cognite/neat/{_graph → core/_graph}/extractors/_base.py +6 -6
  14. cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_base.py +23 -7
  15. cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_classic.py +16 -12
  16. cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_files.py +10 -3
  17. cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_relationships.py +5 -3
  18. cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_sequences.py +7 -2
  19. cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_timeseries.py +10 -3
  20. cognite/neat/{_graph → core/_graph}/extractors/_dict.py +2 -2
  21. cognite/neat/{_graph → core/_graph}/extractors/_dms.py +6 -6
  22. cognite/neat/{_graph → core/_graph}/extractors/_dms_graph.py +15 -11
  23. cognite/neat/{_graph → core/_graph}/extractors/_mock_graph_generator.py +10 -10
  24. cognite/neat/{_graph → core/_graph}/extractors/_raw.py +3 -3
  25. cognite/neat/{_graph → core/_graph}/extractors/_rdf_file.py +10 -7
  26. cognite/neat/{_graph → core/_graph}/loaders/_base.py +5 -5
  27. cognite/neat/{_graph → core/_graph}/loaders/_rdf2dms.py +31 -18
  28. cognite/neat/{_graph → core/_graph}/queries/_select.py +3 -3
  29. cognite/neat/{_graph → core/_graph}/queries/_update.py +1 -1
  30. cognite/neat/{_graph → core/_graph}/transformers/_base.py +8 -4
  31. cognite/neat/{_graph → core/_graph}/transformers/_classic_cdf.py +6 -6
  32. cognite/neat/{_graph → core/_graph}/transformers/_prune_graph.py +4 -4
  33. cognite/neat/{_graph → core/_graph}/transformers/_rdfpath.py +1 -1
  34. cognite/neat/{_graph → core/_graph}/transformers/_value_type.py +8 -4
  35. cognite/neat/{_issues → core/_issues}/_base.py +12 -5
  36. cognite/neat/{_issues → core/_issues}/_contextmanagers.py +1 -1
  37. cognite/neat/{_issues → core/_issues}/_factory.py +2 -2
  38. cognite/neat/{_issues → core/_issues}/errors/__init__.py +1 -1
  39. cognite/neat/{_issues → core/_issues}/errors/_external.py +1 -1
  40. cognite/neat/{_issues → core/_issues}/errors/_general.py +1 -1
  41. cognite/neat/{_issues → core/_issues}/errors/_properties.py +1 -1
  42. cognite/neat/{_issues → core/_issues}/errors/_resources.py +7 -2
  43. cognite/neat/{_issues → core/_issues}/errors/_wrapper.py +2 -2
  44. cognite/neat/{_issues → core/_issues}/warnings/__init__.py +1 -1
  45. cognite/neat/{_issues → core/_issues}/warnings/_external.py +1 -1
  46. cognite/neat/{_issues → core/_issues}/warnings/_general.py +1 -1
  47. cognite/neat/{_issues → core/_issues}/warnings/_models.py +2 -2
  48. cognite/neat/{_issues → core/_issues}/warnings/_properties.py +2 -2
  49. cognite/neat/{_issues → core/_issues}/warnings/_resources.py +6 -1
  50. cognite/neat/{_issues → core/_issues}/warnings/user_modeling.py +1 -1
  51. cognite/neat/{_rules → core/_rules}/_shared.py +6 -4
  52. cognite/neat/{_rules → core/_rules}/analysis/_base.py +15 -8
  53. cognite/neat/{_rules → core/_rules}/exporters/_base.py +7 -7
  54. cognite/neat/{_rules → core/_rules}/exporters/_rules2dms.py +15 -9
  55. cognite/neat/{_rules → core/_rules}/exporters/_rules2excel.py +219 -163
  56. cognite/neat/{_rules → core/_rules}/exporters/_rules2instance_template.py +4 -4
  57. cognite/neat/{_rules → core/_rules}/exporters/_rules2ontology.py +10 -10
  58. cognite/neat/{_rules → core/_rules}/exporters/_rules2yaml.py +1 -1
  59. cognite/neat/{_rules → core/_rules}/exporters/_validation.py +2 -2
  60. cognite/neat/{_rules → core/_rules}/importers/_base.py +5 -5
  61. cognite/neat/{_rules → core/_rules}/importers/_dms2rules.py +20 -12
  62. cognite/neat/{_rules → core/_rules}/importers/_dtdl2rules/dtdl_converter.py +15 -7
  63. cognite/neat/{_rules → core/_rules}/importers/_dtdl2rules/dtdl_importer.py +13 -9
  64. cognite/neat/{_rules → core/_rules}/importers/_dtdl2rules/spec.py +1 -1
  65. cognite/neat/{_rules → core/_rules}/importers/_rdf/_base.py +12 -12
  66. cognite/neat/{_rules → core/_rules}/importers/_rdf/_imf2rules.py +5 -2
  67. cognite/neat/{_rules → core/_rules}/importers/_rdf/_inference2rules.py +14 -14
  68. cognite/neat/{_rules → core/_rules}/importers/_rdf/_owl2rules.py +5 -2
  69. cognite/neat/{_rules → core/_rules}/importers/_rdf/_shared.py +4 -4
  70. cognite/neat/{_rules → core/_rules}/importers/_spreadsheet2rules.py +7 -7
  71. cognite/neat/{_rules → core/_rules}/importers/_yaml2rules.py +5 -5
  72. cognite/neat/{_rules → core/_rules}/models/__init__.py +5 -3
  73. cognite/neat/{_rules → core/_rules}/models/_base_rules.py +9 -6
  74. cognite/neat/{_rules → core/_rules}/models/_types.py +5 -5
  75. cognite/neat/{_rules → core/_rules}/models/data_types.py +9 -3
  76. cognite/neat/{_rules → core/_rules}/models/dms/__init__.py +1 -1
  77. cognite/neat/{_rules → core/_rules}/models/dms/_exporter.py +15 -8
  78. cognite/neat/{_rules → core/_rules}/models/dms/_rules.py +9 -9
  79. cognite/neat/{_rules → core/_rules}/models/dms/_rules_input.py +10 -7
  80. cognite/neat/{_rules → core/_rules}/models/dms/_validation.py +14 -14
  81. cognite/neat/{_rules → core/_rules}/models/entities/_loaders.py +2 -2
  82. cognite/neat/{_rules → core/_rules}/models/entities/_multi_value.py +2 -2
  83. cognite/neat/{_rules → core/_rules}/models/entities/_single_value.py +3 -3
  84. cognite/neat/{_rules → core/_rules}/models/information/_rules.py +11 -9
  85. cognite/neat/{_rules → core/_rules}/models/information/_rules_input.py +5 -5
  86. cognite/neat/{_rules → core/_rules}/models/information/_validation.py +10 -10
  87. cognite/neat/{_rules → core/_rules}/models/mapping/_classic2core.py +5 -5
  88. cognite/neat/{_rules → core/_rules}/transformers/_base.py +4 -4
  89. cognite/neat/{_rules → core/_rules}/transformers/_converters.py +52 -26
  90. cognite/neat/{_rules → core/_rules}/transformers/_mapping.py +15 -7
  91. cognite/neat/{_rules → core/_rules}/transformers/_verification.py +7 -7
  92. cognite/neat/{_store → core/_store}/_graph_store.py +13 -10
  93. cognite/neat/{_store → core/_store}/_provenance.py +3 -3
  94. cognite/neat/{_store → core/_store}/_rules_store.py +19 -12
  95. cognite/neat/{_store → core/_store}/exceptions.py +4 -4
  96. cognite/neat/core/_utils/__init__.py +0 -0
  97. cognite/neat/{_utils → core/_utils}/auth.py +1 -1
  98. cognite/neat/{_utils → core/_utils}/auxiliary.py +1 -1
  99. cognite/neat/{_utils → core/_utils}/collection_.py +2 -2
  100. cognite/neat/{_utils → core/_utils}/graph_transformations_report.py +1 -1
  101. cognite/neat/{_utils → core/_utils}/rdf_.py +1 -1
  102. cognite/neat/{_utils → core/_utils}/reader/_base.py +1 -1
  103. cognite/neat/{_utils → core/_utils}/spreadsheet.py +11 -4
  104. cognite/neat/{_utils → core/_utils}/text.py +1 -1
  105. cognite/neat/{_utils → core/_utils}/upload.py +3 -3
  106. cognite/neat/{_session → session}/_base.py +10 -10
  107. cognite/neat/{_session → session}/_collector.py +1 -1
  108. cognite/neat/{_session → session}/_drop.py +3 -3
  109. cognite/neat/{_session → session}/_explore.py +2 -2
  110. cognite/neat/{_session → session}/_fix.py +2 -2
  111. cognite/neat/{_session → session}/_inspect.py +7 -3
  112. cognite/neat/{_session → session}/_mapping.py +3 -3
  113. cognite/neat/{_session → session}/_prepare.py +8 -8
  114. cognite/neat/{_session → session}/_read.py +130 -16
  115. cognite/neat/{_session → session}/_set.py +8 -8
  116. cognite/neat/{_session → session}/_show.py +5 -5
  117. cognite/neat/{_session → session}/_state.py +8 -8
  118. cognite/neat/{_session → session}/_subset.py +7 -4
  119. cognite/neat/{_session → session}/_template.py +22 -14
  120. cognite/neat/{_session → session}/_to.py +12 -12
  121. cognite/neat/{_session → session}/_wizard.py +1 -1
  122. cognite/neat/{_session → session}/engine/_load.py +1 -1
  123. cognite/neat/{_session → session}/exceptions.py +4 -4
  124. {cognite_neat-0.119.9.dist-info → cognite_neat-0.121.0.dist-info}/METADATA +1 -1
  125. cognite_neat-0.121.0.dist-info/RECORD +187 -0
  126. cognite_neat-0.119.9.dist-info/RECORD +0 -186
  127. /cognite/neat/{_client/_api → core}/__init__.py +0 -0
  128. /cognite/neat/{_client → core/_client}/__init__.py +0 -0
  129. /cognite/neat/{_client/data_classes → core/_client/_api}/__init__.py +0 -0
  130. /cognite/neat/{_graph → core/_client/data_classes}/__init__.py +0 -0
  131. /cognite/neat/{_client → core/_client}/data_classes/data_modeling.py +0 -0
  132. /cognite/neat/{_client → core/_client}/data_classes/neat_sequence.py +0 -0
  133. /cognite/neat/{_config.py → core/_config.py} +0 -0
  134. /cognite/neat/{_graph/extractors/_classic_cdf → core/_graph}/__init__.py +0 -0
  135. /cognite/neat/{_graph → core/_graph}/_shared.py +0 -0
  136. /cognite/neat/{_graph → core/_graph}/_tracking/__init__.py +0 -0
  137. /cognite/neat/{_graph → core/_graph}/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  138. /cognite/neat/{_graph → core/_graph}/examples/Knowledge-Graph-Nordic44.xml +0 -0
  139. /cognite/neat/{_graph → core/_graph}/examples/__init__.py +0 -0
  140. /cognite/neat/{_graph → core/_graph}/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  141. /cognite/neat/{_rules → core/_graph/extractors/_classic_cdf}/__init__.py +0 -0
  142. /cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_assets.py +0 -0
  143. /cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_data_sets.py +0 -0
  144. /cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_events.py +0 -0
  145. /cognite/neat/{_graph → core/_graph}/extractors/_classic_cdf/_labels.py +0 -0
  146. /cognite/neat/{_graph → core/_graph}/loaders/__init__.py +0 -0
  147. /cognite/neat/{_graph → core/_graph}/queries/__init__.py +0 -0
  148. /cognite/neat/{_graph → core/_graph}/queries/_base.py +0 -0
  149. /cognite/neat/{_graph → core/_graph}/queries/_queries.py +0 -0
  150. /cognite/neat/{_graph → core/_graph}/transformers/__init__.py +0 -0
  151. /cognite/neat/{_issues → core/_issues}/__init__.py +0 -0
  152. /cognite/neat/{_issues → core/_issues}/formatters.py +0 -0
  153. /cognite/neat/{_utils → core/_rules}/__init__.py +0 -0
  154. /cognite/neat/{_rules → core/_rules}/_constants.py +0 -0
  155. /cognite/neat/{_rules → core/_rules}/analysis/__init__.py +0 -0
  156. /cognite/neat/{_rules → core/_rules}/catalog/__init__.py +0 -0
  157. /cognite/neat/{_rules → core/_rules}/catalog/classic_model.xlsx +0 -0
  158. /cognite/neat/{_rules → core/_rules}/catalog/hello_world_pump.xlsx +0 -0
  159. /cognite/neat/{_rules → core/_rules}/catalog/info-rules-imf.xlsx +0 -0
  160. /cognite/neat/{_rules → core/_rules}/exporters/__init__.py +0 -0
  161. /cognite/neat/{_rules → core/_rules}/importers/__init__.py +0 -0
  162. /cognite/neat/{_rules → core/_rules}/importers/_dtdl2rules/__init__.py +0 -0
  163. /cognite/neat/{_rules → core/_rules}/importers/_dtdl2rules/_unit_lookup.py +0 -0
  164. /cognite/neat/{_rules → core/_rules}/importers/_rdf/__init__.py +0 -0
  165. /cognite/neat/{_rules → core/_rules}/models/_base_input.py +0 -0
  166. /cognite/neat/{_rules → core/_rules}/models/entities/__init__.py +0 -0
  167. /cognite/neat/{_rules → core/_rules}/models/entities/_constants.py +0 -0
  168. /cognite/neat/{_rules → core/_rules}/models/entities/_types.py +0 -0
  169. /cognite/neat/{_rules → core/_rules}/models/entities/_wrapped.py +0 -0
  170. /cognite/neat/{_rules → core/_rules}/models/information/__init__.py +0 -0
  171. /cognite/neat/{_rules → core/_rules}/models/mapping/__init__.py +0 -0
  172. /cognite/neat/{_rules → core/_rules}/models/mapping/_classic2core.yaml +0 -0
  173. /cognite/neat/{_rules → core/_rules}/transformers/__init__.py +0 -0
  174. /cognite/neat/{_shared.py → core/_shared.py} +0 -0
  175. /cognite/neat/{_store → core/_store}/__init__.py +0 -0
  176. /cognite/neat/{_utils → core/_utils}/io_.py +0 -0
  177. /cognite/neat/{_utils → core/_utils}/reader/__init__.py +0 -0
  178. /cognite/neat/{_utils → core/_utils}/time_.py +0 -0
  179. /cognite/neat/{_utils → core/_utils}/xml_.py +0 -0
  180. /cognite/neat/{_session → session}/__init__.py +0 -0
  181. /cognite/neat/{_alpha.py → session/_experimental.py} +0 -0
  182. /cognite/neat/{_state → session/_state}/README.md +0 -0
  183. /cognite/neat/{_session → session}/engine/__init__.py +0 -0
  184. /cognite/neat/{_session → session}/engine/_import.py +0 -0
  185. /cognite/neat/{_session → session}/engine/_interface.py +0 -0
  186. {cognite_neat-0.119.9.dist-info → cognite_neat-0.121.0.dist-info}/WHEEL +0 -0
  187. {cognite_neat-0.119.9.dist-info → cognite_neat-0.121.0.dist-info}/licenses/LICENSE +0 -0
@@ -4,27 +4,29 @@ import itertools
4
4
  from datetime import datetime
5
5
  from pathlib import Path
6
6
  from types import GenericAlias
7
- from typing import Any, ClassVar, Literal, cast, get_args
7
+ from typing import Any, ClassVar, Literal, cast, get_args, overload
8
8
 
9
9
  from openpyxl import Workbook
10
10
  from openpyxl.cell import MergedCell
11
11
  from openpyxl.styles import Alignment, Border, Font, PatternFill, Side
12
+ from openpyxl.utils import get_column_letter
13
+ from openpyxl.worksheet.datavalidation import DataValidation
12
14
  from openpyxl.worksheet.worksheet import Worksheet
13
15
  from rdflib import Namespace
14
16
 
15
- from cognite.neat._constants import COGNITE_CONCEPTS
16
- from cognite.neat._rules._constants import get_internal_properties
17
- from cognite.neat._rules._shared import VerifiedRules
18
- from cognite.neat._rules.models import (
17
+ from cognite.neat.core._constants import BASE_MODEL, get_base_concepts
18
+ from cognite.neat.core._rules._constants import get_internal_properties
19
+ from cognite.neat.core._rules._shared import VerifiedRules
20
+ from cognite.neat.core._rules.models import (
19
21
  SheetRow,
20
22
  )
21
- from cognite.neat._rules.models._base_rules import BaseMetadata, RoleTypes
22
- from cognite.neat._rules.models.data_types import (
23
+ from cognite.neat.core._rules.models._base_rules import BaseMetadata, RoleTypes
24
+ from cognite.neat.core._rules.models.data_types import (
23
25
  _DATA_TYPE_BY_DMS_TYPE,
24
26
  )
25
- from cognite.neat._rules.models.dms._rules import DMSRules
26
- from cognite.neat._rules.models.information._rules import InformationRules
27
- from cognite.neat._utils.spreadsheet import (
27
+ from cognite.neat.core._rules.models.dms._rules import DMSRules
28
+ from cognite.neat.core._rules.models.information._rules import InformationRules
29
+ from cognite.neat.core._utils.spreadsheet import (
28
30
  find_column_with_value,
29
31
  generate_data_validation,
30
32
  )
@@ -67,6 +69,16 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
67
69
  "Nodes": "Definition of Nodes",
68
70
  "Enum": "Definition of Enum Collections",
69
71
  }
72
+ _helper_sheet_column_indexes_by_names: ClassVar[dict[str, int]] = {
73
+ "Class": 1,
74
+ "View": 1,
75
+ "Implements": 2,
76
+ "Value Type": 3,
77
+ "Container": 4,
78
+ "In Model": 5,
79
+ "Immutable": 5,
80
+ "Used For": 6,
81
+ }
70
82
  style_options = get_args(Style)
71
83
  dump_options = get_args(DumpOptions)
72
84
 
@@ -80,6 +92,8 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
80
92
  hide_internal_columns: bool = True,
81
93
  include_properties: Literal["same-space", "all"] = "all",
82
94
  add_drop_downs: bool = True,
95
+ base_model: BASE_MODEL | None = None,
96
+ total_concepts: int | None = None,
83
97
  ):
84
98
  self.sheet_prefix = sheet_prefix or ""
85
99
  if styling not in self.style_options:
@@ -92,6 +106,8 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
92
106
  self.hide_internal_columns = hide_internal_columns
93
107
  self.include_properties = include_properties
94
108
  self.add_drop_downs = add_drop_downs
109
+ self.base_model = base_model
110
+ self.total_concepts = total_concepts
95
111
 
96
112
  @property
97
113
  def description(self) -> str:
@@ -106,6 +122,12 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
106
122
  data.close()
107
123
  return None
108
124
 
125
+ @overload
126
+ def template(self, role: RoleTypes, filepath: Path) -> None: ...
127
+
128
+ @overload
129
+ def template(self, role: RoleTypes, filepath: Path | None = None) -> None: ...
130
+
109
131
  def template(self, role: RoleTypes, filepath: Path | None = None) -> None | Workbook:
110
132
  """This method will create an spreadsheet template for data modeling depending on the role.
111
133
 
@@ -137,10 +159,7 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
137
159
  self._adjust_column_widths(workbook)
138
160
  self._hide_internal_columns(workbook)
139
161
 
140
- if role == RoleTypes.dms:
141
- self._add_dms_drop_downs(workbook)
142
- else:
143
- self._add_info_drop_downs(workbook)
162
+ self._add_drop_downs(role, workbook)
144
163
 
145
164
  if filepath:
146
165
  try:
@@ -176,10 +195,8 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
176
195
  self._hide_internal_columns(workbook)
177
196
 
178
197
  # Only add drop downs if the rules are DMSRules
179
- if self.add_drop_downs and isinstance(rules, DMSRules):
180
- self._add_dms_drop_downs(workbook)
181
- elif self.add_drop_downs and isinstance(rules, InformationRules):
182
- self._add_info_drop_downs(workbook)
198
+ if self.add_drop_downs:
199
+ self._add_drop_downs(rules.metadata.role, workbook)
183
200
 
184
201
  return workbook
185
202
 
@@ -199,199 +216,238 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
199
216
  if column_letter:
200
217
  ws.column_dimensions[column_letter].hidden = True
201
218
 
202
- def _add_info_drop_downs(self, workbook: Workbook, no_rows: int = 100) -> None:
219
+ def _add_drop_downs(
220
+ self,
221
+ role: RoleTypes,
222
+ workbook: Workbook,
223
+ ) -> None:
203
224
  """Adds drop down menus to specific columns for fast and accurate data entry
204
- in the Information rules.
225
+ for both DMS and Information rules.
205
226
 
206
227
  Args:
228
+ role: The role for which the drop downs are created. Can be either "dms" or "information".
207
229
  workbook: Workbook representation of the Excel file.
208
- no_rows: number of rows to add drop down menus. Defaults to 100*100.
209
-
210
- !!! note "Why no_rows=100?"
211
- Maximum number of views per data model is 100, thus this value is set accordingly
212
230
 
213
231
  !!! note "Why defining individual data validation per desired column?
214
232
  This is due to the internal working of openpyxl. Adding same validation to
215
233
  different column leads to unexpected behavior when the openpyxl workbook is exported
216
234
  as and Excel file. Probably, the validation is not copied to the new column,
217
235
  but instead reference to the data validation object is added.
236
+
237
+ !!! note "Why 100*100 rows?"
238
+ This is due to the fact that we need to add drop down menus for all properties
239
+ in the sheet. The maximum number of properties per view/class is 100. So considering
240
+ maximum number of views/classes is 100, we need to add 100*100 rows.
218
241
  """
219
- self._make_helper_info_sheet(workbook, no_rows)
242
+
243
+ self._make_helper_sheet(role, workbook, 100)
244
+
245
+ data_validators: dict[str, DataValidation] = {}
220
246
 
221
247
  # We need create individual data validation and cannot re-use the same one due
222
248
  # the internals of openpyxl
223
- dv_classes = generate_data_validation(self._helper_sheet_name, "A", no_header_rows=0, no_rows=no_rows)
224
- dv_value_types = generate_data_validation(self._helper_sheet_name, "B", no_header_rows=0, no_rows=no_rows)
225
- dv_implements = generate_data_validation(
226
- self._helper_sheet_name,
227
- "C",
228
- no_header_rows=0,
229
- no_rows=no_rows + len(COGNITE_CONCEPTS),
249
+
250
+ self._add_data_validation(
251
+ workbook,
252
+ sheet_name="Views" if role == RoleTypes.dms else "Classes",
253
+ column_name="Implements",
254
+ data_validator_name="implements",
255
+ data_validators=data_validators,
256
+ validation_range=100 + 100, # base + user concepts (max)
257
+ total_rows=100,
258
+ )
259
+
260
+ self._add_data_validation(
261
+ workbook,
262
+ sheet_name="Properties",
263
+ column_name="Value Type",
264
+ data_validator_name="value_type",
265
+ data_validators=data_validators,
266
+ validation_range=150, # primitive types + classes
267
+ total_rows=100 * 100, # 100 views/classes * 100 properties (max properties per view/class)
230
268
  )
231
269
 
232
- workbook["Properties"].add_data_validation(dv_classes)
233
- workbook["Properties"].add_data_validation(dv_value_types)
234
- workbook["Classes"].add_data_validation(dv_implements)
270
+ self._add_data_validation(
271
+ workbook,
272
+ sheet_name="Properties",
273
+ column_name="View" if role == RoleTypes.dms else "Class",
274
+ data_validator_name="views_or_classes",
275
+ data_validators=data_validators,
276
+ validation_range=100,
277
+ total_rows=100 * 100,
278
+ )
235
279
 
236
- # we multiply no_rows with 100 since a view can have max 100 properties per view
237
- if column := find_column_with_value(workbook["Properties"], "Class"):
238
- dv_classes.add(f"{column}{3}:{column}{no_rows * 100}")
280
+ if role == RoleTypes.dms:
281
+ self._add_data_validation(
282
+ workbook,
283
+ sheet_name="Properties",
284
+ column_name="Container",
285
+ data_validator_name="container",
286
+ data_validators=data_validators,
287
+ validation_range=100,
288
+ total_rows=100 * 100,
289
+ )
239
290
 
240
- if column := find_column_with_value(workbook["Properties"], "Value Type"):
241
- dv_value_types.add(f"{column}{3}:{column}{no_rows * 100}")
291
+ self._add_data_validation(
292
+ workbook,
293
+ sheet_name="Properties",
294
+ column_name="Immutable",
295
+ data_validator_name="immutable",
296
+ data_validators=data_validators,
297
+ validation_range=2,
298
+ total_rows=100 * 100,
299
+ )
242
300
 
243
- if column := find_column_with_value(workbook["Classes"], "Implements"):
244
- dv_implements.add(f"{column}{3}:{column}{no_rows}")
301
+ self._add_data_validation(
302
+ workbook,
303
+ sheet_name="Views",
304
+ column_name="In Model",
305
+ data_validator_name="in_model",
306
+ data_validators=data_validators,
307
+ validation_range=2,
308
+ total_rows=100, # 100 views
309
+ )
310
+
311
+ self._add_data_validation(
312
+ workbook,
313
+ sheet_name="Containers",
314
+ column_name="Used For",
315
+ data_validator_name="used_for",
316
+ data_validators=data_validators,
317
+ validation_range=3,
318
+ total_rows=100, # 100 views
319
+ )
320
+
321
+ def _make_helper_sheet(
322
+ self,
323
+ role: RoleTypes,
324
+ workbook: Workbook,
325
+ no_rows: int,
326
+ ) -> None:
327
+ """This helper sheet is used as source of data for drop down menus creation
328
+
329
+ Args:
330
+ role: The role for which the helper sheet is created. Can be either "dms" or "information".
331
+ workbook: Workbook representation of the Excel file.
332
+ no_rows: number of rows to add data too that will form base for drop down menus.
333
+ """
245
334
 
246
- def _make_helper_info_sheet(self, workbook: Workbook, no_rows: int) -> None:
247
- """This helper Information sheet is used as source of data for drop down menus creation"""
248
335
  workbook.create_sheet(title=self._helper_sheet_name)
249
336
 
250
- for dtype_counter, dtype in enumerate(_DATA_TYPE_BY_DMS_TYPE.values()):
337
+ value_type_counter = 0
338
+
339
+ for value_type_counter, value_type in enumerate(_DATA_TYPE_BY_DMS_TYPE.values()):
340
+ value_type_as_str = value_type.dms._type.casefold() if role == RoleTypes.dms else value_type.xsd
251
341
  # skip types which require special handling or are surpassed by CDM
252
- if dtype.xsd in ["enum", "timeseries", "sequence", "file", "json"]:
342
+ if value_type_as_str in ["enum", "timeseries", "sequence", "file", "json"]:
253
343
  continue
254
- workbook[self._helper_sheet_name].cell(row=dtype_counter + 1, column=2, value=dtype.xsd)
255
-
256
- # Add Cognite Core Data Views:
257
- for concept_counter, concept in enumerate(COGNITE_CONCEPTS):
258
344
  workbook[self._helper_sheet_name].cell(
259
- row=concept_counter + 1,
260
- column=3,
261
- value=f"cdf_cdm:{concept}(version=v1)",
345
+ row=value_type_counter + 1,
346
+ column=self._helper_sheet_column_indexes_by_names["Value Type"],
347
+ value=value_type_as_str,
262
348
  )
263
349
 
350
+ value_type_counter += 1
351
+
352
+ concept_counter = 0
353
+ if self.base_model and (concepts := get_base_concepts(self.base_model, self.total_concepts)):
354
+ for concept_counter, concept in enumerate(concepts):
355
+ workbook[self._helper_sheet_name].cell(
356
+ row=concept_counter + 1,
357
+ column=self._helper_sheet_column_indexes_by_names["Implements"],
358
+ value=concept,
359
+ )
360
+ concept_counter += 1
361
+
362
+ views_or_classes_sheet = "Views" if role == RoleTypes.dms else "Classes"
363
+ view_or_class_column = "View" if role == RoleTypes.dms else "Class"
364
+
264
365
  for i in range(no_rows):
265
366
  workbook[self._helper_sheet_name].cell(
266
367
  row=i + 1,
267
- column=1,
268
- value=f'=IF(ISBLANK(Classes!A{i + 3}), "", Classes!A{i + 3})',
368
+ column=self._helper_sheet_column_indexes_by_names[view_or_class_column],
369
+ value=f'=IF(ISBLANK({views_or_classes_sheet}!A{i + 3}), "", {views_or_classes_sheet}!A{i + 3})',
269
370
  )
371
+
270
372
  workbook[self._helper_sheet_name].cell(
271
- row=dtype_counter + i + 2,
272
- column=2,
273
- value=f'=IF(ISBLANK(Classes!A{i + 3}), "", Classes!A{i + 3})',
373
+ row=concept_counter + i + 1,
374
+ column=self._helper_sheet_column_indexes_by_names["Implements"],
375
+ value=f'=IF(ISBLANK({views_or_classes_sheet}!A{i + 3}), "", {views_or_classes_sheet}!A{i + 3})',
274
376
  )
377
+
275
378
  workbook[self._helper_sheet_name].cell(
276
- row=concept_counter + i + 2,
277
- column=3,
278
- value=f'=IF(ISBLANK(Classes!A{i + 3}), "", Classes!A{i + 3})',
379
+ row=value_type_counter + i + 1,
380
+ column=self._helper_sheet_column_indexes_by_names["Value Type"],
381
+ value=f'=IF(ISBLANK({views_or_classes_sheet}!A{i + 3}), "", {views_or_classes_sheet}!A{i + 3})',
279
382
  )
280
383
 
384
+ if role == RoleTypes.dms:
385
+ workbook[self._helper_sheet_name].cell(
386
+ row=i + 1,
387
+ column=self._helper_sheet_column_indexes_by_names["Container"],
388
+ value=f'=IF(ISBLANK(Containers!A{i + 3}), "", Containers!A{i + 3})',
389
+ )
390
+
391
+ if role == RoleTypes.dms:
392
+ for i, value in enumerate([True, False, ""]):
393
+ workbook[self._helper_sheet_name].cell(
394
+ row=i + 1,
395
+ column=self._helper_sheet_column_indexes_by_names["In Model"],
396
+ value=cast(bool | str, value),
397
+ )
398
+
399
+ for i, value in enumerate(["node", "edge", "all"]):
400
+ workbook[self._helper_sheet_name].cell(
401
+ row=i + 1,
402
+ column=self._helper_sheet_column_indexes_by_names["Used For"],
403
+ value=value,
404
+ )
405
+
281
406
  workbook[self._helper_sheet_name].sheet_state = "hidden"
282
407
 
283
- def _add_dms_drop_downs(self, workbook: Workbook, no_rows: int = 100) -> None:
284
- """Adds drop down menus to specific columns for fast and accurate data entry
285
- in the DMS rules.
408
+ def _add_data_validation(
409
+ self,
410
+ workbook: Workbook,
411
+ sheet_name: str,
412
+ column_name: str,
413
+ data_validator_name: str,
414
+ data_validators: dict,
415
+ validation_range: int,
416
+ total_rows: int,
417
+ ) -> None:
418
+ """Adds data validation to a column in a sheet.
286
419
 
287
420
  Args:
288
421
  workbook: Workbook representation of the Excel file.
289
- no_rows: number of rows to add drop down menus. Defaults to 100*100.
290
-
291
- !!! note "Why no_rows=100?"
292
- Maximum number of views per data model is 100, thus this value is set accordingly
293
-
294
- !!! note "Why defining individual data validation per desired column?
422
+ sheet_name: The name of the sheet to add the data validation to.
423
+ column_name: The name of the column to add the data validation to.
424
+ data_validator_name: The name of the data validation to add.
425
+ data_validators: A dictionary to store the data validators.
426
+ validation_range: The total number of validation values to add.
427
+ total_rows: The number of rows to add the data validation to.
428
+
429
+ !!! note "Why defining individual data validation per desired column?"
295
430
  This is due to the internal working of openpyxl. Adding same validation to
296
431
  different column leads to unexpected behavior when the openpyxl workbook is exported
297
- as and Excel file. Probably, the validation is not copied to the new column,
298
- but instead reference to the data validation object is added.
299
- """
432
+ as and Excel file.
300
433
 
301
- self._make_helper_dms_sheet(workbook, no_rows)
302
-
303
- # We need create individual data validation and cannot re-use the same one due
304
- # the internals of openpyxl
305
- dv_views = generate_data_validation(self._helper_sheet_name, "A", no_header_rows=0, no_rows=no_rows)
306
- dv_containers = generate_data_validation(self._helper_sheet_name, "B", no_header_rows=0, no_rows=no_rows)
307
- dv_value_types = generate_data_validation(self._helper_sheet_name, "C", no_header_rows=0, no_rows=no_rows)
308
- dv_implements = generate_data_validation(
434
+ !!! note "Why starting at row 3?"
435
+ This is due to the header rows in the sheet. The first two rows are reserved for the header.
436
+ """
437
+ # CREATE VALIDATOR
438
+ data_validators[data_validator_name] = generate_data_validation(
309
439
  self._helper_sheet_name,
310
- "F",
311
- no_header_rows=0,
312
- no_rows=no_rows + len(COGNITE_CONCEPTS),
440
+ get_column_letter(self._helper_sheet_column_indexes_by_names[column_name]),
441
+ total_header_rows=0,
442
+ validation_range=validation_range,
313
443
  )
314
444
 
315
- dv_immutable = generate_data_validation(self._helper_sheet_name, "D", no_header_rows=0, no_rows=3)
316
- dv_in_model = generate_data_validation(self._helper_sheet_name, "D", no_header_rows=0, no_rows=3)
317
- dv_used_for = generate_data_validation(self._helper_sheet_name, "E", no_header_rows=0, no_rows=3)
318
-
319
- workbook["Properties"].add_data_validation(dv_views)
320
- workbook["Properties"].add_data_validation(dv_containers)
321
- workbook["Properties"].add_data_validation(dv_value_types)
322
- workbook["Properties"].add_data_validation(dv_immutable)
323
- workbook["Views"].add_data_validation(dv_in_model)
324
- workbook["Views"].add_data_validation(dv_implements)
325
- workbook["Containers"].add_data_validation(dv_used_for)
326
-
327
- # we multiply no_rows with 100 since a view can have max 100 properties per view
328
- if column := find_column_with_value(workbook["Properties"], "View"):
329
- dv_views.add(f"{column}{3}:{column}{no_rows * 100}")
330
-
331
- if column := find_column_with_value(workbook["Properties"], "Container"):
332
- dv_containers.add(f"{column}{3}:{column}{no_rows * 100}")
333
-
334
- if column := find_column_with_value(workbook["Properties"], "Value Type"):
335
- dv_value_types.add(f"{column}{3}:{column}{no_rows * 100}")
336
-
337
- if column := find_column_with_value(workbook["Properties"], "Immutable"):
338
- dv_immutable.add(f"{column}{3}:{column}{no_rows * 100}")
339
-
340
- if column := find_column_with_value(workbook["Views"], "In Model"):
341
- dv_in_model.add(f"{column}{3}:{column}{no_rows}")
342
-
343
- if column := find_column_with_value(workbook["Views"], "Implements"):
344
- dv_implements.add(f"{column}{3}:{column}{no_rows}")
445
+ # REGISTER VALIDATOR TO SPECIFIC WORKBOOK SHEET
446
+ workbook[sheet_name].add_data_validation(data_validators[data_validator_name])
345
447
 
346
- if column := find_column_with_value(workbook["Containers"], "Used For"):
347
- dv_used_for.add(f"{column}{3}:{column}{no_rows}")
348
-
349
- def _make_helper_dms_sheet(self, workbook: Workbook, no_rows: int) -> None:
350
- """This helper DMS sheet is used as source of data for drop down menus creation"""
351
- workbook.create_sheet(title=self._helper_sheet_name)
352
-
353
- for dtype_counter, dtype in enumerate(_DATA_TYPE_BY_DMS_TYPE):
354
- if dtype in ["enum", "timeseries", "sequence", "file", "json"]:
355
- continue
356
- workbook[self._helper_sheet_name].cell(row=dtype_counter + 1, column=3, value=dtype)
357
-
358
- # Add Cognite Core Data Views:
359
- for concept_counter, concept in enumerate(COGNITE_CONCEPTS):
360
- workbook[self._helper_sheet_name].cell(
361
- row=concept_counter + 1,
362
- column=6,
363
- value=f"cdf_cdm:{concept}(version=v1)",
364
- )
365
-
366
- for i in range(no_rows):
367
- workbook[self._helper_sheet_name].cell(
368
- row=i + 1,
369
- column=1,
370
- value=f'=IF(ISBLANK(Views!A{i + 3}), "", Views!A{i + 3})',
371
- )
372
- workbook[self._helper_sheet_name].cell(
373
- row=i + 1,
374
- column=2,
375
- value=f'=IF(ISBLANK(Containers!A{i + 3}), "", Containers!A{i + 3})',
376
- )
377
- workbook[self._helper_sheet_name].cell(
378
- row=dtype_counter + i + 2,
379
- column=3,
380
- value=f'=IF(ISBLANK(Views!A{i + 3}), "", Views!A{i + 3})',
381
- )
382
- workbook[self._helper_sheet_name].cell(
383
- row=concept_counter + i + 2,
384
- column=6,
385
- value=f'=IF(ISBLANK(Views!A{i + 3}), "", Views!A{i + 3})',
386
- )
387
-
388
- for i, value in enumerate([True, False, ""]):
389
- workbook[self._helper_sheet_name].cell(row=i + 1, column=4, value=cast(bool | str, value))
390
-
391
- for i, value in enumerate(["node", "edge", "all"]):
392
- workbook[self._helper_sheet_name].cell(row=i + 1, column=5, value=value)
393
-
394
- workbook[self._helper_sheet_name].sheet_state = "hidden"
448
+ # APPLY VALIDATOR TO SPECIFIC COLUMN
449
+ if column_letter := find_column_with_value(workbook[sheet_name], column_name):
450
+ data_validators[data_validator_name].add(f"{column_letter}{3}:{column_letter}{3 + total_rows}")
395
451
 
396
452
  def _create_sheet_with_header(
397
453
  self,
@@ -8,10 +8,10 @@ from openpyxl.styles import Alignment, Border, Font, NamedStyle, PatternFill, Si
8
8
  from openpyxl.utils import get_column_letter
9
9
  from openpyxl.worksheet.datavalidation import DataValidation
10
10
 
11
- from cognite.neat._rules._constants import EntityTypes
12
- from cognite.neat._rules.analysis import RulesAnalysis
13
- from cognite.neat._rules.models.entities._single_value import ClassEntity
14
- from cognite.neat._rules.models.information._rules import InformationRules
11
+ from cognite.neat.core._rules._constants import EntityTypes
12
+ from cognite.neat.core._rules.analysis import RulesAnalysis
13
+ from cognite.neat.core._rules.models.entities._single_value import ClassEntity
14
+ from cognite.neat.core._rules.models.information._rules import InformationRules
15
15
 
16
16
  from ._base import BaseExporter
17
17
 
@@ -8,23 +8,23 @@ from pydantic import BaseModel, ConfigDict, ValidationInfo, field_validator
8
8
  from rdflib import DCTERMS, OWL, RDF, RDFS, XSD, BNode, Graph, Literal, Namespace, URIRef
9
9
  from rdflib.collection import Collection as GraphCollection
10
10
 
11
- from cognite.neat._constants import DEFAULT_NAMESPACE as NEAT_NAMESPACE
12
- from cognite.neat._issues import MultiValueError
13
- from cognite.neat._issues.errors import (
11
+ from cognite.neat.core._constants import DEFAULT_NAMESPACE as NEAT_NAMESPACE
12
+ from cognite.neat.core._issues import MultiValueError
13
+ from cognite.neat.core._issues.errors import (
14
14
  PropertyDefinitionDuplicatedError,
15
15
  )
16
- from cognite.neat._issues.warnings import PropertyDefinitionDuplicatedWarning
17
- from cognite.neat._rules._constants import EntityTypes
18
- from cognite.neat._rules.analysis import RulesAnalysis
19
- from cognite.neat._rules.models.data_types import DataType
20
- from cognite.neat._rules.models.entities import ClassEntity
21
- from cognite.neat._rules.models.information import (
16
+ from cognite.neat.core._issues.warnings import PropertyDefinitionDuplicatedWarning
17
+ from cognite.neat.core._rules._constants import EntityTypes
18
+ from cognite.neat.core._rules.analysis import RulesAnalysis
19
+ from cognite.neat.core._rules.models.data_types import DataType
20
+ from cognite.neat.core._rules.models.entities import ClassEntity
21
+ from cognite.neat.core._rules.models.information import (
22
22
  InformationClass,
23
23
  InformationMetadata,
24
24
  InformationProperty,
25
25
  InformationRules,
26
26
  )
27
- from cognite.neat._utils.rdf_ import remove_namespace_from_uri
27
+ from cognite.neat.core._utils.rdf_ import remove_namespace_from_uri
28
28
 
29
29
  from ._base import BaseExporter
30
30
  from ._validation import duplicated_properties
@@ -5,7 +5,7 @@ from typing import Literal, get_args
5
5
 
6
6
  import yaml
7
7
 
8
- from cognite.neat._rules._shared import VerifiedRules
8
+ from cognite.neat.core._rules._shared import VerifiedRules
9
9
 
10
10
  from ._base import BaseExporter
11
11
 
@@ -1,8 +1,8 @@
1
1
  from collections import defaultdict
2
2
  from collections.abc import Iterable
3
3
 
4
- from cognite.neat._rules.models.entities import ClassEntity
5
- from cognite.neat._rules.models.information import InformationProperty
4
+ from cognite.neat.core._rules.models.entities import ClassEntity
5
+ from cognite.neat.core._rules.models.information import InformationProperty
6
6
 
7
7
 
8
8
  def duplicated_properties(
@@ -5,12 +5,12 @@ from typing import TYPE_CHECKING, Any, Generic
5
5
 
6
6
  from rdflib import URIRef
7
7
 
8
- from cognite.neat._constants import DEFAULT_NAMESPACE
9
- from cognite.neat._rules._shared import ReadRules, T_InputRules
10
- from cognite.neat._utils.auxiliary import class_html_doc
8
+ from cognite.neat.core._constants import DEFAULT_NAMESPACE
9
+ from cognite.neat.core._rules._shared import ReadRules, T_InputRules
10
+ from cognite.neat.core._utils.auxiliary import class_html_doc
11
11
 
12
12
  if TYPE_CHECKING:
13
- from cognite.neat._store._provenance import Agent as ProvenanceAgent
13
+ from cognite.neat.core._store._provenance import Agent as ProvenanceAgent
14
14
 
15
15
 
16
16
  class BaseImporter(ABC, Generic[T_InputRules]):
@@ -49,7 +49,7 @@ class BaseImporter(ABC, Generic[T_InputRules]):
49
49
  @property
50
50
  def agent(self) -> "ProvenanceAgent":
51
51
  """Provenance agent for the importer."""
52
- from cognite.neat._store._provenance import Agent as ProvenanceAgent
52
+ from cognite.neat.core._store._provenance import Agent as ProvenanceAgent
53
53
 
54
54
  return ProvenanceAgent(id_=DEFAULT_NAMESPACE[f"agent/{type(self).__name__}"])
55
55
 
@@ -28,17 +28,25 @@ from cognite.client.data_classes.data_modeling.views import (
28
28
  )
29
29
  from cognite.client.utils import ms_to_datetime
30
30
 
31
- from cognite.neat._client import NeatClient
32
- from cognite.neat._constants import DMS_DIRECT_RELATION_LIST_DEFAULT_LIMIT, DMS_PRIMITIVE_LIST_DEFAULT_LIMIT
33
- from cognite.neat._issues import IssueList, MultiValueError, NeatIssue, catch_issues
34
- from cognite.neat._issues.errors import (
31
+ from cognite.neat.core._client import NeatClient
32
+ from cognite.neat.core._constants import (
33
+ DMS_DIRECT_RELATION_LIST_DEFAULT_LIMIT,
34
+ DMS_PRIMITIVE_LIST_DEFAULT_LIMIT,
35
+ )
36
+ from cognite.neat.core._issues import (
37
+ IssueList,
38
+ MultiValueError,
39
+ NeatIssue,
40
+ catch_issues,
41
+ )
42
+ from cognite.neat.core._issues.errors import (
35
43
  FileTypeUnexpectedError,
36
44
  NeatValueError,
37
45
  PropertyTypeNotSupportedError,
38
46
  ResourceMissingIdentifierError,
39
47
  ResourceRetrievalError,
40
48
  )
41
- from cognite.neat._issues.warnings import (
49
+ from cognite.neat.core._issues.warnings import (
42
50
  MissingCogniteClientWarning,
43
51
  NeatValueWarning,
44
52
  PropertyNotFoundWarning,
@@ -47,14 +55,14 @@ from cognite.neat._issues.warnings import (
47
55
  ResourcesDuplicatedWarning,
48
56
  ResourceUnknownWarning,
49
57
  )
50
- from cognite.neat._rules._shared import ReadRules
51
- from cognite.neat._rules.importers._base import BaseImporter
52
- from cognite.neat._rules.models import (
58
+ from cognite.neat.core._rules._shared import ReadRules
59
+ from cognite.neat.core._rules.importers._base import BaseImporter
60
+ from cognite.neat.core._rules.models import (
53
61
  DMSInputRules,
54
62
  DMSSchema,
55
63
  )
56
- from cognite.neat._rules.models.data_types import DataType, Enum, String
57
- from cognite.neat._rules.models.dms import (
64
+ from cognite.neat.core._rules.models.data_types import DataType, Enum, String
65
+ from cognite.neat.core._rules.models.dms import (
58
66
  DMSInputContainer,
59
67
  DMSInputEnum,
60
68
  DMSInputMetadata,
@@ -62,7 +70,7 @@ from cognite.neat._rules.models.dms import (
62
70
  DMSInputProperty,
63
71
  DMSInputView,
64
72
  )
65
- from cognite.neat._rules.models.entities import (
73
+ from cognite.neat.core._rules.models.entities import (
66
74
  ClassEntity,
67
75
  ContainerEntity,
68
76
  DMSNodeEntity,
@@ -71,7 +79,7 @@ from cognite.neat._rules.models.entities import (
71
79
  ReverseConnectionEntity,
72
80
  ViewEntity,
73
81
  )
74
- from cognite.neat._rules.models.information import (
82
+ from cognite.neat.core._rules.models.information import (
75
83
  InformationInputClass,
76
84
  InformationInputProperty,
77
85
  )