cognite-neat 0.70.1__py3-none-any.whl → 0.127.19__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 (530) hide show
  1. cognite/neat/__init__.py +4 -1
  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/_data_model/_analysis.py +186 -0
  13. cognite/neat/_data_model/_constants.py +67 -0
  14. cognite/neat/_data_model/_identifiers.py +61 -0
  15. cognite/neat/_data_model/_shared.py +41 -0
  16. cognite/neat/_data_model/deployer/_differ.py +140 -0
  17. cognite/neat/_data_model/deployer/_differ_container.py +360 -0
  18. cognite/neat/_data_model/deployer/_differ_data_model.py +54 -0
  19. cognite/neat/_data_model/deployer/_differ_space.py +9 -0
  20. cognite/neat/_data_model/deployer/_differ_view.py +299 -0
  21. cognite/neat/_data_model/deployer/data_classes.py +529 -0
  22. cognite/neat/_data_model/deployer/deployer.py +401 -0
  23. cognite/neat/_data_model/exporters/__init__.py +15 -0
  24. cognite/neat/_data_model/exporters/_api_exporter.py +37 -0
  25. cognite/neat/_data_model/exporters/_base.py +24 -0
  26. cognite/neat/_data_model/exporters/_table_exporter/exporter.py +128 -0
  27. cognite/neat/_data_model/exporters/_table_exporter/workbook.py +409 -0
  28. cognite/neat/_data_model/exporters/_table_exporter/writer.py +399 -0
  29. cognite/neat/_data_model/importers/__init__.py +5 -0
  30. cognite/neat/_data_model/importers/_api_importer.py +166 -0
  31. cognite/neat/_data_model/importers/_base.py +16 -0
  32. cognite/neat/_data_model/importers/_table_importer/data_classes.py +291 -0
  33. cognite/neat/_data_model/importers/_table_importer/importer.py +192 -0
  34. cognite/neat/_data_model/importers/_table_importer/reader.py +875 -0
  35. cognite/neat/_data_model/importers/_table_importer/source.py +94 -0
  36. cognite/neat/_data_model/models/conceptual/_base.py +18 -0
  37. cognite/neat/_data_model/models/conceptual/_concept.py +67 -0
  38. cognite/neat/_data_model/models/conceptual/_data_model.py +51 -0
  39. cognite/neat/_data_model/models/conceptual/_properties.py +104 -0
  40. cognite/neat/_data_model/models/conceptual/_property.py +105 -0
  41. cognite/neat/_data_model/models/dms/__init__.py +206 -0
  42. cognite/neat/_data_model/models/dms/_base.py +31 -0
  43. cognite/neat/_data_model/models/dms/_constants.py +47 -0
  44. cognite/neat/_data_model/models/dms/_constraints.py +42 -0
  45. cognite/neat/_data_model/models/dms/_container.py +159 -0
  46. cognite/neat/_data_model/models/dms/_data_model.py +94 -0
  47. cognite/neat/_data_model/models/dms/_data_types.py +195 -0
  48. cognite/neat/_data_model/models/dms/_http.py +28 -0
  49. cognite/neat/_data_model/models/dms/_indexes.py +30 -0
  50. cognite/neat/_data_model/models/dms/_limits.py +96 -0
  51. cognite/neat/_data_model/models/dms/_references.py +135 -0
  52. cognite/neat/_data_model/models/dms/_schema.py +18 -0
  53. cognite/neat/_data_model/models/dms/_space.py +48 -0
  54. cognite/neat/_data_model/models/dms/_types.py +17 -0
  55. cognite/neat/_data_model/models/dms/_view_filter.py +282 -0
  56. cognite/neat/_data_model/models/dms/_view_property.py +235 -0
  57. cognite/neat/_data_model/models/dms/_views.py +210 -0
  58. cognite/neat/_data_model/models/entities/__init__.py +50 -0
  59. cognite/neat/_data_model/models/entities/_base.py +101 -0
  60. cognite/neat/_data_model/models/entities/_constants.py +22 -0
  61. cognite/neat/_data_model/models/entities/_data_types.py +144 -0
  62. cognite/neat/_data_model/models/entities/_identifiers.py +61 -0
  63. cognite/neat/_data_model/models/entities/_parser.py +226 -0
  64. cognite/neat/_data_model/validation/dms/__init__.py +57 -0
  65. cognite/neat/_data_model/validation/dms/_ai_readiness.py +167 -0
  66. cognite/neat/_data_model/validation/dms/_base.py +304 -0
  67. cognite/neat/_data_model/validation/dms/_connections.py +627 -0
  68. cognite/neat/_data_model/validation/dms/_consistency.py +56 -0
  69. cognite/neat/_data_model/validation/dms/_containers.py +135 -0
  70. cognite/neat/_data_model/validation/dms/_limits.py +414 -0
  71. cognite/neat/_data_model/validation/dms/_orchestrator.py +202 -0
  72. cognite/neat/_data_model/validation/dms/_views.py +101 -0
  73. cognite/neat/_exceptions.py +56 -0
  74. cognite/neat/_issues.py +68 -0
  75. cognite/neat/_session/__init__.py +3 -0
  76. cognite/neat/_session/_html/_render.py +30 -0
  77. cognite/neat/_session/_html/static/__init__.py +8 -0
  78. cognite/neat/_session/_html/static/deployment.css +303 -0
  79. cognite/neat/_session/_html/static/deployment.js +149 -0
  80. cognite/neat/_session/_html/static/issues.css +211 -0
  81. cognite/neat/_session/_html/static/issues.js +167 -0
  82. cognite/neat/_session/_html/static/shared.css +186 -0
  83. cognite/neat/_session/_html/templates/__init__.py +4 -0
  84. cognite/neat/_session/_html/templates/deployment.html +74 -0
  85. cognite/neat/_session/_html/templates/issues.html +44 -0
  86. cognite/neat/_session/_issues.py +76 -0
  87. cognite/neat/_session/_opt.py +35 -0
  88. cognite/neat/_session/_physical.py +240 -0
  89. cognite/neat/_session/_result.py +231 -0
  90. cognite/neat/_session/_session.py +69 -0
  91. cognite/neat/_session/_usage_analytics/_collector.py +131 -0
  92. cognite/neat/_session/_usage_analytics/_constants.py +23 -0
  93. cognite/neat/_session/_usage_analytics/_storage.py +240 -0
  94. cognite/neat/_session/_wrappers.py +82 -0
  95. cognite/neat/_state_machine/__init__.py +10 -0
  96. cognite/neat/_state_machine/_base.py +37 -0
  97. cognite/neat/_state_machine/_states.py +52 -0
  98. cognite/neat/_store/__init__.py +3 -0
  99. cognite/neat/_store/_provenance.py +71 -0
  100. cognite/neat/_store/_store.py +144 -0
  101. cognite/neat/_utils/_reader.py +194 -0
  102. cognite/neat/_utils/auxiliary.py +39 -0
  103. cognite/neat/_utils/collection.py +11 -0
  104. cognite/neat/_utils/http_client/__init__.py +39 -0
  105. cognite/neat/_utils/http_client/_client.py +245 -0
  106. cognite/neat/_utils/http_client/_config.py +19 -0
  107. cognite/neat/_utils/http_client/_data_classes.py +294 -0
  108. cognite/neat/_utils/http_client/_tracker.py +31 -0
  109. cognite/neat/_utils/text.py +71 -0
  110. cognite/neat/_utils/useful_types.py +37 -0
  111. cognite/neat/_utils/validation.py +149 -0
  112. cognite/neat/_version.py +2 -1
  113. cognite/neat/v0/core/__init__.py +0 -0
  114. cognite/neat/v0/core/_client/__init__.py +4 -0
  115. cognite/neat/v0/core/_client/_api/__init__.py +0 -0
  116. cognite/neat/v0/core/_client/_api/data_modeling_loaders.py +1032 -0
  117. cognite/neat/v0/core/_client/_api/neat_instances.py +101 -0
  118. cognite/neat/v0/core/_client/_api/schema.py +158 -0
  119. cognite/neat/v0/core/_client/_api/statistics.py +91 -0
  120. cognite/neat/v0/core/_client/_api_client.py +21 -0
  121. cognite/neat/v0/core/_client/data_classes/__init__.py +0 -0
  122. cognite/neat/v0/core/_client/data_classes/data_modeling.py +198 -0
  123. cognite/neat/v0/core/_client/data_classes/neat_sequence.py +261 -0
  124. cognite/neat/v0/core/_client/data_classes/schema.py +540 -0
  125. cognite/neat/v0/core/_client/data_classes/statistics.py +125 -0
  126. cognite/neat/v0/core/_client/testing.py +39 -0
  127. cognite/neat/v0/core/_config.py +11 -0
  128. cognite/neat/v0/core/_constants.py +278 -0
  129. cognite/neat/v0/core/_data_model/__init__.py +0 -0
  130. cognite/neat/v0/core/_data_model/_constants.py +210 -0
  131. cognite/neat/v0/core/_data_model/_shared.py +59 -0
  132. cognite/neat/v0/core/_data_model/analysis/__init__.py +3 -0
  133. cognite/neat/v0/core/_data_model/analysis/_base.py +578 -0
  134. cognite/neat/v0/core/_data_model/catalog/__init__.py +8 -0
  135. cognite/neat/v0/core/_data_model/catalog/classic_model.xlsx +0 -0
  136. cognite/neat/v0/core/_data_model/catalog/conceptual-imf-data-model.xlsx +0 -0
  137. cognite/neat/v0/core/_data_model/catalog/hello_world_pump.xlsx +0 -0
  138. cognite/neat/v0/core/_data_model/exporters/__init__.py +38 -0
  139. cognite/neat/v0/core/_data_model/exporters/_base.py +67 -0
  140. cognite/neat/v0/core/_data_model/exporters/_data_model2dms.py +428 -0
  141. cognite/neat/v0/core/_data_model/exporters/_data_model2excel.py +612 -0
  142. cognite/neat/v0/core/_data_model/exporters/_data_model2instance_template.py +158 -0
  143. cognite/neat/v0/core/_data_model/exporters/_data_model2semantic_model.py +646 -0
  144. cognite/neat/v0/core/_data_model/exporters/_data_model2yaml.py +84 -0
  145. cognite/neat/v0/core/_data_model/importers/__init__.py +49 -0
  146. cognite/neat/v0/core/_data_model/importers/_base.py +64 -0
  147. cognite/neat/v0/core/_data_model/importers/_base_file_reader.py +56 -0
  148. cognite/neat/v0/core/_data_model/importers/_dict2data_model.py +131 -0
  149. cognite/neat/v0/core/_data_model/importers/_dms2data_model.py +705 -0
  150. cognite/neat/v0/core/_data_model/importers/_graph2data_model.py +299 -0
  151. cognite/neat/v0/core/_data_model/importers/_rdf/__init__.py +4 -0
  152. cognite/neat/v0/core/_data_model/importers/_rdf/_base.py +161 -0
  153. cognite/neat/v0/core/_data_model/importers/_rdf/_inference2rdata_model.py +618 -0
  154. cognite/neat/v0/core/_data_model/importers/_rdf/_owl2data_model.py +124 -0
  155. cognite/neat/v0/core/_data_model/importers/_rdf/_shared.py +255 -0
  156. cognite/neat/v0/core/_data_model/importers/_spreadsheet2data_model.py +424 -0
  157. cognite/neat/v0/core/_data_model/models/__init__.py +38 -0
  158. cognite/neat/v0/core/_data_model/models/_base_unverified.py +181 -0
  159. cognite/neat/v0/core/_data_model/models/_base_verified.py +449 -0
  160. cognite/neat/v0/core/_data_model/models/_import_contexts.py +82 -0
  161. cognite/neat/v0/core/_data_model/models/_types.py +171 -0
  162. cognite/neat/v0/core/_data_model/models/conceptual/__init__.py +25 -0
  163. cognite/neat/v0/core/_data_model/models/conceptual/_unverified.py +193 -0
  164. cognite/neat/v0/core/_data_model/models/conceptual/_validation.py +308 -0
  165. cognite/neat/v0/core/_data_model/models/conceptual/_verified.py +327 -0
  166. cognite/neat/v0/core/_data_model/models/data_types.py +422 -0
  167. cognite/neat/v0/core/_data_model/models/entities/__init__.py +70 -0
  168. cognite/neat/v0/core/_data_model/models/entities/_constants.py +18 -0
  169. cognite/neat/v0/core/_data_model/models/entities/_loaders.py +155 -0
  170. cognite/neat/v0/core/_data_model/models/entities/_multi_value.py +83 -0
  171. cognite/neat/v0/core/_data_model/models/entities/_restrictions.py +230 -0
  172. cognite/neat/v0/core/_data_model/models/entities/_single_value.py +676 -0
  173. cognite/neat/v0/core/_data_model/models/entities/_types.py +103 -0
  174. cognite/neat/v0/core/_data_model/models/entities/_wrapped.py +217 -0
  175. cognite/neat/v0/core/_data_model/models/mapping/__init__.py +3 -0
  176. cognite/neat/v0/core/_data_model/models/mapping/_classic2core.py +39 -0
  177. cognite/neat/v0/core/_data_model/models/mapping/_classic2core.yaml +608 -0
  178. cognite/neat/v0/core/_data_model/models/physical/__init__.py +40 -0
  179. cognite/neat/v0/core/_data_model/models/physical/_exporter.py +658 -0
  180. cognite/neat/v0/core/_data_model/models/physical/_unverified.py +557 -0
  181. cognite/neat/v0/core/_data_model/models/physical/_validation.py +887 -0
  182. cognite/neat/v0/core/_data_model/models/physical/_verified.py +667 -0
  183. cognite/neat/v0/core/_data_model/transformers/__init__.py +70 -0
  184. cognite/neat/v0/core/_data_model/transformers/_base.py +79 -0
  185. cognite/neat/v0/core/_data_model/transformers/_converters.py +2485 -0
  186. cognite/neat/v0/core/_data_model/transformers/_mapping.py +390 -0
  187. cognite/neat/v0/core/_data_model/transformers/_union_conceptual.py +208 -0
  188. cognite/neat/v0/core/_data_model/transformers/_verification.py +120 -0
  189. cognite/neat/v0/core/_instances/__init__.py +0 -0
  190. cognite/neat/v0/core/_instances/_shared.py +37 -0
  191. cognite/neat/v0/core/_instances/_tracking/__init__.py +4 -0
  192. cognite/neat/v0/core/_instances/_tracking/base.py +30 -0
  193. cognite/neat/v0/core/_instances/_tracking/log.py +27 -0
  194. cognite/neat/v0/core/_instances/extractors/__init__.py +76 -0
  195. cognite/neat/v0/core/_instances/extractors/_base.py +58 -0
  196. cognite/neat/v0/core/_instances/extractors/_classic_cdf/__init__.py +0 -0
  197. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_assets.py +37 -0
  198. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_base.py +443 -0
  199. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_classic.py +479 -0
  200. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_data_sets.py +35 -0
  201. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_events.py +33 -0
  202. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_files.py +45 -0
  203. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_labels.py +54 -0
  204. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_relationships.py +122 -0
  205. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_sequences.py +280 -0
  206. cognite/neat/v0/core/_instances/extractors/_classic_cdf/_timeseries.py +48 -0
  207. cognite/neat/v0/core/_instances/extractors/_dict.py +105 -0
  208. cognite/neat/v0/core/_instances/extractors/_dms.py +315 -0
  209. cognite/neat/v0/core/_instances/extractors/_dms_graph.py +238 -0
  210. cognite/neat/v0/core/_instances/extractors/_mock_graph_generator.py +404 -0
  211. cognite/neat/v0/core/_instances/extractors/_raw.py +67 -0
  212. cognite/neat/v0/core/_instances/extractors/_rdf_file.py +80 -0
  213. cognite/neat/v0/core/_instances/loaders/__init__.py +24 -0
  214. cognite/neat/v0/core/_instances/loaders/_base.py +116 -0
  215. cognite/neat/v0/core/_instances/loaders/_rdf2dms.py +649 -0
  216. cognite/neat/v0/core/_instances/loaders/_rdf_to_instance_space.py +249 -0
  217. cognite/neat/v0/core/_instances/queries/__init__.py +3 -0
  218. cognite/neat/v0/core/_instances/queries/_base.py +16 -0
  219. cognite/neat/v0/core/_instances/queries/_queries.py +16 -0
  220. cognite/neat/v0/core/_instances/queries/_select.py +478 -0
  221. cognite/neat/v0/core/_instances/queries/_update.py +37 -0
  222. cognite/neat/v0/core/_instances/transformers/__init__.py +65 -0
  223. cognite/neat/v0/core/_instances/transformers/_base.py +133 -0
  224. cognite/neat/v0/core/_instances/transformers/_classic_cdf.py +589 -0
  225. cognite/neat/v0/core/_instances/transformers/_prune_graph.py +315 -0
  226. cognite/neat/v0/core/_instances/transformers/_rdfpath.py +84 -0
  227. cognite/neat/v0/core/_instances/transformers/_value_type.py +366 -0
  228. cognite/neat/v0/core/_issues/__init__.py +21 -0
  229. cognite/neat/v0/core/_issues/_base.py +348 -0
  230. cognite/neat/v0/core/_issues/_contextmanagers.py +50 -0
  231. cognite/neat/v0/core/_issues/_factory.py +69 -0
  232. cognite/neat/v0/core/_issues/errors/__init__.py +90 -0
  233. cognite/neat/v0/core/_issues/errors/_external.py +91 -0
  234. cognite/neat/v0/core/_issues/errors/_general.py +51 -0
  235. cognite/neat/v0/core/_issues/errors/_properties.py +80 -0
  236. cognite/neat/v0/core/_issues/errors/_resources.py +116 -0
  237. cognite/neat/v0/core/_issues/errors/_wrapper.py +93 -0
  238. cognite/neat/{rules/issues → v0/core/_issues}/formatters.py +12 -10
  239. cognite/neat/v0/core/_issues/warnings/__init__.py +99 -0
  240. cognite/neat/v0/core/_issues/warnings/_external.py +56 -0
  241. cognite/neat/v0/core/_issues/warnings/_general.py +46 -0
  242. cognite/neat/v0/core/_issues/warnings/_models.py +165 -0
  243. cognite/neat/v0/core/_issues/warnings/_properties.py +108 -0
  244. cognite/neat/v0/core/_issues/warnings/_resources.py +110 -0
  245. cognite/neat/v0/core/_issues/warnings/user_modeling.py +125 -0
  246. cognite/neat/v0/core/_shared.py +77 -0
  247. cognite/neat/v0/core/_store/__init__.py +4 -0
  248. cognite/neat/v0/core/_store/_data_model.py +487 -0
  249. cognite/neat/v0/core/_store/_instance.py +485 -0
  250. cognite/neat/v0/core/_store/_provenance.py +217 -0
  251. cognite/neat/v0/core/_store/exceptions.py +59 -0
  252. cognite/neat/v0/core/_utils/__init__.py +0 -0
  253. cognite/neat/v0/core/_utils/auth.py +364 -0
  254. cognite/neat/v0/core/_utils/auxiliary.py +169 -0
  255. cognite/neat/v0/core/_utils/collection_.py +66 -0
  256. cognite/neat/v0/core/_utils/graph_transformations_report.py +36 -0
  257. cognite/neat/v0/core/_utils/io_.py +11 -0
  258. cognite/neat/v0/core/_utils/rdf_.py +336 -0
  259. cognite/neat/v0/core/_utils/reader/__init__.py +3 -0
  260. cognite/neat/v0/core/_utils/reader/_base.py +194 -0
  261. cognite/neat/v0/core/_utils/spreadsheet.py +182 -0
  262. cognite/neat/v0/core/_utils/tarjan.py +44 -0
  263. cognite/neat/v0/core/_utils/text.py +277 -0
  264. cognite/neat/v0/core/_utils/time_.py +17 -0
  265. cognite/neat/v0/core/_utils/upload.py +134 -0
  266. cognite/neat/v0/core/_utils/xml_.py +52 -0
  267. cognite/neat/v0/plugins/__init__.py +4 -0
  268. cognite/neat/v0/plugins/_base.py +9 -0
  269. cognite/neat/v0/plugins/_data_model.py +48 -0
  270. cognite/neat/v0/plugins/_issues.py +35 -0
  271. cognite/neat/v0/plugins/_manager.py +94 -0
  272. cognite/neat/v0/session/__init__.py +3 -0
  273. cognite/neat/v0/session/_base.py +332 -0
  274. cognite/neat/v0/session/_collector.py +131 -0
  275. cognite/neat/v0/session/_diff.py +51 -0
  276. cognite/neat/v0/session/_drop.py +103 -0
  277. cognite/neat/v0/session/_experimental.py +26 -0
  278. cognite/neat/v0/session/_explore.py +39 -0
  279. cognite/neat/v0/session/_fix.py +28 -0
  280. cognite/neat/v0/session/_inspect.py +285 -0
  281. cognite/neat/v0/session/_mapping.py +71 -0
  282. cognite/neat/v0/session/_plugin.py +66 -0
  283. cognite/neat/v0/session/_prepare.py +286 -0
  284. cognite/neat/v0/session/_read.py +923 -0
  285. cognite/neat/v0/session/_set.py +101 -0
  286. cognite/neat/v0/session/_show.py +298 -0
  287. cognite/neat/v0/session/_state/README.md +23 -0
  288. cognite/neat/v0/session/_state.py +161 -0
  289. cognite/neat/v0/session/_subset.py +88 -0
  290. cognite/neat/v0/session/_template.py +208 -0
  291. cognite/neat/v0/session/_to.py +454 -0
  292. cognite/neat/v0/session/_wizard.py +44 -0
  293. cognite/neat/v0/session/engine/__init__.py +4 -0
  294. cognite/neat/v0/session/engine/_import.py +7 -0
  295. cognite/neat/v0/session/engine/_interface.py +25 -0
  296. cognite/neat/v0/session/engine/_load.py +131 -0
  297. cognite/neat/v0/session/exceptions.py +103 -0
  298. cognite/neat/v1.py +3 -0
  299. cognite_neat-0.127.19.dist-info/METADATA +145 -0
  300. cognite_neat-0.127.19.dist-info/RECORD +318 -0
  301. {cognite_neat-0.70.1.dist-info → cognite_neat-0.127.19.dist-info}/WHEEL +1 -1
  302. cognite/neat/app/api/asgi/metrics.py +0 -4
  303. cognite/neat/app/api/configuration.py +0 -110
  304. cognite/neat/app/api/context_manager/__init__.py +0 -3
  305. cognite/neat/app/api/context_manager/manager.py +0 -16
  306. cognite/neat/app/api/data_classes/configuration.py +0 -121
  307. cognite/neat/app/api/data_classes/rest.py +0 -78
  308. cognite/neat/app/api/explorer.py +0 -64
  309. cognite/neat/app/api/routers/configuration.py +0 -24
  310. cognite/neat/app/api/routers/core.py +0 -51
  311. cognite/neat/app/api/routers/crud.py +0 -112
  312. cognite/neat/app/api/routers/data_exploration.py +0 -334
  313. cognite/neat/app/api/routers/metrics.py +0 -10
  314. cognite/neat/app/api/routers/rules.py +0 -169
  315. cognite/neat/app/api/routers/workflows.py +0 -274
  316. cognite/neat/app/api/utils/data_mapping.py +0 -17
  317. cognite/neat/app/api/utils/logging.py +0 -26
  318. cognite/neat/app/api/utils/query_templates.py +0 -92
  319. cognite/neat/app/main.py +0 -17
  320. cognite/neat/app/monitoring/metrics.py +0 -69
  321. cognite/neat/app/ui/index.html +0 -1
  322. cognite/neat/app/ui/neat-app/.gitignore +0 -23
  323. cognite/neat/app/ui/neat-app/README.md +0 -70
  324. cognite/neat/app/ui/neat-app/build/asset-manifest.json +0 -14
  325. cognite/neat/app/ui/neat-app/build/favicon.ico +0 -0
  326. cognite/neat/app/ui/neat-app/build/index.html +0 -1
  327. cognite/neat/app/ui/neat-app/build/logo192.png +0 -0
  328. cognite/neat/app/ui/neat-app/build/manifest.json +0 -25
  329. cognite/neat/app/ui/neat-app/build/robots.txt +0 -3
  330. cognite/neat/app/ui/neat-app/build/static/css/main.38a62222.css +0 -2
  331. cognite/neat/app/ui/neat-app/build/static/css/main.38a62222.css.map +0 -1
  332. cognite/neat/app/ui/neat-app/build/static/js/main.ed960141.js +0 -3
  333. cognite/neat/app/ui/neat-app/build/static/js/main.ed960141.js.LICENSE.txt +0 -97
  334. cognite/neat/app/ui/neat-app/build/static/js/main.ed960141.js.map +0 -1
  335. cognite/neat/app/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -1
  336. cognite/neat/config.py +0 -46
  337. cognite/neat/constants.py +0 -36
  338. cognite/neat/exceptions.py +0 -139
  339. cognite/neat/graph/__init__.py +0 -3
  340. cognite/neat/graph/exceptions.py +0 -91
  341. cognite/neat/graph/extractor/__init__.py +0 -6
  342. cognite/neat/graph/extractor/_base.py +0 -14
  343. cognite/neat/graph/extractor/_dexpi.py +0 -306
  344. cognite/neat/graph/extractor/_graph_capturing_sheet.py +0 -401
  345. cognite/neat/graph/extractor/_mock_graph_generator.py +0 -359
  346. cognite/neat/graph/extractors/_base.py +0 -14
  347. cognite/neat/graph/extractors/_mock_graph_generator.py +0 -359
  348. cognite/neat/graph/loader/__init__.py +0 -23
  349. cognite/neat/graph/loader/_asset_loader.py +0 -516
  350. cognite/neat/graph/loader/_base.py +0 -69
  351. cognite/neat/graph/loader/_exceptions.py +0 -87
  352. cognite/neat/graph/loader/core/labels.py +0 -58
  353. cognite/neat/graph/loader/core/models.py +0 -136
  354. cognite/neat/graph/loader/core/rdf_to_assets.py +0 -1047
  355. cognite/neat/graph/loader/core/rdf_to_relationships.py +0 -558
  356. cognite/neat/graph/loader/rdf_to_dms.py +0 -309
  357. cognite/neat/graph/loader/validator.py +0 -87
  358. cognite/neat/graph/models.py +0 -6
  359. cognite/neat/graph/stores/__init__.py +0 -13
  360. cognite/neat/graph/stores/_base.py +0 -384
  361. cognite/neat/graph/stores/_graphdb_store.py +0 -51
  362. cognite/neat/graph/stores/_memory_store.py +0 -43
  363. cognite/neat/graph/stores/_oxigraph_store.py +0 -145
  364. cognite/neat/graph/stores/_oxrdflib.py +0 -247
  365. cognite/neat/graph/stores/_rdf_to_graph.py +0 -40
  366. cognite/neat/graph/transformation/entity_matcher.py +0 -101
  367. cognite/neat/graph/transformation/query_generator/__init__.py +0 -3
  368. cognite/neat/graph/transformation/query_generator/sparql.py +0 -540
  369. cognite/neat/graph/transformation/transformer.py +0 -316
  370. cognite/neat/rules/_analysis/_base.py +0 -25
  371. cognite/neat/rules/_analysis/_information_rules.py +0 -414
  372. cognite/neat/rules/_shared.py +0 -5
  373. cognite/neat/rules/analysis.py +0 -231
  374. cognite/neat/rules/examples/Rules-Nordic44-to-TNT.xlsx +0 -0
  375. cognite/neat/rules/examples/Rules-Nordic44-to-graphql.xlsx +0 -0
  376. cognite/neat/rules/examples/__init__.py +0 -18
  377. cognite/neat/rules/examples/power-grid-containers.yaml +0 -113
  378. cognite/neat/rules/examples/power-grid-example.xlsx +0 -0
  379. cognite/neat/rules/examples/power-grid-model.yaml +0 -213
  380. cognite/neat/rules/examples/rules-template.xlsx +0 -0
  381. cognite/neat/rules/examples/sheet2cdf-transformation-rules.xlsx +0 -0
  382. cognite/neat/rules/examples/skos-rules.xlsx +0 -0
  383. cognite/neat/rules/examples/source-to-solution-mapping-rules.xlsx +0 -0
  384. cognite/neat/rules/examples/wind-energy.owl +0 -1511
  385. cognite/neat/rules/exceptions.py +0 -2972
  386. cognite/neat/rules/exporter/__init__.py +0 -20
  387. cognite/neat/rules/exporter/_base.py +0 -45
  388. cognite/neat/rules/exporter/_core/__init__.py +0 -5
  389. cognite/neat/rules/exporter/_core/rules2labels.py +0 -24
  390. cognite/neat/rules/exporter/_rules2dms.py +0 -888
  391. cognite/neat/rules/exporter/_rules2excel.py +0 -212
  392. cognite/neat/rules/exporter/_rules2graphql.py +0 -183
  393. cognite/neat/rules/exporter/_rules2ontology.py +0 -523
  394. cognite/neat/rules/exporter/_rules2pydantic_models.py +0 -748
  395. cognite/neat/rules/exporter/_rules2rules.py +0 -104
  396. cognite/neat/rules/exporter/_rules2triples.py +0 -37
  397. cognite/neat/rules/exporter/_validation.py +0 -150
  398. cognite/neat/rules/exporters/__init__.py +0 -15
  399. cognite/neat/rules/exporters/_base.py +0 -42
  400. cognite/neat/rules/exporters/_models.py +0 -58
  401. cognite/neat/rules/exporters/_rules2dms.py +0 -259
  402. cognite/neat/rules/exporters/_rules2excel.py +0 -196
  403. cognite/neat/rules/exporters/_rules2ontology.py +0 -561
  404. cognite/neat/rules/exporters/_rules2yaml.py +0 -78
  405. cognite/neat/rules/exporters/_validation.py +0 -107
  406. cognite/neat/rules/importer/__init__.py +0 -22
  407. cognite/neat/rules/importer/_base.py +0 -70
  408. cognite/neat/rules/importer/_dict2rules.py +0 -158
  409. cognite/neat/rules/importer/_dms2rules.py +0 -196
  410. cognite/neat/rules/importer/_graph2rules.py +0 -304
  411. cognite/neat/rules/importer/_json2rules.py +0 -39
  412. cognite/neat/rules/importer/_owl2rules/__init__.py +0 -3
  413. cognite/neat/rules/importer/_owl2rules/_owl2classes.py +0 -239
  414. cognite/neat/rules/importer/_owl2rules/_owl2metadata.py +0 -255
  415. cognite/neat/rules/importer/_owl2rules/_owl2properties.py +0 -217
  416. cognite/neat/rules/importer/_owl2rules/_owl2rules.py +0 -290
  417. cognite/neat/rules/importer/_spreadsheet2rules.py +0 -45
  418. cognite/neat/rules/importer/_xsd2rules.py +0 -20
  419. cognite/neat/rules/importer/_yaml2rules.py +0 -39
  420. cognite/neat/rules/importers/__init__.py +0 -16
  421. cognite/neat/rules/importers/_base.py +0 -124
  422. cognite/neat/rules/importers/_dms2rules.py +0 -191
  423. cognite/neat/rules/importers/_dtdl2rules/__init__.py +0 -3
  424. cognite/neat/rules/importers/_dtdl2rules/_unit_lookup.py +0 -224
  425. cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py +0 -318
  426. cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py +0 -164
  427. cognite/neat/rules/importers/_dtdl2rules/spec.py +0 -359
  428. cognite/neat/rules/importers/_owl2rules/__init__.py +0 -3
  429. cognite/neat/rules/importers/_owl2rules/_owl2classes.py +0 -219
  430. cognite/neat/rules/importers/_owl2rules/_owl2metadata.py +0 -217
  431. cognite/neat/rules/importers/_owl2rules/_owl2properties.py +0 -203
  432. cognite/neat/rules/importers/_owl2rules/_owl2rules.py +0 -148
  433. cognite/neat/rules/importers/_spreadsheet2rules.py +0 -266
  434. cognite/neat/rules/importers/_yaml2rules.py +0 -110
  435. cognite/neat/rules/issues/__init__.py +0 -27
  436. cognite/neat/rules/issues/base.py +0 -190
  437. cognite/neat/rules/issues/dms.py +0 -331
  438. cognite/neat/rules/issues/fileread.py +0 -156
  439. cognite/neat/rules/issues/importing.py +0 -220
  440. cognite/neat/rules/issues/spreadsheet.py +0 -381
  441. cognite/neat/rules/issues/spreadsheet_file.py +0 -151
  442. cognite/neat/rules/models/__init__.py +0 -5
  443. cognite/neat/rules/models/_base.py +0 -151
  444. cognite/neat/rules/models/_rules/__init__.py +0 -14
  445. cognite/neat/rules/models/_rules/_types/__init__.py +0 -66
  446. cognite/neat/rules/models/_rules/_types/_base.py +0 -450
  447. cognite/neat/rules/models/_rules/_types/_field.py +0 -339
  448. cognite/neat/rules/models/_rules/_types/_value.py +0 -156
  449. cognite/neat/rules/models/_rules/base.py +0 -320
  450. cognite/neat/rules/models/_rules/dms_architect_rules.py +0 -1034
  451. cognite/neat/rules/models/_rules/dms_schema.py +0 -641
  452. cognite/neat/rules/models/_rules/domain_rules.py +0 -55
  453. cognite/neat/rules/models/_rules/information_rules.py +0 -525
  454. cognite/neat/rules/models/raw_rules.py +0 -304
  455. cognite/neat/rules/models/rdfpath.py +0 -238
  456. cognite/neat/rules/models/rules.py +0 -1269
  457. cognite/neat/rules/models/tables.py +0 -9
  458. cognite/neat/rules/models/value_types.py +0 -117
  459. cognite/neat/utils/__init__.py +0 -3
  460. cognite/neat/utils/auxiliary.py +0 -11
  461. cognite/neat/utils/cdf.py +0 -24
  462. cognite/neat/utils/cdf_loaders/__init__.py +0 -25
  463. cognite/neat/utils/cdf_loaders/_base.py +0 -62
  464. cognite/neat/utils/cdf_loaders/_data_modeling.py +0 -275
  465. cognite/neat/utils/cdf_loaders/_ingestion.py +0 -152
  466. cognite/neat/utils/cdf_loaders/data_classes.py +0 -121
  467. cognite/neat/utils/exceptions.py +0 -41
  468. cognite/neat/utils/spreadsheet.py +0 -84
  469. cognite/neat/utils/text.py +0 -104
  470. cognite/neat/utils/utils.py +0 -354
  471. cognite/neat/utils/xml.py +0 -37
  472. cognite/neat/workflows/__init__.py +0 -12
  473. cognite/neat/workflows/_exceptions.py +0 -41
  474. cognite/neat/workflows/base.py +0 -574
  475. cognite/neat/workflows/cdf_store.py +0 -393
  476. cognite/neat/workflows/examples/Export DMS/workflow.yaml +0 -89
  477. cognite/neat/workflows/examples/Export Rules to Ontology/workflow.yaml +0 -152
  478. cognite/neat/workflows/examples/Extract DEXPI Graph and Export Rules/workflow.yaml +0 -139
  479. cognite/neat/workflows/examples/Extract RDF Graph and Generate Assets/workflow.yaml +0 -270
  480. cognite/neat/workflows/examples/Import DMS/workflow.yaml +0 -65
  481. cognite/neat/workflows/examples/Ontology to Data Model/workflow.yaml +0 -116
  482. cognite/neat/workflows/examples/Validate Rules/workflow.yaml +0 -67
  483. cognite/neat/workflows/examples/Validate Solution Model/workflow.yaml +0 -64
  484. cognite/neat/workflows/examples/Visualize Data Model Using Mock Graph/workflow.yaml +0 -95
  485. cognite/neat/workflows/examples/Visualize Semantic Data Model/workflow.yaml +0 -111
  486. cognite/neat/workflows/manager.py +0 -309
  487. cognite/neat/workflows/migration/steps.py +0 -93
  488. cognite/neat/workflows/migration/wf_manifests.py +0 -33
  489. cognite/neat/workflows/model.py +0 -202
  490. cognite/neat/workflows/steps/data_contracts.py +0 -140
  491. cognite/neat/workflows/steps/lib/__init__.py +0 -7
  492. cognite/neat/workflows/steps/lib/graph_extractor.py +0 -123
  493. cognite/neat/workflows/steps/lib/graph_loader.py +0 -68
  494. cognite/neat/workflows/steps/lib/graph_store.py +0 -139
  495. cognite/neat/workflows/steps/lib/io_steps.py +0 -393
  496. cognite/neat/workflows/steps/lib/rules_exporter.py +0 -453
  497. cognite/neat/workflows/steps/lib/rules_importer.py +0 -171
  498. cognite/neat/workflows/steps/lib/rules_validator.py +0 -102
  499. cognite/neat/workflows/steps/lib/v1/__init__.py +0 -7
  500. cognite/neat/workflows/steps/lib/v1/graph_contextualization.py +0 -82
  501. cognite/neat/workflows/steps/lib/v1/graph_extractor.py +0 -644
  502. cognite/neat/workflows/steps/lib/v1/graph_loader.py +0 -606
  503. cognite/neat/workflows/steps/lib/v1/graph_store.py +0 -278
  504. cognite/neat/workflows/steps/lib/v1/graph_transformer.py +0 -58
  505. cognite/neat/workflows/steps/lib/v1/rules_exporter.py +0 -513
  506. cognite/neat/workflows/steps/lib/v1/rules_importer.py +0 -612
  507. cognite/neat/workflows/steps/step_model.py +0 -83
  508. cognite/neat/workflows/steps_registry.py +0 -212
  509. cognite/neat/workflows/tasks.py +0 -18
  510. cognite/neat/workflows/triggers.py +0 -169
  511. cognite/neat/workflows/utils.py +0 -19
  512. cognite_neat-0.70.1.dist-info/METADATA +0 -212
  513. cognite_neat-0.70.1.dist-info/RECORD +0 -234
  514. cognite_neat-0.70.1.dist-info/entry_points.txt +0 -3
  515. /cognite/neat/{app/api → _data_model}/__init__.py +0 -0
  516. /cognite/neat/{app/api/data_classes → _data_model/deployer}/__init__.py +0 -0
  517. /cognite/neat/{app/api/utils → _data_model/exporters/_table_exporter}/__init__.py +0 -0
  518. /cognite/neat/{app/monitoring → _data_model/importers/_table_importer}/__init__.py +0 -0
  519. /cognite/neat/{graph/extractors → _data_model/models}/__init__.py +0 -0
  520. /cognite/neat/{graph/loader/core → _data_model/models/conceptual}/__init__.py +0 -0
  521. /cognite/neat/{graph/transformation → _data_model/validation}/__init__.py +0 -0
  522. /cognite/neat/{rules → _session/_html}/__init__.py +0 -0
  523. /cognite/neat/{rules/_analysis → _session/_usage_analytics}/__init__.py +0 -0
  524. /cognite/neat/{workflows/migration → _utils}/__init__.py +0 -0
  525. /cognite/neat/{workflows/steps → v0}/__init__.py +0 -0
  526. /cognite/neat/{graph → v0/core/_instances}/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  527. /cognite/neat/{graph → v0/core/_instances}/examples/Knowledge-Graph-Nordic44.xml +0 -0
  528. /cognite/neat/{graph → v0/core/_instances}/examples/__init__.py +0 -0
  529. /cognite/neat/{graph → v0/core/_instances}/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  530. {cognite_neat-0.70.1.dist-info → cognite_neat-0.127.19.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,182 @@
1
+ import warnings
2
+ from dataclasses import dataclass, field
3
+ from typing import Any, Literal, cast, overload
4
+ from warnings import catch_warnings
5
+
6
+ import pandas as pd
7
+ from openpyxl import load_workbook
8
+ from openpyxl.worksheet.datavalidation import DataValidation
9
+ from openpyxl.worksheet.worksheet import Worksheet
10
+
11
+ from cognite.neat.v0.core._data_model._constants import get_internal_properties
12
+
13
+
14
+ @dataclass
15
+ class SpreadsheetRead:
16
+ """This class is used to store information about the source spreadsheet.
17
+
18
+ It is used to adjust row numbers to account for header rows and empty rows
19
+ such that the error/warning messages are accurate.
20
+ """
21
+
22
+ header_row: int = 1
23
+ empty_rows: list[int] = field(default_factory=list)
24
+ skipped_rows: list[int] = field(default_factory=list)
25
+ is_one_indexed: bool = True
26
+
27
+ def __post_init__(self) -> None:
28
+ self.empty_rows = sorted(self.empty_rows)
29
+
30
+ def adjusted_row_number(self, row_no: int) -> int:
31
+ output = row_no
32
+ for empty_row in self.empty_rows:
33
+ if empty_row <= output:
34
+ output += 1
35
+ else:
36
+ break
37
+
38
+ for skipped_rows in self.skipped_rows:
39
+ if skipped_rows <= output:
40
+ output += 1
41
+ else:
42
+ break
43
+
44
+ return output + self.header_row + (1 if self.is_one_indexed else 0)
45
+
46
+
47
+ @overload
48
+ def read_individual_sheet(
49
+ excel_file: pd.ExcelFile,
50
+ sheet_name: str,
51
+ return_read_info: Literal[True],
52
+ expected_headers: list[str] | None = None,
53
+ ) -> tuple[list[dict], SpreadsheetRead]: ...
54
+
55
+
56
+ @overload
57
+ def read_individual_sheet(
58
+ excel_file: pd.ExcelFile,
59
+ sheet_name: str,
60
+ return_read_info: Literal[False] = False,
61
+ expected_headers: list[str] | None = None,
62
+ ) -> list[dict]: ...
63
+
64
+
65
+ def read_individual_sheet(
66
+ excel_file: pd.ExcelFile,
67
+ sheet_name: str,
68
+ return_read_info: bool = False,
69
+ expected_headers: list[str] | None = None,
70
+ ) -> tuple[list[dict], SpreadsheetRead] | list[dict]:
71
+ if expected_headers:
72
+ with catch_warnings():
73
+ # When reading spreadsheets produced by neat, they contain dropdowns. These
74
+ # are not supported by openpyxl and will raise a warning as openpyxl cannot validate these.
75
+ # We ignore these warnings as Neat will do the same checks.
76
+ warnings.simplefilter("ignore")
77
+ target_row = _get_row_number(cast(Worksheet, load_workbook(excel_file)[sheet_name]), expected_headers)
78
+ skiprows = target_row - 1 if target_row is not None else 0
79
+ else:
80
+ skiprows = 0
81
+
82
+ with catch_warnings():
83
+ # When reading spreadsheets produced by neat, they contain dropdowns. These
84
+ # are not supported by openpyxl and will raise a warning as openpyxl cannot validate these.
85
+ # We ignore these warnings as Neat will do the same checks.
86
+ warnings.simplefilter("ignore")
87
+ raw = pd.read_excel(excel_file, sheet_name, skiprows=skiprows)
88
+ is_na = raw.isnull().all(axis=1)
89
+ skip_rows = _find_rows_to_skip(raw)
90
+ empty_rows = is_na[is_na].index.tolist()
91
+
92
+ if skip_rows:
93
+ raw = raw.drop(skip_rows)
94
+
95
+ raw.dropna(axis=0, how="all", inplace=True)
96
+
97
+ if "Value Type" in raw.columns:
98
+ # Special handling for Value Type column, #N/A is treated specially by NEAT it means Unknown
99
+ raw["Value Type"] = raw["Value Type"].replace(float("nan"), "#N/A")
100
+
101
+ if "Concept" in raw.columns:
102
+ # Special handling for Concept column, #N/A is treated specially by NEAT it means Unknown
103
+ raw["Concept"] = raw["Concept"].replace(float("nan"), "#N/A")
104
+
105
+ output = raw.replace(float("nan"), None).to_dict(orient="records")
106
+ if return_read_info:
107
+ # If no rows are skipped, row 1 is the header row.
108
+ return output, SpreadsheetRead(
109
+ header_row=skiprows + 1,
110
+ empty_rows=empty_rows,
111
+ is_one_indexed=True,
112
+ skipped_rows=skip_rows,
113
+ )
114
+ return output
115
+
116
+
117
+ def _find_rows_to_skip(
118
+ df: pd.DataFrame,
119
+ ) -> list:
120
+ """Find rows which are having all values as None except for internal properties."""
121
+ rows_to_skip = []
122
+
123
+ internal_cols = {val.lower() for val in get_internal_properties()}
124
+ for i, row in df.iterrows():
125
+ user_cols_state = []
126
+ internal_cols_state = []
127
+ for col in df.columns:
128
+ if col.lower() not in internal_cols:
129
+ user_cols_state.append(row[col] == "#N/A" or row[col].__str__().lower() in ["none", "nan"])
130
+ else:
131
+ internal_cols_state.append(row[col] is not None)
132
+
133
+ if all(user_cols_state) and any(internal_cols_state):
134
+ rows_to_skip.append(i)
135
+
136
+ return rows_to_skip
137
+
138
+
139
+ def _get_row_number(sheet: Worksheet, values_to_find: list[str]) -> int | None:
140
+ for row_number, row in enumerate(sheet.iter_rows(values_only=True), start=1):
141
+ if any(value in row for value in values_to_find):
142
+ return row_number
143
+ return None
144
+
145
+
146
+ @overload
147
+ def find_column_and_row_with_value(
148
+ sheet: Worksheet, value: Any, column_letter: Literal[True] = True
149
+ ) -> tuple[str, int] | tuple[None, None]: ...
150
+
151
+
152
+ @overload
153
+ def find_column_and_row_with_value(
154
+ sheet: Worksheet, value: Any, column_letter: Literal[False]
155
+ ) -> tuple[int, int] | tuple[None, None]: ...
156
+
157
+
158
+ def find_column_and_row_with_value(
159
+ sheet: Worksheet, value: Any, column_letter: bool = True
160
+ ) -> tuple[int, int] | tuple[str, int] | tuple[None, None]:
161
+ for row in sheet.iter_rows():
162
+ for cell in row:
163
+ if cell.value and isinstance(cell.value, str) and cell.value.lower() == value.lower():
164
+ return (cell.column_letter, cell.row) if column_letter else (cell.column, cell.row)
165
+
166
+ return None, None
167
+
168
+
169
+ def generate_data_validation(sheet: str, column: str, total_header_rows: int, validation_range: int) -> DataValidation:
170
+ """Creates openpyxl data validation object for a cell in a sheet
171
+
172
+ Args:
173
+ sheet: The name of the sheet where the data validation is applied.
174
+ column: The column letter where the data validation is applied.
175
+ total_header_rows: The number of header rows in the sheet.
176
+ validation_range: The total number of validation values in the column.
177
+ """
178
+
179
+ return DataValidation(
180
+ type="list",
181
+ formula1=f"={sheet}!{column}${total_header_rows + 1}:{column}${validation_range + total_header_rows + 1}",
182
+ )
@@ -0,0 +1,44 @@
1
+ from typing import TypeVar
2
+
3
+ T = TypeVar("T")
4
+
5
+
6
+ def tarjan(dependencies_by_id: dict[T, set[T]]) -> list[set[T]]:
7
+ """Returns the strongly connected components of the dependency graph
8
+ in topological order.
9
+ Args:
10
+ dependencies_by_id: A dictionary where the keys are ids and the values are sets of ids that the key depends on.
11
+ Returns:
12
+ A list of sets of ids that are strongly connected components in the dependency graph.
13
+ """
14
+
15
+ stack = []
16
+ stack_set = set()
17
+ index: dict[T, int] = {}
18
+ lowlink = {}
19
+ result = []
20
+
21
+ def visit(v: T) -> None:
22
+ index[v] = len(index)
23
+ lowlink[v] = index[v]
24
+ stack.append(v)
25
+ stack_set.add(v)
26
+ for w in dependencies_by_id.get(v, []):
27
+ if w not in index:
28
+ visit(w)
29
+ lowlink[v] = min(lowlink[w], lowlink[v])
30
+ elif w in stack_set:
31
+ lowlink[v] = min(lowlink[v], index[w])
32
+ if lowlink[v] == index[v]:
33
+ scc = set()
34
+ dependency: T | None = None
35
+ while v != dependency:
36
+ dependency = stack.pop()
37
+ scc.add(dependency)
38
+ stack_set.remove(dependency)
39
+ result.append(scc)
40
+
41
+ for view_id in dependencies_by_id.keys():
42
+ if view_id not in index:
43
+ visit(view_id)
44
+ return result
@@ -0,0 +1,277 @@
1
+ import re
2
+ import urllib.parse
3
+ from collections.abc import Collection, Set
4
+ from re import Pattern
5
+ from typing import Any
6
+
7
+ from cognite.neat.v0.core._data_model._constants import get_reserved_words
8
+
9
+ PREPOSITIONS = frozenset(
10
+ {
11
+ "in",
12
+ "on",
13
+ "at",
14
+ "by",
15
+ "for",
16
+ "with",
17
+ "about",
18
+ "against",
19
+ "between",
20
+ "into",
21
+ "through",
22
+ "during",
23
+ "before",
24
+ "after",
25
+ "above",
26
+ "below",
27
+ "to",
28
+ "from",
29
+ "up",
30
+ "down",
31
+ "out",
32
+ "off",
33
+ "over",
34
+ "under",
35
+ "again",
36
+ "further",
37
+ "then",
38
+ "once",
39
+ }
40
+ )
41
+
42
+
43
+ def to_camel_case(string: str) -> str:
44
+ """Convert snake_case_name to camelCaseName.
45
+
46
+ Args:
47
+ string: The string to convert.
48
+ Returns:
49
+ camelCase of the input string.
50
+
51
+ Examples:
52
+ >>> to_camel_case("a_b")
53
+ 'aB'
54
+ >>> to_camel_case("ScenarioInstance_priceForecast")
55
+ 'scenarioInstancePriceForecast'
56
+ """
57
+ string = re.sub(r"[^a-zA-Z0-9_]", "_", string)
58
+ string = re.sub("_+", "_", string)
59
+ is_all_upper = string.upper() == string
60
+ is_first_upper = (
61
+ len(string) >= 2 and string[:2].upper() == string[:2] and "_" not in string[:2] and not is_all_upper
62
+ )
63
+ return _to_camel_case(string, is_all_upper, is_first_upper)
64
+
65
+
66
+ def _to_camel_case(string: str, is_all_upper: bool, is_first_upper: bool) -> str:
67
+ if "_" in string:
68
+ pascal_splits = [
69
+ _to_pascal_case(part, is_all_upper, is_first_upper and no == 0)
70
+ for no, part in enumerate(string.split("_"), 0)
71
+ ]
72
+ else:
73
+ # Ensure pascal
74
+ if string:
75
+ string = string[0].upper() + string[1:]
76
+ pascal_splits = [string]
77
+ cleaned: list[str] = []
78
+ for part in pascal_splits:
79
+ if part.upper() == part and is_all_upper:
80
+ cleaned.append(part.capitalize())
81
+ else:
82
+ cleaned.append(part)
83
+
84
+ string_split = []
85
+ for part in cleaned:
86
+ string_split.extend(re.findall(r"[A-Z][a-z0-9]*", part))
87
+ if not string_split:
88
+ string_split = [string]
89
+ if len(string_split) == 0:
90
+ return ""
91
+ # The first word is a single letter, keep the original case
92
+ if is_first_upper:
93
+ return "".join(word for word in string_split)
94
+ else:
95
+ return string_split[0].casefold() + "".join(word for word in string_split[1:])
96
+
97
+
98
+ def to_pascal_case(string: str) -> str:
99
+ """Convert string to PascalCaseName.
100
+
101
+ Args:
102
+ string: The string to convert.
103
+ Returns:
104
+ PascalCase of the input string.
105
+
106
+ Examples:
107
+ >>> to_pascal_case("a_b")
108
+ 'AB'
109
+ >>> to_pascal_case('camel_case')
110
+ 'CamelCase'
111
+ """
112
+ return _to_pascal_case(string, string == string.upper(), True)
113
+
114
+
115
+ def _to_pascal_case(string: str, is_all_upper: bool, is_first_upper: bool) -> str:
116
+ camel = _to_camel_case(string, is_all_upper, is_first_upper)
117
+ return f"{camel[0].upper()}{camel[1:]}" if camel else ""
118
+
119
+
120
+ def to_snake_case(string: str) -> str:
121
+ """
122
+ Convert input string to snake_case
123
+
124
+ Args:
125
+ string: The string to convert.
126
+ Returns:
127
+ snake_case of the input string.
128
+
129
+ Examples:
130
+ >>> to_snake_case("aB")
131
+ 'a_b'
132
+ >>> to_snake_case('CamelCase')
133
+ 'camel_case'
134
+ >>> to_snake_case('camelCamelCase')
135
+ 'camel_camel_case'
136
+ >>> to_snake_case('Camel2Camel2Case')
137
+ 'camel_2_camel_2_case'
138
+ >>> to_snake_case('getHTTPResponseCode')
139
+ 'get_http_response_code'
140
+ >>> to_snake_case('get200HTTPResponseCode')
141
+ 'get_200_http_response_code'
142
+ >>> to_snake_case('getHTTP200ResponseCode')
143
+ 'get_http_200_response_code'
144
+ >>> to_snake_case('HTTPResponseCode')
145
+ 'http_response_code'
146
+ >>> to_snake_case('ResponseHTTP')
147
+ 'response_http'
148
+ >>> to_snake_case('ResponseHTTP2')
149
+ 'response_http_2'
150
+ >>> to_snake_case('Fun?!awesome')
151
+ 'fun_awesome'
152
+ >>> to_snake_case('Fun?!Awesome')
153
+ 'fun_awesome'
154
+ >>> to_snake_case('10CoolDudes')
155
+ '10_cool_dudes'
156
+ >>> to_snake_case('20coolDudes')
157
+ '20_cool_dudes'
158
+ """
159
+ pattern = re.compile(r"[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\d|\W|$)|\d+")
160
+ if "_" in string:
161
+ words = [word for section in string.split("_") for word in pattern.findall(section)]
162
+ else:
163
+ words = pattern.findall(string)
164
+ return "_".join(map(str.lower, words))
165
+
166
+
167
+ def to_words(string: str) -> str:
168
+ """Converts snake_case camelCase or PascalCase to words."""
169
+ return to_snake_case(string).replace("_", " ")
170
+
171
+
172
+ def title(text: str, skip_words: Set[str] = PREPOSITIONS) -> str:
173
+ """Converts text to title case, skipping prepositions."""
174
+ words = (word.lower() for word in text.split())
175
+ titled_words = (word.capitalize() if word not in skip_words else word for word in words)
176
+ return " ".join(titled_words)
177
+
178
+
179
+ def sentence_or_string_to_camel(string: str) -> str:
180
+ # Could be a combination of kebab and pascal/camel case
181
+ if " " in string:
182
+ parts = string.split(" ")
183
+ try:
184
+ return parts[0].casefold() + "".join(word.capitalize() for word in parts[1:])
185
+ except IndexError:
186
+ return ""
187
+ else:
188
+ return to_camel_case(string)
189
+
190
+
191
+ def replace_non_alphanumeric_with_underscore(text: str) -> str:
192
+ return re.sub(r"\W+", "_", text)
193
+
194
+
195
+ def humanize_collection(collection: Collection[Any], /, *, sort: bool = True, bind_word: str = "and") -> str:
196
+ """Convert a collection of items to a human-readable string.
197
+
198
+ Args:
199
+ collection: The collection of items to convert.
200
+ sort: Whether to sort the collection before converting. Default is True.
201
+ bind_word: The word to use to bind the last two items. Default is "and".
202
+
203
+ Returns:
204
+ A human-readable string of the collection.
205
+
206
+ Examples:
207
+ >>> humanize_collection(["b", "c", "a"])
208
+ 'a, b and c'
209
+ >>> humanize_collection(["b", "c", "a"], sort=False)
210
+ 'b, c and a'
211
+ >>> humanize_collection(["a", "b"])
212
+ 'a and b'
213
+ >>> humanize_collection(["a"])
214
+ 'a'
215
+ >>> humanize_collection([])
216
+
217
+ """
218
+ if not collection:
219
+ return ""
220
+ elif len(collection) == 1:
221
+ return str(next(iter(collection)))
222
+
223
+ strings = (str(item) for item in collection)
224
+ if sort:
225
+ sequence = sorted(strings)
226
+ else:
227
+ sequence = list(strings)
228
+
229
+ return f"{', '.join(sequence[:-1])} {bind_word} {sequence[-1]}"
230
+
231
+
232
+ class NamingStandardization:
233
+ _letter_number_underscore = re.compile(r"[^a-zA-Z0-9_]+")
234
+ _letter_number_underscore_hyphen = re.compile(r"[^a-zA-Z0-9_-]+")
235
+ _multi_underscore_pattern = re.compile(r"_+")
236
+ _start_letter_pattern = re.compile(r"^[a-zA-Z]")
237
+
238
+ @classmethod
239
+ def standardize_concept_str(cls, raw: str) -> str:
240
+ clean = cls._clean_string(raw)
241
+ if not cls._start_letter_pattern.match(clean):
242
+ # Underscore ensure that 'Class' it treated as a separate word
243
+ # in the to_pascale function
244
+ clean = f"Class_{clean}"
245
+ return to_pascal_case(clean)
246
+
247
+ @classmethod
248
+ def standardize_property_str(cls, raw: str) -> str:
249
+ clean = cls._clean_string(raw)
250
+ if not cls._start_letter_pattern.match(clean):
251
+ # Underscore ensure that 'property' it treated as a separate word
252
+ # in the to_camel function
253
+ clean = f"property_{clean}"
254
+ return to_camel_case(clean)
255
+
256
+ @classmethod
257
+ def standardize_space_str(cls, raw: str) -> str:
258
+ clean = cls._clean_string(raw, cls._letter_number_underscore_hyphen)
259
+ if not cls._start_letter_pattern.match(clean):
260
+ clean = f"sp_{clean}"
261
+ if clean in set(get_reserved_words("space")):
262
+ clean = f"my_{clean}"
263
+ if len(clean) > 43:
264
+ clean = clean[:43]
265
+ if not (clean[-1].isalnum()) and len(clean) == 43:
266
+ clean = f"{clean[:-1]}x"
267
+ elif not clean[-1].isalnum():
268
+ clean = f"{clean}x"
269
+ if not clean:
270
+ raise ValueError("Space name must contain at least one letter.")
271
+ return to_snake_case(clean)
272
+
273
+ @classmethod
274
+ def _clean_string(cls, raw: str, clean_pattern: Pattern[str] = _letter_number_underscore) -> str:
275
+ raw = urllib.parse.unquote(raw)
276
+ raw = clean_pattern.sub("_", raw)
277
+ return cls._multi_underscore_pattern.sub("_", raw)
@@ -0,0 +1,17 @@
1
+ import sys
2
+ from datetime import datetime
3
+
4
+ if sys.version_info >= (3, 11):
5
+ from datetime import UTC
6
+ else:
7
+ from datetime import timezone
8
+
9
+ UTC = timezone.utc
10
+
11
+
12
+ def epoch_now_ms() -> int:
13
+ return int((datetime.now(UTC) - datetime(1970, 1, 1, tzinfo=UTC)).total_seconds() * 1000)
14
+
15
+
16
+ def datetime_utc_now() -> datetime:
17
+ return datetime.now(UTC)
@@ -0,0 +1,134 @@
1
+ from abc import ABC
2
+ from dataclasses import dataclass, field
3
+ from functools import total_ordering
4
+ from typing import Any, Generic
5
+
6
+ from cognite.neat.v0.core._issues import IssueList
7
+ from cognite.neat.v0.core._issues.errors import NeatValueError
8
+ from cognite.neat.v0.core._shared import T_ID, NeatList, NeatObject
9
+
10
+
11
+ @total_ordering
12
+ @dataclass
13
+ class UploadResultCore(NeatObject, ABC):
14
+ name: str
15
+ error_messages: list[str] = field(default_factory=list)
16
+ issues: IssueList = field(default_factory=IssueList)
17
+
18
+ def __lt__(self, other: object) -> bool:
19
+ if isinstance(other, UploadResultCore):
20
+ return self.name < other.name
21
+ else:
22
+ return NotImplemented
23
+
24
+ def __eq__(self, other: object) -> bool:
25
+ if isinstance(other, UploadResultCore):
26
+ return self.name == other.name
27
+ else:
28
+ return NotImplemented
29
+
30
+ def dump(self, aggregate: bool = True) -> dict[str, Any]:
31
+ output: dict[str, Any] = {"name": self.name}
32
+ if self.error_messages:
33
+ output["error_messages"] = len(self.error_messages) if aggregate else self.error_messages
34
+ if self.issues:
35
+ output["issues"] = len(self.issues) if aggregate else [issue.dump() for issue in self.issues]
36
+ return output
37
+
38
+
39
+ class UploadResultList(NeatList[UploadResultCore]):
40
+ def _repr_html_(self) -> str:
41
+ df = self.to_pandas().fillna(0)
42
+ df = df.style.format({column: "{:,.0f}".format for column in df.select_dtypes(include="number").columns})
43
+ return df._repr_html_() # type: ignore[attr-defined]
44
+
45
+
46
+ @dataclass
47
+ class UploadResult(UploadResultCore, Generic[T_ID]):
48
+ created: set[T_ID] = field(default_factory=set)
49
+ upserted: set[T_ID] = field(default_factory=set)
50
+ deleted: set[T_ID] = field(default_factory=set)
51
+ changed: set[T_ID] = field(default_factory=set)
52
+ unchanged: set[T_ID] = field(default_factory=set)
53
+ skipped: set[T_ID] = field(default_factory=set)
54
+ failed_created: set[T_ID] = field(default_factory=set)
55
+ failed_upserted: set[T_ID] = field(default_factory=set)
56
+ failed_changed: set[T_ID] = field(default_factory=set)
57
+ failed_deleted: set[T_ID] = field(default_factory=set)
58
+ failed_items: list = field(default_factory=list)
59
+
60
+ @property
61
+ def failed(self) -> int:
62
+ return (
63
+ len(self.failed_created) + len(self.failed_changed) + len(self.failed_deleted) + len(self.failed_upserted)
64
+ )
65
+
66
+ @property
67
+ def success(self) -> int:
68
+ return (
69
+ len(self.created)
70
+ + len(self.deleted)
71
+ + len(self.changed)
72
+ + len(self.upserted)
73
+ + len(self.unchanged)
74
+ + len(self.skipped)
75
+ )
76
+
77
+ def dump(self, aggregate: bool = True) -> dict[str, Any]:
78
+ output = super().dump(aggregate)
79
+ if self.created:
80
+ output["created"] = len(self.created) if aggregate else list(self.created)
81
+ if self.upserted:
82
+ output["upserted"] = len(self.upserted) if aggregate else list(self.upserted)
83
+ if self.deleted:
84
+ output["deleted"] = len(self.deleted) if aggregate else list(self.deleted)
85
+ if self.changed:
86
+ output["changed"] = len(self.changed) if aggregate else list(self.changed)
87
+ if self.unchanged:
88
+ output["unchanged"] = len(self.unchanged) if aggregate else list(self.unchanged)
89
+ if self.skipped:
90
+ output["skipped"] = len(self.skipped) if aggregate else list(self.skipped)
91
+ if self.failed_created:
92
+ output["failed_created"] = len(self.failed_created) if aggregate else list(self.failed_created)
93
+ if self.failed_upserted:
94
+ output["failed_upserted"] = len(self.failed_upserted) if aggregate else list(self.failed_upserted)
95
+ if self.failed_changed:
96
+ output["failed_changed"] = len(self.failed_changed) if aggregate else list(self.failed_changed)
97
+ if self.failed_deleted:
98
+ output["failed_deleted"] = len(self.failed_deleted) if aggregate else list(self.failed_deleted)
99
+ if "error_messages" in output:
100
+ # Trick to move error_messages to the end of the dict
101
+ output["error_messages"] = output.pop("error_messages")
102
+ if "issues" in output:
103
+ # Trick to move issues to the end of the dict
104
+ output["issues"] = output.pop("issues")
105
+ return output
106
+
107
+ def __str__(self) -> str:
108
+ dumped = self.dump(aggregate=True)
109
+ lines: list[str] = []
110
+ for key, value in dumped.items():
111
+ if key in ["name", "error_messages", "issues"]:
112
+ continue
113
+ lines.append(f"{key}: {value}")
114
+ return f"{self.name.title()}: {', '.join(lines)}"
115
+
116
+ def merge(self, other: "UploadResult[T_ID]") -> "UploadResult[T_ID]":
117
+ if self.name != other.name:
118
+ raise NeatValueError(f"Cannot merge UploadResults with different names: {self.name} and {other.name}")
119
+ return UploadResult(
120
+ name=self.name,
121
+ error_messages=self.error_messages + other.error_messages,
122
+ issues=IssueList(self.issues + other.issues),
123
+ created=self.created.union(other.created),
124
+ upserted=self.upserted.union(other.upserted),
125
+ deleted=self.deleted.union(other.deleted),
126
+ changed=self.changed.union(other.changed),
127
+ unchanged=self.unchanged.union(other.unchanged),
128
+ skipped=self.skipped.union(other.skipped),
129
+ failed_created=self.failed_created.union(other.failed_created),
130
+ failed_upserted=self.failed_upserted.union(other.failed_upserted),
131
+ failed_changed=self.failed_changed.union(other.failed_changed),
132
+ failed_deleted=self.failed_deleted.union(other.failed_deleted),
133
+ failed_items=self.failed_items + other.failed_items,
134
+ )