cognite-neat 0.123.2__py3-none-any.whl → 0.127.30__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 (333) hide show
  1. cognite/neat/__init__.py +2 -2
  2. cognite/neat/_client/__init__.py +4 -0
  3. cognite/neat/_client/api.py +8 -0
  4. cognite/neat/_client/client.py +21 -0
  5. cognite/neat/_client/config.py +40 -0
  6. cognite/neat/_client/containers_api.py +125 -0
  7. cognite/neat/_client/data_classes.py +44 -0
  8. cognite/neat/_client/data_model_api.py +115 -0
  9. cognite/neat/_client/spaces_api.py +115 -0
  10. cognite/neat/_client/statistics_api.py +24 -0
  11. cognite/neat/_client/views_api.py +129 -0
  12. cognite/neat/_config.py +185 -0
  13. cognite/neat/_data_model/_analysis.py +196 -0
  14. cognite/neat/_data_model/_constants.py +67 -0
  15. cognite/neat/_data_model/_identifiers.py +61 -0
  16. cognite/neat/_data_model/_shared.py +41 -0
  17. cognite/neat/_data_model/deployer/_differ.py +140 -0
  18. cognite/neat/_data_model/deployer/_differ_container.py +360 -0
  19. cognite/neat/_data_model/deployer/_differ_data_model.py +54 -0
  20. cognite/neat/_data_model/deployer/_differ_space.py +9 -0
  21. cognite/neat/_data_model/deployer/_differ_view.py +299 -0
  22. cognite/neat/_data_model/deployer/data_classes.py +529 -0
  23. cognite/neat/_data_model/deployer/deployer.py +401 -0
  24. cognite/neat/_data_model/exporters/__init__.py +15 -0
  25. cognite/neat/_data_model/exporters/_api_exporter.py +37 -0
  26. cognite/neat/_data_model/exporters/_base.py +24 -0
  27. cognite/neat/_data_model/exporters/_table_exporter/exporter.py +128 -0
  28. cognite/neat/_data_model/exporters/_table_exporter/workbook.py +409 -0
  29. cognite/neat/_data_model/exporters/_table_exporter/writer.py +421 -0
  30. cognite/neat/_data_model/importers/__init__.py +5 -0
  31. cognite/neat/_data_model/importers/_api_importer.py +166 -0
  32. cognite/neat/_data_model/importers/_base.py +16 -0
  33. cognite/neat/_data_model/importers/_table_importer/data_classes.py +295 -0
  34. cognite/neat/_data_model/importers/_table_importer/importer.py +192 -0
  35. cognite/neat/_data_model/importers/_table_importer/reader.py +1063 -0
  36. cognite/neat/_data_model/importers/_table_importer/source.py +94 -0
  37. cognite/neat/_data_model/models/conceptual/_base.py +18 -0
  38. cognite/neat/_data_model/models/conceptual/_concept.py +67 -0
  39. cognite/neat/_data_model/models/conceptual/_data_model.py +51 -0
  40. cognite/neat/_data_model/models/conceptual/_properties.py +104 -0
  41. cognite/neat/_data_model/models/conceptual/_property.py +105 -0
  42. cognite/neat/_data_model/models/dms/__init__.py +206 -0
  43. cognite/neat/_data_model/models/dms/_base.py +31 -0
  44. cognite/neat/_data_model/models/dms/_constants.py +48 -0
  45. cognite/neat/_data_model/models/dms/_constraints.py +42 -0
  46. cognite/neat/_data_model/models/dms/_container.py +159 -0
  47. cognite/neat/_data_model/models/dms/_data_model.py +95 -0
  48. cognite/neat/_data_model/models/dms/_data_types.py +195 -0
  49. cognite/neat/_data_model/models/dms/_http.py +28 -0
  50. cognite/neat/_data_model/models/dms/_indexes.py +30 -0
  51. cognite/neat/_data_model/models/dms/_limits.py +96 -0
  52. cognite/neat/_data_model/models/dms/_references.py +135 -0
  53. cognite/neat/_data_model/models/dms/_schema.py +18 -0
  54. cognite/neat/_data_model/models/dms/_space.py +48 -0
  55. cognite/neat/_data_model/models/dms/_types.py +17 -0
  56. cognite/neat/_data_model/models/dms/_view_filter.py +282 -0
  57. cognite/neat/_data_model/models/dms/_view_property.py +235 -0
  58. cognite/neat/_data_model/models/dms/_views.py +210 -0
  59. cognite/neat/_data_model/models/entities/__init__.py +50 -0
  60. cognite/neat/_data_model/models/entities/_base.py +101 -0
  61. cognite/neat/_data_model/models/entities/_constants.py +22 -0
  62. cognite/neat/_data_model/models/entities/_data_types.py +144 -0
  63. cognite/neat/_data_model/models/entities/_identifiers.py +61 -0
  64. cognite/neat/_data_model/models/entities/_parser.py +226 -0
  65. cognite/neat/_data_model/validation/dms/__init__.py +75 -0
  66. cognite/neat/_data_model/validation/dms/_ai_readiness.py +364 -0
  67. cognite/neat/_data_model/validation/dms/_base.py +307 -0
  68. cognite/neat/_data_model/validation/dms/_connections.py +638 -0
  69. cognite/neat/_data_model/validation/dms/_consistency.py +57 -0
  70. cognite/neat/_data_model/validation/dms/_containers.py +174 -0
  71. cognite/neat/_data_model/validation/dms/_limits.py +420 -0
  72. cognite/neat/_data_model/validation/dms/_orchestrator.py +222 -0
  73. cognite/neat/_data_model/validation/dms/_views.py +103 -0
  74. cognite/neat/_exceptions.py +56 -0
  75. cognite/neat/_issues.py +68 -0
  76. cognite/neat/_session/__init__.py +3 -0
  77. cognite/neat/_session/_html/_render.py +30 -0
  78. cognite/neat/_session/_html/static/__init__.py +8 -0
  79. cognite/neat/_session/_html/static/deployment.css +303 -0
  80. cognite/neat/_session/_html/static/deployment.js +150 -0
  81. cognite/neat/_session/_html/static/issues.css +211 -0
  82. cognite/neat/_session/_html/static/issues.js +168 -0
  83. cognite/neat/_session/_html/static/shared.css +186 -0
  84. cognite/neat/_session/_html/templates/__init__.py +4 -0
  85. cognite/neat/_session/_html/templates/deployment.html +75 -0
  86. cognite/neat/_session/_html/templates/issues.html +45 -0
  87. cognite/neat/_session/_issues.py +81 -0
  88. cognite/neat/_session/_opt.py +35 -0
  89. cognite/neat/_session/_physical.py +261 -0
  90. cognite/neat/_session/_result.py +236 -0
  91. cognite/neat/_session/_session.py +88 -0
  92. cognite/neat/_session/_usage_analytics/__init__.py +0 -0
  93. cognite/neat/_session/_usage_analytics/_collector.py +131 -0
  94. cognite/neat/_session/_usage_analytics/_constants.py +23 -0
  95. cognite/neat/_session/_usage_analytics/_storage.py +240 -0
  96. cognite/neat/_session/_wrappers.py +82 -0
  97. cognite/neat/_state_machine/__init__.py +10 -0
  98. cognite/neat/_state_machine/_base.py +37 -0
  99. cognite/neat/_state_machine/_states.py +52 -0
  100. cognite/neat/_store/__init__.py +3 -0
  101. cognite/neat/_store/_provenance.py +81 -0
  102. cognite/neat/_store/_store.py +156 -0
  103. cognite/neat/_utils/__init__.py +0 -0
  104. cognite/neat/_utils/_reader.py +194 -0
  105. cognite/neat/_utils/auxiliary.py +39 -0
  106. cognite/neat/_utils/collection.py +11 -0
  107. cognite/neat/_utils/http_client/__init__.py +39 -0
  108. cognite/neat/_utils/http_client/_client.py +245 -0
  109. cognite/neat/_utils/http_client/_config.py +19 -0
  110. cognite/neat/_utils/http_client/_data_classes.py +294 -0
  111. cognite/neat/_utils/http_client/_tracker.py +31 -0
  112. cognite/neat/_utils/text.py +71 -0
  113. cognite/neat/_utils/useful_types.py +37 -0
  114. cognite/neat/_utils/validation.py +154 -0
  115. cognite/neat/_version.py +1 -1
  116. cognite/neat/v0/__init__.py +0 -0
  117. cognite/neat/v0/core/__init__.py +0 -0
  118. cognite/neat/v0/core/_client/_api/__init__.py +0 -0
  119. cognite/neat/{core → v0/core}/_client/_api/data_modeling_loaders.py +86 -7
  120. cognite/neat/{core → v0/core}/_client/_api/neat_instances.py +5 -5
  121. cognite/neat/{core → v0/core}/_client/_api/schema.py +5 -5
  122. cognite/neat/{core → v0/core}/_client/_api/statistics.py +3 -3
  123. cognite/neat/{core → v0/core}/_client/_api_client.py +1 -1
  124. cognite/neat/v0/core/_client/data_classes/__init__.py +0 -0
  125. cognite/neat/{core → v0/core}/_client/data_classes/schema.py +4 -4
  126. cognite/neat/{core → v0/core}/_client/testing.py +1 -1
  127. cognite/neat/{core → v0/core}/_constants.py +10 -3
  128. cognite/neat/v0/core/_data_model/__init__.py +0 -0
  129. cognite/neat/{core → v0/core}/_data_model/_constants.py +9 -6
  130. cognite/neat/{core → v0/core}/_data_model/_shared.py +5 -5
  131. cognite/neat/{core → v0/core}/_data_model/analysis/_base.py +12 -8
  132. cognite/neat/{core → v0/core}/_data_model/exporters/__init__.py +1 -2
  133. cognite/neat/{core → v0/core}/_data_model/exporters/_base.py +7 -7
  134. cognite/neat/{core → v0/core}/_data_model/exporters/_data_model2dms.py +9 -9
  135. cognite/neat/{core → v0/core}/_data_model/exporters/_data_model2excel.py +13 -13
  136. cognite/neat/{core → v0/core}/_data_model/exporters/_data_model2instance_template.py +4 -4
  137. cognite/neat/{core/_data_model/exporters/_data_model2ontology.py → v0/core/_data_model/exporters/_data_model2semantic_model.py} +126 -133
  138. cognite/neat/{core → v0/core}/_data_model/exporters/_data_model2yaml.py +1 -1
  139. cognite/neat/{core → v0/core}/_data_model/importers/__init__.py +4 -6
  140. cognite/neat/{core → v0/core}/_data_model/importers/_base.py +5 -5
  141. cognite/neat/{core → v0/core}/_data_model/importers/_base_file_reader.py +2 -2
  142. cognite/neat/{core → v0/core}/_data_model/importers/_dict2data_model.py +6 -6
  143. cognite/neat/{core → v0/core}/_data_model/importers/_dms2data_model.py +19 -16
  144. cognite/neat/v0/core/_data_model/importers/_graph2data_model.py +299 -0
  145. cognite/neat/v0/core/_data_model/importers/_rdf/__init__.py +4 -0
  146. cognite/neat/{core → v0/core}/_data_model/importers/_rdf/_base.py +13 -13
  147. cognite/neat/{core → v0/core}/_data_model/importers/_rdf/_inference2rdata_model.py +14 -14
  148. cognite/neat/v0/core/_data_model/importers/_rdf/_owl2data_model.py +144 -0
  149. cognite/neat/v0/core/_data_model/importers/_rdf/_shared.py +255 -0
  150. cognite/neat/{core → v0/core}/_data_model/importers/_spreadsheet2data_model.py +94 -13
  151. cognite/neat/{core → v0/core}/_data_model/models/__init__.py +3 -3
  152. cognite/neat/{core → v0/core}/_data_model/models/_base_verified.py +5 -5
  153. cognite/neat/v0/core/_data_model/models/_import_contexts.py +82 -0
  154. cognite/neat/{core → v0/core}/_data_model/models/_types.py +5 -5
  155. cognite/neat/{core → v0/core}/_data_model/models/conceptual/_unverified.py +18 -12
  156. cognite/neat/v0/core/_data_model/models/conceptual/_validation.py +308 -0
  157. cognite/neat/{core → v0/core}/_data_model/models/conceptual/_verified.py +13 -11
  158. cognite/neat/{core → v0/core}/_data_model/models/data_types.py +14 -4
  159. cognite/neat/{core → v0/core}/_data_model/models/entities/__init__.py +6 -0
  160. cognite/neat/v0/core/_data_model/models/entities/_loaders.py +155 -0
  161. cognite/neat/{core → v0/core}/_data_model/models/entities/_multi_value.py +2 -2
  162. cognite/neat/v0/core/_data_model/models/entities/_restrictions.py +230 -0
  163. cognite/neat/{core → v0/core}/_data_model/models/entities/_single_value.py +121 -16
  164. cognite/neat/{core → v0/core}/_data_model/models/entities/_types.py +10 -0
  165. cognite/neat/{core → v0/core}/_data_model/models/mapping/_classic2core.py +5 -5
  166. cognite/neat/{core → v0/core}/_data_model/models/physical/__init__.py +1 -1
  167. cognite/neat/{core → v0/core}/_data_model/models/physical/_exporter.py +28 -21
  168. cognite/neat/{core → v0/core}/_data_model/models/physical/_unverified.py +141 -38
  169. cognite/neat/{core → v0/core}/_data_model/models/physical/_validation.py +190 -24
  170. cognite/neat/{core → v0/core}/_data_model/models/physical/_verified.py +135 -15
  171. cognite/neat/{core → v0/core}/_data_model/transformers/__init__.py +2 -0
  172. cognite/neat/{core → v0/core}/_data_model/transformers/_base.py +4 -4
  173. cognite/neat/{core → v0/core}/_data_model/transformers/_converters.py +39 -32
  174. cognite/neat/{core → v0/core}/_data_model/transformers/_mapping.py +7 -7
  175. cognite/neat/v0/core/_data_model/transformers/_union_conceptual.py +208 -0
  176. cognite/neat/{core → v0/core}/_data_model/transformers/_verification.py +7 -7
  177. cognite/neat/v0/core/_instances/__init__.py +0 -0
  178. cognite/neat/{core → v0/core}/_instances/_tracking/base.py +1 -1
  179. cognite/neat/{core → v0/core}/_instances/_tracking/log.py +1 -1
  180. cognite/neat/{core → v0/core}/_instances/extractors/__init__.py +1 -1
  181. cognite/neat/{core → v0/core}/_instances/extractors/_base.py +6 -6
  182. cognite/neat/v0/core/_instances/extractors/_classic_cdf/__init__.py +0 -0
  183. cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_base.py +7 -7
  184. cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_classic.py +12 -12
  185. cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_relationships.py +3 -3
  186. cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_sequences.py +2 -2
  187. cognite/neat/{core → v0/core}/_instances/extractors/_dict.py +6 -3
  188. cognite/neat/{core → v0/core}/_instances/extractors/_dms.py +6 -6
  189. cognite/neat/{core → v0/core}/_instances/extractors/_dms_graph.py +11 -11
  190. cognite/neat/{core → v0/core}/_instances/extractors/_mock_graph_generator.py +10 -10
  191. cognite/neat/{core → v0/core}/_instances/extractors/_raw.py +3 -3
  192. cognite/neat/{core → v0/core}/_instances/extractors/_rdf_file.py +7 -7
  193. cognite/neat/{core → v0/core}/_instances/loaders/_base.py +5 -5
  194. cognite/neat/{core → v0/core}/_instances/loaders/_rdf2dms.py +17 -17
  195. cognite/neat/{core → v0/core}/_instances/loaders/_rdf_to_instance_space.py +11 -11
  196. cognite/neat/{core → v0/core}/_instances/queries/_select.py +29 -3
  197. cognite/neat/{core → v0/core}/_instances/queries/_update.py +1 -1
  198. cognite/neat/{core → v0/core}/_instances/transformers/_base.py +4 -4
  199. cognite/neat/{core → v0/core}/_instances/transformers/_classic_cdf.py +6 -6
  200. cognite/neat/{core → v0/core}/_instances/transformers/_prune_graph.py +4 -4
  201. cognite/neat/{core → v0/core}/_instances/transformers/_rdfpath.py +1 -1
  202. cognite/neat/{core → v0/core}/_instances/transformers/_value_type.py +4 -4
  203. cognite/neat/{core → v0/core}/_issues/_base.py +11 -6
  204. cognite/neat/{core → v0/core}/_issues/_contextmanagers.py +8 -6
  205. cognite/neat/{core → v0/core}/_issues/_factory.py +11 -8
  206. cognite/neat/{core → v0/core}/_issues/errors/__init__.py +3 -1
  207. cognite/neat/{core → v0/core}/_issues/errors/_external.py +1 -1
  208. cognite/neat/{core → v0/core}/_issues/errors/_general.py +1 -1
  209. cognite/neat/{core → v0/core}/_issues/errors/_properties.py +12 -1
  210. cognite/neat/{core → v0/core}/_issues/errors/_resources.py +2 -2
  211. cognite/neat/{core → v0/core}/_issues/errors/_wrapper.py +7 -3
  212. cognite/neat/{core → v0/core}/_issues/warnings/__init__.py +5 -1
  213. cognite/neat/{core → v0/core}/_issues/warnings/_external.py +1 -1
  214. cognite/neat/{core → v0/core}/_issues/warnings/_general.py +1 -1
  215. cognite/neat/{core → v0/core}/_issues/warnings/_models.py +39 -4
  216. cognite/neat/{core → v0/core}/_issues/warnings/_properties.py +13 -2
  217. cognite/neat/{core → v0/core}/_issues/warnings/_resources.py +1 -1
  218. cognite/neat/{core → v0/core}/_issues/warnings/user_modeling.py +1 -1
  219. cognite/neat/{core → v0/core}/_store/_data_model.py +13 -12
  220. cognite/neat/{core → v0/core}/_store/_instance.py +45 -12
  221. cognite/neat/{core → v0/core}/_store/_provenance.py +3 -3
  222. cognite/neat/{core → v0/core}/_store/exceptions.py +4 -4
  223. cognite/neat/v0/core/_utils/__init__.py +0 -0
  224. cognite/neat/{core → v0/core}/_utils/auth.py +1 -1
  225. cognite/neat/{core → v0/core}/_utils/auxiliary.py +7 -1
  226. cognite/neat/{core → v0/core}/_utils/collection_.py +2 -2
  227. cognite/neat/{core → v0/core}/_utils/graph_transformations_report.py +1 -1
  228. cognite/neat/{core → v0/core}/_utils/rdf_.py +38 -14
  229. cognite/neat/{core → v0/core}/_utils/reader/_base.py +1 -1
  230. cognite/neat/{core → v0/core}/_utils/spreadsheet.py +22 -4
  231. cognite/neat/v0/core/_utils/tarjan.py +44 -0
  232. cognite/neat/{core → v0/core}/_utils/text.py +1 -1
  233. cognite/neat/{core → v0/core}/_utils/upload.py +3 -3
  234. cognite/neat/v0/plugins/__init__.py +4 -0
  235. cognite/neat/v0/plugins/_base.py +9 -0
  236. cognite/neat/v0/plugins/_data_model.py +48 -0
  237. cognite/neat/{plugins → v0/plugins}/_issues.py +1 -1
  238. cognite/neat/{plugins → v0/plugins}/_manager.py +7 -16
  239. cognite/neat/{session → v0/session}/_base.py +13 -10
  240. cognite/neat/{session → v0/session}/_collector.py +1 -1
  241. cognite/neat/v0/session/_diff.py +51 -0
  242. cognite/neat/{session → v0/session}/_drop.py +3 -3
  243. cognite/neat/{session → v0/session}/_explore.py +2 -2
  244. cognite/neat/{session → v0/session}/_fix.py +2 -2
  245. cognite/neat/{session → v0/session}/_inspect.py +3 -3
  246. cognite/neat/{session → v0/session}/_mapping.py +3 -3
  247. cognite/neat/{session → v0/session}/_plugin.py +4 -5
  248. cognite/neat/{session → v0/session}/_prepare.py +8 -8
  249. cognite/neat/{session → v0/session}/_read.py +33 -43
  250. cognite/neat/{session → v0/session}/_set.py +8 -8
  251. cognite/neat/{session → v0/session}/_show.py +5 -5
  252. cognite/neat/{session → v0/session}/_state.py +22 -8
  253. cognite/neat/{session → v0/session}/_subset.py +4 -4
  254. cognite/neat/{session → v0/session}/_template.py +11 -11
  255. cognite/neat/{session → v0/session}/_to.py +12 -12
  256. cognite/neat/{session → v0/session}/_wizard.py +1 -1
  257. cognite/neat/{session → v0/session}/engine/_load.py +1 -1
  258. cognite/neat/{session → v0/session}/exceptions.py +5 -5
  259. cognite/neat/v1.py +3 -0
  260. {cognite_neat-0.123.2.dist-info → cognite_neat-0.127.30.dist-info}/METADATA +9 -8
  261. cognite_neat-0.127.30.dist-info/RECORD +319 -0
  262. {cognite_neat-0.123.2.dist-info → cognite_neat-0.127.30.dist-info}/WHEEL +1 -1
  263. cognite/neat/core/_data_model/importers/_dtdl2data_model/__init__.py +0 -3
  264. cognite/neat/core/_data_model/importers/_dtdl2data_model/_unit_lookup.py +0 -224
  265. cognite/neat/core/_data_model/importers/_dtdl2data_model/dtdl_converter.py +0 -320
  266. cognite/neat/core/_data_model/importers/_dtdl2data_model/dtdl_importer.py +0 -155
  267. cognite/neat/core/_data_model/importers/_dtdl2data_model/spec.py +0 -363
  268. cognite/neat/core/_data_model/importers/_rdf/__init__.py +0 -5
  269. cognite/neat/core/_data_model/importers/_rdf/_imf2data_model.py +0 -98
  270. cognite/neat/core/_data_model/importers/_rdf/_owl2data_model.py +0 -87
  271. cognite/neat/core/_data_model/importers/_rdf/_shared.py +0 -168
  272. cognite/neat/core/_data_model/models/conceptual/_validation.py +0 -294
  273. cognite/neat/core/_data_model/models/entities/_loaders.py +0 -75
  274. cognite/neat/plugins/__init__.py +0 -3
  275. cognite/neat/plugins/data_model/importers/__init__.py +0 -5
  276. cognite/neat/plugins/data_model/importers/_base.py +0 -28
  277. cognite_neat-0.123.2.dist-info/RECORD +0 -197
  278. /cognite/neat/{core → _data_model}/__init__.py +0 -0
  279. /cognite/neat/{core/_client/_api → _data_model/deployer}/__init__.py +0 -0
  280. /cognite/neat/{core/_client/data_classes → _data_model/exporters/_table_exporter}/__init__.py +0 -0
  281. /cognite/neat/{core/_data_model → _data_model/importers/_table_importer}/__init__.py +0 -0
  282. /cognite/neat/{core/_instances → _data_model/models}/__init__.py +0 -0
  283. /cognite/neat/{core/_instances/extractors/_classic_cdf → _data_model/models/conceptual}/__init__.py +0 -0
  284. /cognite/neat/{core/_utils → _data_model/validation}/__init__.py +0 -0
  285. /cognite/neat/{plugins/data_model → _session/_html}/__init__.py +0 -0
  286. /cognite/neat/{core → v0/core}/_client/__init__.py +0 -0
  287. /cognite/neat/{core → v0/core}/_client/data_classes/data_modeling.py +0 -0
  288. /cognite/neat/{core → v0/core}/_client/data_classes/neat_sequence.py +0 -0
  289. /cognite/neat/{core → v0/core}/_client/data_classes/statistics.py +0 -0
  290. /cognite/neat/{core → v0/core}/_config.py +0 -0
  291. /cognite/neat/{core → v0/core}/_data_model/analysis/__init__.py +0 -0
  292. /cognite/neat/{core → v0/core}/_data_model/catalog/__init__.py +0 -0
  293. /cognite/neat/{core → v0/core}/_data_model/catalog/classic_model.xlsx +0 -0
  294. /cognite/neat/{core → v0/core}/_data_model/catalog/conceptual-imf-data-model.xlsx +0 -0
  295. /cognite/neat/{core → v0/core}/_data_model/catalog/hello_world_pump.xlsx +0 -0
  296. /cognite/neat/{core → v0/core}/_data_model/models/_base_unverified.py +0 -0
  297. /cognite/neat/{core → v0/core}/_data_model/models/conceptual/__init__.py +0 -0
  298. /cognite/neat/{core → v0/core}/_data_model/models/entities/_constants.py +0 -0
  299. /cognite/neat/{core → v0/core}/_data_model/models/entities/_wrapped.py +0 -0
  300. /cognite/neat/{core → v0/core}/_data_model/models/mapping/__init__.py +0 -0
  301. /cognite/neat/{core → v0/core}/_data_model/models/mapping/_classic2core.yaml +0 -0
  302. /cognite/neat/{core → v0/core}/_instances/_shared.py +0 -0
  303. /cognite/neat/{core → v0/core}/_instances/_tracking/__init__.py +0 -0
  304. /cognite/neat/{core → v0/core}/_instances/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  305. /cognite/neat/{core → v0/core}/_instances/examples/Knowledge-Graph-Nordic44.xml +0 -0
  306. /cognite/neat/{core → v0/core}/_instances/examples/__init__.py +0 -0
  307. /cognite/neat/{core → v0/core}/_instances/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  308. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_assets.py +0 -0
  309. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_data_sets.py +0 -0
  310. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_events.py +0 -0
  311. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_files.py +0 -0
  312. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_labels.py +0 -0
  313. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_timeseries.py +0 -0
  314. /cognite/neat/{core → v0/core}/_instances/loaders/__init__.py +0 -0
  315. /cognite/neat/{core → v0/core}/_instances/queries/__init__.py +0 -0
  316. /cognite/neat/{core → v0/core}/_instances/queries/_base.py +0 -0
  317. /cognite/neat/{core → v0/core}/_instances/queries/_queries.py +0 -0
  318. /cognite/neat/{core → v0/core}/_instances/transformers/__init__.py +0 -0
  319. /cognite/neat/{core → v0/core}/_issues/__init__.py +0 -0
  320. /cognite/neat/{core → v0/core}/_issues/formatters.py +0 -0
  321. /cognite/neat/{core → v0/core}/_shared.py +0 -0
  322. /cognite/neat/{core → v0/core}/_store/__init__.py +0 -0
  323. /cognite/neat/{core → v0/core}/_utils/io_.py +0 -0
  324. /cognite/neat/{core → v0/core}/_utils/reader/__init__.py +0 -0
  325. /cognite/neat/{core → v0/core}/_utils/time_.py +0 -0
  326. /cognite/neat/{core → v0/core}/_utils/xml_.py +0 -0
  327. /cognite/neat/{session → v0/session}/__init__.py +0 -0
  328. /cognite/neat/{session → v0/session}/_experimental.py +0 -0
  329. /cognite/neat/{session → v0/session}/_state/README.md +0 -0
  330. /cognite/neat/{session → v0/session}/engine/__init__.py +0 -0
  331. /cognite/neat/{session → v0/session}/engine/_import.py +0 -0
  332. /cognite/neat/{session → v0/session}/engine/_interface.py +0 -0
  333. {cognite_neat-0.123.2.dist-info → cognite_neat-0.127.30.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,295 @@
1
+ import json
2
+ from collections.abc import Mapping
3
+ from typing import Annotated, Literal, cast, get_args
4
+
5
+ from pydantic import (
6
+ AliasGenerator,
7
+ BaseModel,
8
+ BeforeValidator,
9
+ Field,
10
+ PlainSerializer,
11
+ field_validator,
12
+ model_validator,
13
+ )
14
+ from pydantic.alias_generators import to_camel
15
+ from pydantic.fields import FieldInfo
16
+ from traitlets import Any
17
+
18
+ from cognite.neat._data_model.models.entities import ParsedEntity, parse_entities, parse_entity
19
+ from cognite.neat._utils.text import title_case
20
+ from cognite.neat._utils.useful_types import CellValueType
21
+ from cognite.neat.v0.core._data_model.models.entities import (
22
+ HasDataFilter,
23
+ NodeTypeFilter,
24
+ RawFilter,
25
+ )
26
+
27
+ # This marker is used to identify creator in the description field.
28
+ CREATOR_MARKER = "Creator: "
29
+ CREATOR_KEY = "creator"
30
+
31
+
32
+ def parse_entity_str(v: str) -> ParsedEntity:
33
+ if isinstance(v, ParsedEntity):
34
+ return v
35
+ try:
36
+ return parse_entity(v)
37
+ except ValueError as e:
38
+ raise ValueError(f"Invalid entity syntax: {e}") from e
39
+
40
+
41
+ def parse_entities_str(v: str) -> list[ParsedEntity] | None:
42
+ if isinstance(v, list) and all(isinstance(item, ParsedEntity) for item in v):
43
+ return v
44
+ try:
45
+ return parse_entities(v)
46
+ except ValueError as e:
47
+ raise ValueError(f"Invalid entity list syntax: {e}") from e
48
+
49
+
50
+ Entity = Annotated[ParsedEntity, BeforeValidator(parse_entity_str, str), PlainSerializer(func=str)]
51
+ EntityList = Annotated[
52
+ list[ParsedEntity],
53
+ BeforeValidator(parse_entities_str, str),
54
+ PlainSerializer(func=lambda v: ",".join([str(item) for item in v])),
55
+ ]
56
+
57
+
58
+ class TableObj(
59
+ BaseModel,
60
+ extra="ignore",
61
+ alias_generator=AliasGenerator(
62
+ alias=to_camel,
63
+ validation_alias=title_case,
64
+ serialization_alias=title_case,
65
+ ),
66
+ populate_by_name=True,
67
+ ): ...
68
+
69
+
70
+ class MetadataValue(TableObj):
71
+ key: str
72
+ value: CellValueType
73
+
74
+ @field_validator("key", mode="after")
75
+ def _legacy_external_id(cls, value: str) -> str:
76
+ return "externalId" if value.lower() == "external_id" else value
77
+
78
+
79
+ class DMSProperty(TableObj):
80
+ view: Entity
81
+ view_property: str
82
+ name: str | None = None
83
+ description: str | None = None
84
+ connection: Entity | None
85
+ value_type: Entity
86
+ min_count: int | None
87
+ max_count: int | None
88
+ immutable: bool | None = None
89
+ default: CellValueType | None = None
90
+ auto_increment: bool | None = None
91
+ container: Entity | None = None
92
+ container_property: str | None = None
93
+ container_property_name: str | None = None
94
+ container_property_description: str | None = None
95
+ index: EntityList | None = None
96
+ constraint: EntityList | None = None
97
+
98
+ @field_validator("max_count", mode="before")
99
+ @classmethod
100
+ def _legacy_max_count(cls, value: Any) -> Any | None:
101
+ """Validates and converts the max_count field if it uses the legacy 'inf' value."""
102
+ if isinstance(value, str) and value.lower() == "inf":
103
+ return None
104
+ return value
105
+
106
+ @model_validator(mode="before")
107
+ def _legacy_cardinality(cls, data: dict[str, Any]) -> dict[str, Any]:
108
+ """Converts Is List to Max Count and Nullable to Min Count."""
109
+ if not data:
110
+ return data
111
+
112
+ if "Max Count" not in data and "Is List" in data:
113
+ is_list = data.pop("Is List")
114
+ if isinstance(is_list, bool):
115
+ data["Max Count"] = None if is_list else 1
116
+
117
+ if "Min Count" not in data and "Nullable" in data:
118
+ nullable = data.pop("Nullable")
119
+ if isinstance(nullable, bool):
120
+ data["Min Count"] = 0 if nullable else 1
121
+
122
+ return data
123
+
124
+ @model_validator(mode="after")
125
+ def _legacy_index(self) -> "DMSProperty":
126
+ """Converts Is List to Max Count and Nullable to Min Count."""
127
+ if not self.index:
128
+ return self
129
+
130
+ for index in self.index:
131
+ if not index.prefix:
132
+ index.prefix = "inverted" if not self.max_count or self.max_count > 1 else "btree"
133
+
134
+ return self
135
+
136
+ @model_validator(mode="after")
137
+ def _legacy_constraint(self) -> "DMSProperty":
138
+ """Converts Is List to Max Count and Nullable to Min Count."""
139
+ if not self.constraint:
140
+ return self
141
+
142
+ for constraint in self.constraint:
143
+ if not constraint.prefix:
144
+ constraint.prefix = "uniqueness"
145
+
146
+ return self
147
+
148
+
149
+ class DMSView(TableObj):
150
+ view: Entity
151
+ name: str | None = None
152
+ description: str | None = None
153
+ implements: EntityList | None = None
154
+ filter: str | None = None
155
+
156
+ @field_validator("filter", mode="after")
157
+ def _legacy_filter(cls, value: str | None) -> str | None:
158
+ if value is None:
159
+ return value
160
+
161
+ value_lower = value.lower()
162
+
163
+ if value_lower.startswith("hasdata("):
164
+ return json.dumps(HasDataFilter.load(value).as_dms_filter().dump())
165
+ elif value_lower.startswith("nodetype("):
166
+ return json.dumps(NodeTypeFilter.load(value).as_dms_filter().dump())
167
+ elif value_lower.startswith("rawfilter("):
168
+ return json.dumps(RawFilter.load(value).as_dms_filter().dump())
169
+
170
+ return value
171
+
172
+
173
+ class DMSContainer(TableObj):
174
+ container: Entity
175
+ name: str | None = None
176
+ description: str | None = None
177
+ constraint: EntityList | None = None
178
+ used_for: str | None = None
179
+
180
+ @model_validator(mode="after")
181
+ def _legacy_constraint(self) -> "DMSContainer":
182
+ """Converts legacy constraint formats to the current standard."""
183
+ if not self.constraint:
184
+ return self
185
+
186
+ for constraint in self.constraint:
187
+ # Skip if already in correct format or being wrong but not legacy
188
+ if constraint.prefix == "requires" or constraint.properties:
189
+ continue
190
+
191
+ # This part handles legacy constraints
192
+ if not constraint.prefix:
193
+ constraint.prefix = "requires"
194
+ constraint.properties = {"require": constraint.suffix}
195
+
196
+ else:
197
+ container_space = constraint.prefix
198
+ container_external_id = constraint.suffix
199
+ constraint.prefix = "requires"
200
+ constraint.suffix = f"{container_space}_{container_external_id}"
201
+ constraint.properties = {"require": f"{container_space}:{container_external_id}"}
202
+
203
+ return self
204
+
205
+
206
+ class DMSEnum(TableObj):
207
+ collection: str
208
+ value: str
209
+ name: str | None = None
210
+ description: str | None = None
211
+
212
+
213
+ class DMSNode(TableObj):
214
+ node: Entity
215
+
216
+
217
+ class TableDMS(TableObj):
218
+ metadata: list[MetadataValue]
219
+ properties: list[DMSProperty]
220
+ views: list[DMSView]
221
+ containers: list[DMSContainer] = Field(default_factory=list)
222
+ enum: list[DMSEnum] = Field(default_factory=list)
223
+ nodes: list[DMSNode] = Field(default_factory=list)
224
+
225
+ @model_validator(mode="before")
226
+ def _title_case_keys(
227
+ cls, data: dict[str, list[dict[str, CellValueType]]]
228
+ ) -> dict[str, list[dict[str, CellValueType]]]:
229
+ if isinstance(data, dict):
230
+ # We are case-insensitive on the table names.
231
+ return {title_case(k): v for k, v in data.items()}
232
+ return data
233
+
234
+ @classmethod
235
+ def get_sheet_columns(
236
+ cls, sheet_id: str, sheet: FieldInfo | None = None, *, column_type: Literal["all", "required"] = "required"
237
+ ) -> list[str]:
238
+ if sheet_id not in cls.model_fields.keys():
239
+ raise KeyError(f"Invalid field id: {sheet_id}")
240
+ if sheet is None:
241
+ sheet = cls.model_fields[sheet_id]
242
+ return [
243
+ # We know all fields has validation_alias because of the alias_generator in TableDMS
244
+ cast(str, sheet_field.validation_alias)
245
+ # All the fields in the sheet's model are lists.
246
+ for sheet_field in get_args(sheet.annotation)[0].model_fields.values()
247
+ if sheet_field.is_required() or column_type == "all"
248
+ ]
249
+
250
+ @classmethod
251
+ def get_sheet_column_by_name(
252
+ cls, sheet_name: str, *, column_type: Literal["all", "required"] = "required"
253
+ ) -> list[str]:
254
+ for field_id, field_ in cls.model_fields.items():
255
+ if cast(str, field_.validation_alias) == sheet_name:
256
+ return cls.get_sheet_columns(field_id, field_, column_type=column_type)
257
+ raise KeyError(f"Invalid field alias: {sheet_name}")
258
+
259
+ @classmethod
260
+ def required_sheets(cls) -> set[str]:
261
+ return {cast(str, field_.validation_alias) for field_ in cls.model_fields.values() if field_.is_required()}
262
+
263
+
264
+ DMS_API_MAPPING: Mapping[str, Mapping[str, str]] = {
265
+ "Views": {
266
+ "space": "View",
267
+ "externalId": "View",
268
+ "version": "View",
269
+ **{
270
+ cast(str, field_.alias): cast(str, field_.validation_alias)
271
+ for field_id, field_ in DMSView.model_fields.items()
272
+ if field_id != "View"
273
+ },
274
+ },
275
+ "Containers": {
276
+ "space": "Container",
277
+ "externalId": "Container",
278
+ **{
279
+ cast(str, field_.alias): cast(str, field_.validation_alias)
280
+ for field_id, field_ in DMSContainer.model_fields.items()
281
+ if field_id != "Container"
282
+ },
283
+ },
284
+ "Properties": {
285
+ "space": "View",
286
+ "externalId": "View",
287
+ "property": "ViewProperty",
288
+ "type": "Value Type",
289
+ **{
290
+ cast(str, field_.alias): cast(str, field_.validation_alias)
291
+ for field_id, field_ in DMSProperty.model_fields.items()
292
+ if field_id not in ("View", "ViewProperty")
293
+ },
294
+ },
295
+ }
@@ -0,0 +1,192 @@
1
+ import warnings
2
+ from collections.abc import Mapping
3
+ from pathlib import Path
4
+ from typing import ClassVar, cast
5
+
6
+ import yaml
7
+ from openpyxl import load_workbook
8
+ from openpyxl.worksheet.worksheet import Worksheet
9
+ from pydantic import ValidationError
10
+
11
+ from cognite.neat._data_model.importers._base import DMSImporter
12
+ from cognite.neat._data_model.models.dms import (
13
+ RequestSchema,
14
+ )
15
+ from cognite.neat._exceptions import DataModelImportException
16
+ from cognite.neat._issues import ModelSyntaxError
17
+ from cognite.neat._utils.text import humanize_collection
18
+ from cognite.neat._utils.useful_types import CellValueType, DataModelTableType
19
+ from cognite.neat._utils.validation import ValidationContext, as_json_path, humanize_validation_error
20
+
21
+ from .data_classes import MetadataValue, TableDMS
22
+ from .reader import DMSTableReader
23
+ from .source import SpreadsheetReadContext, TableSource
24
+
25
+
26
+ class DMSTableImporter(DMSImporter):
27
+ """Imports DMS from a table structure.
28
+
29
+ The tables can are expected to be a dictionary where the keys are the table names and the values
30
+ are lists of dictionaries representing the rows in the table.
31
+ """
32
+
33
+ # We can safely cast as we know the validation_alias is always set to a str.
34
+ REQUIRED_SHEETS = tuple(
35
+ cast(str, field_.validation_alias) for field_ in TableDMS.model_fields.values() if field_.is_required()
36
+ )
37
+ REQUIRED_SHEET_MESSAGES: ClassVar[Mapping[str, str]] = {
38
+ f"Missing required column: {sheet!r}": f"Missing required sheet: {sheet!r}" for sheet in REQUIRED_SHEETS
39
+ }
40
+ MetadataSheet = cast(str, TableDMS.model_fields["metadata"].validation_alias)
41
+
42
+ def __init__(self, tables: DataModelTableType, source: TableSource | None = None) -> None:
43
+ self._table = tables
44
+ self._source = source or TableSource("Unknown")
45
+
46
+ def to_data_model(self) -> RequestSchema:
47
+ tables = self._read_tables()
48
+
49
+ space, version = self._read_defaults(tables.metadata)
50
+ reader = DMSTableReader(space, version, self._source)
51
+ return reader.read_tables(tables)
52
+
53
+ @classmethod
54
+ def from_yaml(cls, yaml_file: Path) -> "DMSTableImporter":
55
+ """Create a DMSTableImporter from a YAML file."""
56
+ source = cls._display_name(yaml_file)
57
+ return cls(yaml.safe_load(yaml_file.read_text()), TableSource(source.as_posix()))
58
+
59
+ @classmethod
60
+ def from_json(cls, json_file: Path) -> "DMSTableImporter":
61
+ """Create a DMSTableImporter from a JSON file."""
62
+ return cls.from_yaml(json_file)
63
+
64
+ @classmethod
65
+ def from_excel(cls, excel_file: Path) -> "DMSTableImporter":
66
+ """Create a DMSTableImporter from an Excel file."""
67
+ tables: DataModelTableType = {}
68
+ source = TableSource(cls._display_name(excel_file).as_posix())
69
+ workbook = load_workbook(excel_file, read_only=True, data_only=True, rich_text=False)
70
+ try:
71
+ for column_id, column_info in TableDMS.model_fields.items():
72
+ sheet_name = cast(str, column_info.validation_alias)
73
+ if sheet_name not in workbook.sheetnames:
74
+ continue
75
+ required_columns = TableDMS.get_sheet_columns(column_id, column_info, column_type="required")
76
+ sheet = workbook[sheet_name]
77
+ context = SpreadsheetReadContext()
78
+ table_rows = cls._read_rows(sheet, required_columns, context)
79
+ tables[sheet_name] = table_rows
80
+ source.table_read[sheet_name] = context
81
+ return cls(tables, source)
82
+ finally:
83
+ workbook.close()
84
+
85
+ def _read_tables(self) -> TableDMS:
86
+ try:
87
+ # Check tables, columns, data type and entity syntax.
88
+ table = TableDMS.model_validate(self._table)
89
+ except ValidationError as e:
90
+ errors = self._create_error_messages(e)
91
+ raise DataModelImportException(errors) from None
92
+ return table
93
+
94
+ def _create_error_messages(self, error: ValidationError) -> list[ModelSyntaxError]:
95
+ errors: list[ModelSyntaxError] = []
96
+ context = ValidationContext(
97
+ humanize_location=self._location,
98
+ field_name="column",
99
+ missing_required_descriptor="missing",
100
+ )
101
+ seen: set[str] = set()
102
+
103
+ for error_details in error.errors(include_input=True, include_url=False):
104
+ message = humanize_validation_error(error_details, context)
105
+ # Replace messages about missing required columns with missing required sheets.
106
+ message = self.REQUIRED_SHEET_MESSAGES.get(message, message)
107
+ if message in seen:
108
+ # We treat all rows as the same, so we get duplicated errors for each row.
109
+ continue
110
+
111
+ seen.add(message)
112
+ errors.append(ModelSyntaxError(message=message))
113
+
114
+ return errors
115
+
116
+ def _location(self, loc: tuple[str | int, ...]) -> str:
117
+ if isinstance(loc[0], str) and len(loc) == 2: # Sheet + row.
118
+ # We skip the row as we treat all rows as the same. For example, if a required column is missing in one
119
+ # row, it is missing in all rows.
120
+ return f"{loc[0]} sheet"
121
+ elif len(loc) == 3 and isinstance(loc[0], str) and isinstance(loc[1], int) and isinstance(loc[2], str):
122
+ # This means there is something wrong in a specific cell.
123
+
124
+ sheet = loc[0]
125
+ row = loc[1]
126
+ if self._source and sheet in self._source.table_read:
127
+ context = self._source.table_read[sheet]
128
+ row = context.adjusted_row_number(row) - 1
129
+
130
+ return f"{sheet} sheet row {row + 1} column {loc[2]!r}"
131
+ # This should be unreachable as the TableDMS model only has 2 levels.
132
+ return as_json_path(loc)
133
+
134
+ @staticmethod
135
+ def _read_defaults(metadata: list[MetadataValue]) -> tuple[str, str]:
136
+ """Reads the space and version from the metadata table."""
137
+ default_space: str | None = None
138
+ default_version: str | None = None
139
+ missing = {"space", "version"}
140
+ for meta in metadata:
141
+ if meta.key == "space":
142
+ default_space = str(meta.value)
143
+ missing.remove("space")
144
+ elif meta.key == "version":
145
+ default_version = str(meta.value)
146
+ missing.remove("version")
147
+ if missing:
148
+ error = ModelSyntaxError(message=f"In Metadata missing required values: {humanize_collection(missing)}")
149
+ # If space or version is missing, we cannot continue parsing the model as these are used as defaults.
150
+ raise DataModelImportException([error]) from None
151
+ return str(default_space), str(default_version)
152
+
153
+ @classmethod
154
+ def _display_name(cls, filepath: Path) -> Path:
155
+ """Get a display-friendly version of the file path."""
156
+ cwd = Path.cwd()
157
+ source = filepath
158
+ if filepath.is_relative_to(cwd):
159
+ source = filepath.relative_to(cwd)
160
+ return source
161
+
162
+ @classmethod
163
+ def _read_rows(
164
+ cls, sheet: Worksheet, required_columns: list[str], context: SpreadsheetReadContext
165
+ ) -> list[dict[str, CellValueType]]:
166
+ table_rows: list[dict[str, CellValueType]] = []
167
+ # Metadata sheet is just a key-value pair of the first two columns.
168
+ # For other sheets, we need to find the column header row first.
169
+ columns: list[str] = [] if sheet.title != cls.MetadataSheet else required_columns
170
+ # Ignore warnings about Data Validation extension not being supported in read-only mode.
171
+ warnings.filterwarnings("ignore", category=UserWarning, message="Data Validation extension is not supported*")
172
+ # The .iter_rows with values_only=True raises the warning `UserWarning: Data Validation extension is
173
+ # not supported and will be removed`
174
+ # which confuses the user and we do not depend on data validation here, so we suppress it.
175
+ for row_no, row in enumerate(sheet.iter_rows(values_only=True)):
176
+ if columns:
177
+ # We have found the column header row, read the data rows.
178
+ if all(cell is None for cell in row):
179
+ context.empty_rows.append(row_no)
180
+ else:
181
+ record = dict(zip(columns, row, strict=False))
182
+ # MyPy complains as it thinks DataTableFormula | ArrayFormula could be cell values,
183
+ # but as we used values_only=True, this is not the case.
184
+ table_rows.append(record) # type: ignore[arg-type]
185
+ else:
186
+ # Look for the column header row.
187
+ row_values = [str(cell) for cell in row]
188
+ if set(row_values).intersection(required_columns):
189
+ columns = row_values
190
+ context.header_row = row_no
191
+
192
+ return table_rows