cognite-neat 0.99.0__tar.gz → 0.100.0__tar.gz

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 (288) hide show
  1. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/PKG-INFO +1 -1
  2. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_client/_api/data_modeling_loaders.py +390 -116
  3. cognite_neat-0.100.0/cognite/neat/_client/_api/schema.py +111 -0
  4. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_client/data_classes/data_modeling.py +4 -0
  5. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_client/data_classes/schema.py +2 -348
  6. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_constants.py +27 -4
  7. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_base.py +7 -0
  8. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_classic.py +28 -18
  9. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/loaders/_rdf2dms.py +52 -13
  10. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/transformers/__init__.py +3 -3
  11. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/transformers/_classic_cdf.py +135 -56
  12. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/_base.py +26 -17
  13. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/errors/__init__.py +4 -2
  14. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/errors/_external.py +7 -0
  15. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/errors/_properties.py +2 -7
  16. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/errors/_resources.py +1 -1
  17. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/warnings/__init__.py +6 -2
  18. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/warnings/_external.py +9 -1
  19. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/warnings/_resources.py +41 -2
  20. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/warnings/user_modeling.py +4 -4
  21. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/_constants.py +2 -6
  22. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/analysis/_base.py +15 -5
  23. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/analysis/_dms.py +20 -0
  24. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/analysis/_information.py +22 -0
  25. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/exporters/_base.py +3 -5
  26. cognite_neat-0.100.0/cognite/neat/_rules/exporters/_rules2dms.py +352 -0
  27. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/__init__.py +1 -3
  28. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_base.py +1 -1
  29. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_dms2rules.py +3 -25
  30. cognite_neat-0.100.0/cognite/neat/_rules/importers/_rdf/__init__.py +5 -0
  31. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_rdf/_base.py +34 -11
  32. cognite_neat-0.100.0/cognite/neat/_rules/importers/_rdf/_imf2rules.py +91 -0
  33. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_rdf/_inference2rules.py +40 -7
  34. cognite_neat-0.100.0/cognite/neat/_rules/importers/_rdf/_owl2rules.py +80 -0
  35. cognite_neat-0.100.0/cognite/neat/_rules/importers/_rdf/_shared.py +168 -0
  36. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/_base_rules.py +19 -0
  37. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/_types.py +5 -0
  38. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/dms/__init__.py +2 -0
  39. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/dms/_exporter.py +247 -123
  40. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/dms/_rules.py +7 -49
  41. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/dms/_rules_input.py +8 -3
  42. cognite_neat-0.100.0/cognite/neat/_rules/models/dms/_validation.py +584 -0
  43. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/entities/_multi_value.py +3 -0
  44. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/information/__init__.py +2 -0
  45. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/information/_rules.py +17 -61
  46. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/information/_rules_input.py +11 -2
  47. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/information/_validation.py +107 -11
  48. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/mapping/_classic2core.py +1 -1
  49. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/mapping/_classic2core.yaml +8 -4
  50. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/transformers/__init__.py +2 -1
  51. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/transformers/_converters.py +163 -61
  52. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/transformers/_mapping.py +132 -2
  53. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/transformers/_pipelines.py +1 -1
  54. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/transformers/_verification.py +29 -4
  55. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_base.py +46 -60
  56. cognite_neat-0.100.0/cognite/neat/_session/_mapping.py +139 -0
  57. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_prepare.py +49 -14
  58. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_read.py +50 -4
  59. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_set.py +1 -0
  60. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_to.py +38 -12
  61. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_wizard.py +5 -0
  62. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/engine/_interface.py +3 -2
  63. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/exceptions.py +4 -0
  64. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_store/_base.py +79 -19
  65. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/collection_.py +22 -0
  66. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/rdf_.py +30 -4
  67. cognite_neat-0.100.0/cognite/neat/_version.py +2 -0
  68. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/lib/current/rules_exporter.py +3 -91
  69. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/lib/current/rules_importer.py +2 -16
  70. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/lib/current/rules_validator.py +3 -5
  71. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/pyproject.toml +1 -1
  72. cognite_neat-0.99.0/cognite/neat/_client/_api/schema.py +0 -50
  73. cognite_neat-0.99.0/cognite/neat/_rules/exporters/_rules2dms.py +0 -362
  74. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_imf2rules/__init__.py +0 -3
  75. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2classes.py +0 -86
  76. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2metadata.py +0 -29
  77. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2properties.py +0 -130
  78. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_imf2rules/_imf2rules.py +0 -154
  79. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_owl2rules/__init__.py +0 -3
  80. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2classes.py +0 -58
  81. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2metadata.py +0 -65
  82. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2properties.py +0 -59
  83. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2rules.py +0 -39
  84. cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf/_shared.py +0 -471
  85. cognite_neat-0.99.0/cognite/neat/_rules/models/dms/_validation.py +0 -286
  86. cognite_neat-0.99.0/cognite/neat/_session/_mapping.py +0 -39
  87. cognite_neat-0.99.0/cognite/neat/_version.py +0 -2
  88. cognite_neat-0.99.0/cognite/neat/_workflows/steps/lib/__init__.py +0 -0
  89. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/LICENSE +0 -0
  90. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/README.md +0 -0
  91. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/__init__.py +0 -0
  92. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/__init__.py +0 -0
  93. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/asgi/metrics.py +0 -0
  94. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/configuration.py +0 -0
  95. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/context_manager/__init__.py +0 -0
  96. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/context_manager/manager.py +0 -0
  97. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/data_classes/__init__.py +0 -0
  98. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/data_classes/rest.py +0 -0
  99. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/explorer.py +0 -0
  100. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/routers/configuration.py +0 -0
  101. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/routers/crud.py +0 -0
  102. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/routers/metrics.py +0 -0
  103. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/routers/workflows.py +0 -0
  104. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/utils/__init__.py +0 -0
  105. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/utils/data_mapping.py +0 -0
  106. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/utils/logging.py +0 -0
  107. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/api/utils/query_templates.py +0 -0
  108. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/main.py +0 -0
  109. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/monitoring/__init__.py +0 -0
  110. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/monitoring/metrics.py +0 -0
  111. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/index.html +0 -0
  112. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/.gitignore +0 -0
  113. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/README.md +0 -0
  114. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/asset-manifest.json +0 -0
  115. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/favicon.ico +0 -0
  116. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/img/architect-icon.svg +0 -0
  117. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/img/developer-icon.svg +0 -0
  118. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/img/sme-icon.svg +0 -0
  119. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/index.html +0 -0
  120. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/logo192.png +0 -0
  121. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/manifest.json +0 -0
  122. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/robots.txt +0 -0
  123. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/static/css/main.72e3d92e.css +0 -0
  124. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/static/css/main.72e3d92e.css.map +0 -0
  125. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js +0 -0
  126. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js.LICENSE.txt +0 -0
  127. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js.map +0 -0
  128. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -0
  129. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/package-lock.json +0 -0
  130. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/package.json +0 -0
  131. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/public/favicon.ico +0 -0
  132. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/public/img/architect-icon.svg +0 -0
  133. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/public/img/developer-icon.svg +0 -0
  134. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/public/img/sme-icon.svg +0 -0
  135. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/public/index.html +0 -0
  136. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/public/logo192.png +0 -0
  137. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/public/manifest.json +0 -0
  138. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/public/robots.txt +0 -0
  139. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/App.css +0 -0
  140. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/App.js +0 -0
  141. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/App.test.js +0 -0
  142. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/MainContainer.tsx +0 -0
  143. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/JsonViewer.tsx +0 -0
  144. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/LocalUploader.tsx +0 -0
  145. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/OverviewComponentEditorDialog.tsx +0 -0
  146. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/StepEditorDialog.tsx +0 -0
  147. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/TabPanel.tsx +0 -0
  148. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/Utils.tsx +0 -0
  149. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/WorkflowDeleteDialog.tsx +0 -0
  150. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/WorkflowExecutionReport.tsx +0 -0
  151. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/WorkflowImportExportDialog.tsx +0 -0
  152. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/components/WorkflowMetadataDialog.tsx +0 -0
  153. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/index.css +0 -0
  154. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/index.js +0 -0
  155. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/logo.svg +0 -0
  156. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/reportWebVitals.js +0 -0
  157. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/setupTests.js +0 -0
  158. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/types/WorkflowTypes.ts +0 -0
  159. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/views/AboutView.tsx +0 -0
  160. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/views/ConfigView.tsx +0 -0
  161. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/views/GlobalConfigView.tsx +0 -0
  162. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/src/views/WorkflowView.tsx +0 -0
  163. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_app/ui/neat-app/tsconfig.json +0 -0
  164. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_client/__init__.py +0 -0
  165. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_client/_api/__init__.py +0 -0
  166. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_client/_api_client.py +0 -0
  167. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_client/data_classes/__init__.py +0 -0
  168. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_config.py +0 -0
  169. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/__init__.py +0 -0
  170. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/_shared.py +0 -0
  171. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/_tracking/__init__.py +0 -0
  172. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/_tracking/base.py +0 -0
  173. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/_tracking/log.py +0 -0
  174. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  175. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44.xml +0 -0
  176. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/examples/__init__.py +0 -0
  177. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  178. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/__init__.py +0 -0
  179. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/__init__.py +0 -0
  180. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_assets.py +0 -0
  181. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_base.py +0 -0
  182. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_data_sets.py +0 -0
  183. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_events.py +0 -0
  184. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_files.py +0 -0
  185. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_labels.py +0 -0
  186. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_relationships.py +0 -0
  187. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_sequences.py +0 -0
  188. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_classic_cdf/_timeseries.py +0 -0
  189. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_dexpi.py +0 -0
  190. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_dms.py +0 -0
  191. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_iodd.py +0 -0
  192. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_mock_graph_generator.py +0 -0
  193. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/extractors/_rdf_file.py +0 -0
  194. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/loaders/__init__.py +0 -0
  195. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/loaders/_base.py +0 -0
  196. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/queries/__init__.py +0 -0
  197. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/queries/_base.py +0 -0
  198. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/queries/_construct.py +0 -0
  199. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/queries/_shared.py +0 -0
  200. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/transformers/_base.py +0 -0
  201. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/transformers/_iodd.py +0 -0
  202. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/transformers/_prune_graph.py +0 -0
  203. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/transformers/_rdfpath.py +0 -0
  204. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_graph/transformers/_value_type.py +0 -0
  205. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/__init__.py +0 -0
  206. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/errors/_general.py +0 -0
  207. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/errors/_workflow.py +0 -0
  208. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/formatters.py +0 -0
  209. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/warnings/_general.py +0 -0
  210. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/warnings/_models.py +0 -0
  211. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_issues/warnings/_properties.py +0 -0
  212. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/__init__.py +0 -0
  213. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/_shared.py +0 -0
  214. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/analysis/__init__.py +0 -0
  215. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/catalog/__init__.py +0 -0
  216. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
  217. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/exporters/__init__.py +0 -0
  218. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/exporters/_rules2excel.py +0 -0
  219. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/exporters/_rules2instance_template.py +0 -0
  220. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/exporters/_rules2ontology.py +0 -0
  221. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/exporters/_rules2yaml.py +0 -0
  222. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/exporters/_validation.py +0 -0
  223. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_dtdl2rules/__init__.py +0 -0
  224. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_dtdl2rules/_unit_lookup.py +0 -0
  225. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_converter.py +0 -0
  226. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_importer.py +0 -0
  227. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_dtdl2rules/spec.py +0 -0
  228. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_spreadsheet2rules.py +0 -0
  229. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/importers/_yaml2rules.py +0 -0
  230. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/__init__.py +0 -0
  231. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/_base_input.py +0 -0
  232. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/_rdfpath.py +0 -0
  233. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/data_types.py +0 -0
  234. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/entities/__init__.py +0 -0
  235. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/entities/_constants.py +0 -0
  236. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/entities/_loaders.py +0 -0
  237. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/entities/_single_value.py +0 -0
  238. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/entities/_types.py +0 -0
  239. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/entities/_wrapped.py +0 -0
  240. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/models/mapping/__init__.py +0 -0
  241. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_rules/transformers/_base.py +0 -0
  242. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/__init__.py +0 -0
  243. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_collector.py +0 -0
  244. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_drop.py +0 -0
  245. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_inspect.py +0 -0
  246. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_show.py +0 -0
  247. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/_state.py +0 -0
  248. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/engine/__init__.py +0 -0
  249. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/engine/_import.py +0 -0
  250. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_session/engine/_load.py +0 -0
  251. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_shared.py +0 -0
  252. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_store/__init__.py +0 -0
  253. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_store/_provenance.py +0 -0
  254. {cognite_neat-0.99.0/cognite/neat/_rules/importers/_rdf → cognite_neat-0.100.0/cognite/neat/_utils}/__init__.py +0 -0
  255. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/auth.py +0 -0
  256. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/auxiliary.py +0 -0
  257. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/reader/__init__.py +0 -0
  258. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/reader/_base.py +0 -0
  259. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/spreadsheet.py +0 -0
  260. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/text.py +0 -0
  261. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/time_.py +0 -0
  262. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/upload.py +0 -0
  263. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_utils/xml_.py +0 -0
  264. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/__init__.py +0 -0
  265. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/base.py +0 -0
  266. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/cdf_store.py +0 -0
  267. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/examples/Export_DMS/workflow.yaml +0 -0
  268. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/examples/Export_Semantic_Data_Model/workflow.yaml +0 -0
  269. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/examples/Import_DMS/workflow.yaml +0 -0
  270. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/examples/Validate_Rules/workflow.yaml +0 -0
  271. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/examples/Validate_Solution_Model/workflow.yaml +0 -0
  272. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/manager.py +0 -0
  273. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/model.py +0 -0
  274. {cognite_neat-0.99.0/cognite/neat/_utils → cognite_neat-0.100.0/cognite/neat/_workflows/steps}/__init__.py +0 -0
  275. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/data_contracts.py +0 -0
  276. {cognite_neat-0.99.0/cognite/neat/_workflows/steps → cognite_neat-0.100.0/cognite/neat/_workflows/steps/lib}/__init__.py +0 -0
  277. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/lib/current/__init__.py +0 -0
  278. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/lib/current/graph_extractor.py +0 -0
  279. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/lib/current/graph_loader.py +0 -0
  280. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/lib/current/graph_store.py +0 -0
  281. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/lib/io/__init__.py +0 -0
  282. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/lib/io/io_steps.py +0 -0
  283. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps/step_model.py +0 -0
  284. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/steps_registry.py +0 -0
  285. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/tasks.py +0 -0
  286. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/triggers.py +0 -0
  287. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/_workflows/utils.py +0 -0
  288. {cognite_neat-0.99.0 → cognite_neat-0.100.0}/cognite/neat/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cognite-neat
3
- Version: 0.99.0
3
+ Version: 0.100.0
4
4
  Summary: Knowledge graph transformation
5
5
  Home-page: https://cognite-neat.readthedocs-hosted.com/
6
6
  License: Apache-2.0
@@ -1,11 +1,12 @@
1
+ import warnings
1
2
  from abc import ABC, abstractmethod
2
- from collections.abc import Sequence
3
+ from collections.abc import Callable, Collection, Iterable, Sequence
4
+ from dataclasses import dataclass, field
3
5
  from graphlib import TopologicalSorter
4
- from typing import TYPE_CHECKING, Any, Generic, Literal, TypeVar, cast
6
+ from typing import TYPE_CHECKING, Any, ClassVar, Generic, TypeVar, cast
5
7
 
6
8
  from cognite.client.data_classes import filters
7
9
  from cognite.client.data_classes._base import (
8
- CogniteResourceList,
9
10
  T_CogniteResourceList,
10
11
  T_WritableCogniteResource,
11
12
  T_WriteClass,
@@ -22,6 +23,10 @@ from cognite.client.data_classes.data_modeling import (
22
23
  DataModelList,
23
24
  EdgeConnection,
24
25
  MappedProperty,
26
+ Node,
27
+ NodeApply,
28
+ NodeApplyList,
29
+ NodeList,
25
30
  RequiresConstraint,
26
31
  Space,
27
32
  SpaceApply,
@@ -47,6 +52,9 @@ from cognite.client.data_classes.data_modeling.views import (
47
52
  from cognite.client.exceptions import CogniteAPIError
48
53
  from cognite.client.utils.useful_types import SequenceNotStr
49
54
 
55
+ from cognite.neat._client.data_classes.data_modeling import Component
56
+ from cognite.neat._client.data_classes.schema import DMSSchema
57
+ from cognite.neat._issues.warnings import CDFMaxIterationsWarning
50
58
  from cognite.neat._shared import T_ID
51
59
 
52
60
  if TYPE_CHECKING:
@@ -54,6 +62,16 @@ if TYPE_CHECKING:
54
62
 
55
63
  T_WritableCogniteResourceList = TypeVar("T_WritableCogniteResourceList", bound=WriteableCogniteResourceList)
56
64
 
65
+ T_Item = TypeVar("T_Item")
66
+ T_Out = TypeVar("T_Out", bound=Iterable)
67
+
68
+
69
+ @dataclass
70
+ class MultiCogniteAPIError(Exception, Generic[T_ID, T_WritableCogniteResourceList]):
71
+ success: T_WritableCogniteResourceList
72
+ failed: list[T_ID] = field(default_factory=list)
73
+ errors: list[CogniteAPIError] = field(default_factory=list)
74
+
57
75
 
58
76
  class ResourceLoader(
59
77
  ABC,
@@ -66,6 +84,7 @@ class ResourceLoader(
66
84
  """
67
85
 
68
86
  resource_name: str
87
+ dependencies: "ClassVar[frozenset[type[ResourceLoader]]]" = frozenset()
69
88
 
70
89
  def __init__(self, client: "NeatClient") -> None:
71
90
  # This is exposed to allow for disabling the cache.
@@ -87,35 +106,79 @@ class ResourceLoader(
87
106
  return [cls.get_id(item) for item in items]
88
107
 
89
108
  def create(self, items: Sequence[T_WriteClass]) -> T_WritableCogniteResourceList:
90
- created = self._create(items)
109
+ # Containers can have dependencies on other containers, so we sort them before creating them.
110
+ items = self.sort_by_dependencies(items)
111
+
112
+ exception: MultiCogniteAPIError[T_ID, T_WritableCogniteResourceList] | None = None
113
+ try:
114
+ created = self._fallback_one_by_one(self._create, items)
115
+ except MultiCogniteAPIError as e:
116
+ created = e.success
117
+ exception = e
118
+
91
119
  if self.cache:
92
120
  self._items_by_id.update({self.get_id(item): item for item in created})
121
+
122
+ if exception is not None:
123
+ raise exception
124
+
93
125
  return created
94
126
 
95
127
  def retrieve(self, ids: SequenceNotStr[T_ID]) -> T_WritableCogniteResourceList:
96
128
  if not self.cache:
97
- return self._retrieve(ids)
129
+ # We now that SequenceNotStr = Sequence
130
+ return self._fallback_one_by_one(self._retrieve, ids) # type: ignore[arg-type]
131
+ exception: MultiCogniteAPIError[T_ID, T_WritableCogniteResourceList] | None = None
98
132
  missing_ids = [id for id in ids if id not in self._items_by_id.keys()]
99
133
  if missing_ids:
100
- retrieved = self._retrieve(missing_ids)
134
+ try:
135
+ retrieved = self._retrieve(missing_ids)
136
+ except MultiCogniteAPIError as e:
137
+ retrieved = e.success
138
+ exception = e
101
139
  self._items_by_id.update({self.get_id(item): item for item in retrieved})
102
- return self._create_list([self._items_by_id[id] for id in ids])
140
+ if exception is not None:
141
+ raise exception
142
+ # We need to check the cache again, in case we didn't retrieve all the items.
143
+ return self._create_list([self._items_by_id[id] for id in ids if id in self._items_by_id])
144
+
145
+ def update(
146
+ self, items: Sequence[T_WriteClass], force: bool = False, drop_data: bool = False
147
+ ) -> T_WritableCogniteResourceList:
148
+ exception: MultiCogniteAPIError[T_ID, T_WritableCogniteResourceList] | None = None
149
+ if force:
150
+ updated = self._update_force(items, drop_data=drop_data)
151
+ else:
152
+ try:
153
+ updated = self._fallback_one_by_one(self._update, items)
154
+ except MultiCogniteAPIError as e:
155
+ updated = e.success
156
+ exception = e
157
+
158
+ if self.cache:
159
+ self._items_by_id.update({self.get_id(item): item for item in updated})
160
+
161
+ if exception is not None:
162
+ raise exception
103
163
 
104
- def update(self, items: Sequence[T_WriteClass]) -> T_WritableCogniteResourceList:
105
- if not self.cache:
106
- return self._update(items)
107
- updated = self._update(items)
108
- self._items_by_id.update({self.get_id(item): item for item in updated})
109
164
  return updated
110
165
 
111
166
  def delete(self, ids: SequenceNotStr[T_ID] | Sequence[T_WriteClass]) -> list[T_ID]:
112
167
  id_list = [self.get_id(item) for item in ids]
113
- if not self.cache:
114
- return self._delete(id_list)
115
- ids = [self.get_id(item) for item in ids]
116
- deleted = self._delete(id_list)
117
- for id in deleted:
118
- self._items_by_id.pop(id, None)
168
+ exception: MultiCogniteAPIError[T_ID, T_WritableCogniteResourceList] | None = None
169
+ try:
170
+ # We know that SequenceNotStr = Sequence
171
+ deleted = self._fallback_one_by_one(self._delete, id_list) # type: ignore[arg-type]
172
+ except MultiCogniteAPIError as e:
173
+ deleted = e.success
174
+ exception = e
175
+
176
+ if self.cache:
177
+ for id in deleted:
178
+ self._items_by_id.pop(id, None)
179
+ if exception is not None:
180
+ raise exception
181
+
119
182
  return deleted
120
183
 
121
184
  @abstractmethod
@@ -138,9 +201,77 @@ class ResourceLoader(
138
201
  def _create_list(self, items: Sequence[T_WritableCogniteResource]) -> T_WritableCogniteResourceList:
139
202
  raise NotImplementedError
140
203
 
204
+ def has_data(self, item_id: T_ID) -> bool:
205
+ return False
206
+
141
207
  def are_equal(self, local: T_WriteClass, remote: T_WritableCogniteResource) -> bool:
142
208
  return local == remote.as_write()
143
209
 
210
+ def sort_by_dependencies(self, items: Sequence[T_WriteClass]) -> list[T_WriteClass]:
211
+ return list(items)
212
+
213
+ def _update_force(
214
+ self,
215
+ items: Sequence[T_WriteClass],
216
+ drop_data: bool = False,
217
+ tried_force_update: set[T_ID] | None = None,
218
+ success: T_WritableCogniteResourceList | None = None,
219
+ ) -> T_WritableCogniteResourceList:
220
+ tried_force_update = tried_force_update or set()
221
+ try:
222
+ return self._update(items)
223
+ except CogniteAPIError as e:
224
+ failed_ids = {self.get_id(failed) for failed in e.failed + e.unknown}
225
+ success_ids = [self.get_id(success) for success in e.successful]
226
+ success_ = self.retrieve(success_ids)
227
+ if success is None:
228
+ success = success_
229
+ else:
230
+ success.extend(success_)
231
+ to_redeploy: list[T_WriteClass] = []
232
+ for item in items:
233
+ item_id = self.get_id(item)
234
+ if item_id in failed_ids:
235
+ if tried_force_update and item_id in tried_force_update:
236
+ # Avoid infinite loop
237
+ continue
238
+ tried_force_update.add(item_id)
239
+ if self.has_data(item_id) and not drop_data:
240
+ continue
241
+ to_redeploy.append(item)
242
+ if not to_redeploy:
243
+ # Avoid infinite loop
244
+ raise e
245
+ self.delete(to_redeploy)
246
+ forced = self._update_force(to_redeploy, drop_data, tried_force_update, success)
247
+ forced.extend(success)
248
+ return forced
249
+
250
+ def _fallback_one_by_one(self, method: Callable[[Sequence[T_Item]], T_Out], items: Sequence[T_Item]) -> T_Out:
251
+ try:
252
+ return method(items)
253
+ except CogniteAPIError as e:
254
+ exception = MultiCogniteAPIError[T_ID, T_WritableCogniteResourceList](self._create_list([]))
255
+ success = {self.get_id(success) for success in e.successful}
256
+ if success:
257
+ # Need read version of the items to put into cache.
258
+ retrieve_items = self.retrieve(list(success))
259
+ exception.success.extend(retrieve_items)
260
+ for item in items:
261
+ # We know that item is either T_ID or T_WriteClass
262
+ # but the T_Item cannot be bound to both types at the same time.
263
+ item_id = self.get_id(item) # type: ignore[arg-type]
264
+ if item_id in success:
265
+ continue
266
+ try:
267
+ item_result = method([item])
268
+ except CogniteAPIError as item_exception:
269
+ exception.errors.append(item_exception)
270
+ exception.failed.extend(self.get_ids(item_exception.failed))
271
+ else:
272
+ exception.success.extend(item_result)
273
+ raise exception from None
274
+
144
275
 
145
276
  class DataModelingLoader(
146
277
  ResourceLoader[T_ID, T_WriteClass, T_WritableCogniteResource, T_CogniteResourceList, T_WritableCogniteResourceList],
@@ -152,40 +283,10 @@ class DataModelingLoader(
152
283
  return item.space in space
153
284
  raise ValueError(f"Item {item} does not have a space attribute")
154
285
 
155
- def sort_by_dependencies(self, items: list[T_WriteClass]) -> list[T_WriteClass]:
156
- return items
157
-
158
- def create(
159
- self, items: Sequence[T_WriteClass], existing_handling: Literal["fail", "skip", "update", "force"] = "fail"
160
- ) -> T_WritableCogniteResourceList:
161
- if existing_handling != "force":
162
- return super().create(items)
163
-
164
- created = self._create_force(items, set())
165
- if self.cache:
166
- self._items_by_id.update({self.get_id(item): item for item in created})
167
- return created
168
-
169
- def _create_force(
170
- self,
171
- items: Sequence[T_WriteClass],
172
- tried_force_deploy: set[T_ID],
173
- ) -> T_WritableCogniteResourceList:
174
- try:
175
- return self._create(items)
176
- except CogniteAPIError as e:
177
- failed_ids = {self.get_id(failed) for failed in e.failed}
178
- to_redeploy = [
179
- item
180
- for item in items
181
- if self.get_id(item) in failed_ids and self.get_id(item) not in tried_force_deploy
182
- ]
183
- if not to_redeploy:
184
- # Avoid infinite loop
185
- raise e
186
- tried_force_deploy.update([self.get_id(item) for item in to_redeploy])
187
- self.delete(to_redeploy)
188
- return self._create_force(to_redeploy, tried_force_deploy)
286
+ @classmethod
287
+ @abstractmethod
288
+ def items_from_schema(cls, schema: DMSSchema) -> T_CogniteResourceList:
289
+ raise NotImplementedError
189
290
 
190
291
 
191
292
  class SpaceLoader(DataModelingLoader[str, SpaceApply, Space, SpaceApplyList, SpaceList]):
@@ -257,9 +358,147 @@ class SpaceLoader(DataModelingLoader[str, SpaceApply, Space, SpaceApplyList, Spa
257
358
  deleted_space = self._client.data_modeling.spaces.delete(space)
258
359
  print(f"Deleted space {deleted_space}")
259
360
 
361
+ @classmethod
362
+ def items_from_schema(cls, schema: DMSSchema) -> SpaceApplyList:
363
+ return SpaceApplyList(schema.spaces.values())
364
+
365
+ def has_data(self, item_id: str) -> bool:
366
+ return bool(self._client.data_modeling.instances.list("node", limit=1, space=item_id)) or bool(
367
+ self._client.data_modeling.instances.list("edge", limit=1, space=item_id)
368
+ )
369
+
370
+
371
+ class ContainerLoader(DataModelingLoader[ContainerId, ContainerApply, Container, ContainerApplyList, ContainerList]):
372
+ resource_name = "containers"
373
+ dependencies = frozenset({SpaceLoader})
374
+
375
+ @classmethod
376
+ def get_id(cls, item: Container | ContainerApply | ContainerId | dict) -> ContainerId:
377
+ if isinstance(item, Container | ContainerApply):
378
+ return item.as_id()
379
+ if isinstance(item, dict):
380
+ return ContainerId.load(item)
381
+ return item
382
+
383
+ def sort_by_dependencies(self, items: Sequence[ContainerApply]) -> list[ContainerApply]:
384
+ container_by_id = {container.as_id(): container for container in items}
385
+ container_dependencies = {
386
+ container.as_id(): {
387
+ const.require
388
+ for const in container.constraints.values()
389
+ if isinstance(const, RequiresConstraint) and const.require in container_by_id
390
+ }
391
+ for container in items
392
+ }
393
+ return [
394
+ container_by_id[container_id] for container_id in TopologicalSorter(container_dependencies).static_order()
395
+ ]
396
+
397
+ def _create(self, items: Sequence[ContainerApply]) -> ContainerList:
398
+ return self._client.data_modeling.containers.apply(items)
399
+
400
+ def retrieve(self, ids: SequenceNotStr[ContainerId], include_connected: bool = False) -> ContainerList:
401
+ if not include_connected:
402
+ return super().retrieve(ids)
403
+ # Retrieve recursively updates the cache.
404
+ return self._retrieve_recursive(ids)
405
+
406
+ def _retrieve(self, ids: SequenceNotStr[ContainerId]) -> ContainerList:
407
+ return self._client.data_modeling.containers.retrieve(cast(Sequence, ids))
408
+
409
+ def _update(self, items: Sequence[ContainerApply]) -> ContainerList:
410
+ return self._create(items)
411
+
412
+ def _delete(self, ids: SequenceNotStr[ContainerId]) -> list[ContainerId]:
413
+ return self._client.data_modeling.containers.delete(cast(Sequence, ids))
414
+
415
+ def _create_list(self, items: Sequence[Container]) -> ContainerList:
416
+ return ContainerList(items)
417
+
418
+ def _retrieve_recursive(self, container_ids: SequenceNotStr[ContainerId]) -> ContainerList:
419
+ """Containers can reference each other through the 'requires' constraint.
420
+
421
+ This method retrieves all containers that are referenced by other containers through the 'requires' constraint,
422
+ including their parents.
423
+ """
424
+ max_iterations = 10 # Limiting the number of iterations to avoid infinite loops
425
+ found = ContainerList([])
426
+ found_ids: set[ContainerId] = set()
427
+ last_batch = list(container_ids)
428
+ for _ in range(max_iterations):
429
+ if not last_batch:
430
+ break
431
+ to_retrieve_from_cdf: set[ContainerId] = set()
432
+ batch_ids: list[ContainerId] = []
433
+ for container_id in last_batch:
434
+ if container_id in found_ids:
435
+ continue
436
+ elif container_id in self._items_by_id:
437
+ container = self._items_by_id[container_id]
438
+ found.append(container)
439
+ batch_ids.extend(self.get_connected_containers(container, found_ids))
440
+ else:
441
+ to_retrieve_from_cdf.add(container_id)
442
+
443
+ if to_retrieve_from_cdf:
444
+ retrieved_batch = self._client.data_modeling.containers.retrieve(list(to_retrieve_from_cdf))
445
+ self._items_by_id.update({view.as_id(): view for view in retrieved_batch})
446
+ found.extend(retrieved_batch)
447
+ found_ids.update({view.as_id() for view in retrieved_batch})
448
+ for container in retrieved_batch:
449
+ batch_ids.extend(self.get_connected_containers(container, found_ids))
450
+
451
+ last_batch = batch_ids
452
+ else:
453
+ warnings.warn(
454
+ CDFMaxIterationsWarning(
455
+ "The maximum number of iterations was reached while resolving referenced containers."
456
+ "There might be referenced containers that are not included in the list of containers.",
457
+ max_iterations=max_iterations,
458
+ ),
459
+ stacklevel=2,
460
+ )
461
+
462
+ if self.cache is False:
463
+ # We must update the cache to retrieve recursively.
464
+ # If the cache is disabled, bust the cache to avoid storing the retrieved views.
465
+ self.bust_cache()
466
+ return found
467
+
468
+ @staticmethod
469
+ def get_connected_containers(
470
+ container: Container | ContainerApply, skip: set[ContainerId] | None = None
471
+ ) -> set[ContainerId]:
472
+ connected_containers = set()
473
+ for constraint in container.constraints.values():
474
+ if isinstance(constraint, RequiresConstraint):
475
+ connected_containers.add(constraint.require)
476
+ if skip:
477
+ return {container_id for container_id in connected_containers if container_id not in skip}
478
+ return connected_containers
479
+
480
+ def are_equal(self, local: ContainerApply, remote: Container) -> bool:
481
+ local_dumped = local.dump(camel_case=True)
482
+ if "usedFor" not in local_dumped:
483
+ # Setting used_for to "node" as it is the default value in the CDF.
484
+ local_dumped["usedFor"] = "node"
485
+
486
+ return local_dumped == remote.as_write().dump(camel_case=True)
487
+
488
+ @classmethod
489
+ def items_from_schema(cls, schema: DMSSchema) -> ContainerApplyList:
490
+ return ContainerApplyList(schema.containers.values())
491
+
492
+ def has_data(self, item_id: ContainerId) -> bool:
493
+ has_data = filters.HasData(containers=[item_id])
494
+ return bool(self._client.data_modeling.instances.list("node", limit=1, filter=has_data)) or bool(
495
+ self._client.data_modeling.instances.list("edge", limit=1, filter=has_data)
496
+ )
497
+
260
498
 
261
499
  class ViewLoader(DataModelingLoader[ViewId, ViewApply, View, ViewApplyList, ViewList]):
262
500
  resource_name = "views"
501
+ dependencies = frozenset({SpaceLoader, ContainerLoader})
263
502
 
264
503
  @classmethod
265
504
  def get_id(cls, item: View | ViewApply | ViewId | dict) -> ViewId:
@@ -273,12 +512,12 @@ class ViewLoader(DataModelingLoader[ViewId, ViewApply, View, ViewApplyList, View
273
512
  return self._client.data_modeling.views.apply(items)
274
513
 
275
514
  def retrieve(
276
- self, ids: SequenceNotStr[ViewId], include_connections: bool = False, include_ancestor: bool = False
515
+ self, ids: SequenceNotStr[ViewId], include_connected: bool = False, include_ancestor: bool = False
277
516
  ) -> ViewList:
278
- if not include_connections and not include_ancestor:
517
+ if not include_connected and not include_ancestor:
279
518
  return super().retrieve(ids)
280
519
  # Retrieve recursively updates the cache.
281
- return self._retrieve_recursive(ids, include_connections, include_ancestor)
520
+ return self._retrieve_recursive(ids, include_connected, include_ancestor)
282
521
 
283
522
  def _retrieve(self, ids: SequenceNotStr[ViewId]) -> ViewList:
284
523
  return self._client.data_modeling.views.retrieve(cast(Sequence, ids))
@@ -338,19 +577,19 @@ class ViewLoader(DataModelingLoader[ViewId, ViewApply, View, ViewApplyList, View
338
577
  include_connections: Whether to include all connected views.
339
578
  include_ancestors: Whether to include all ancestors.
340
579
  """
341
- last_batch = list(view_ids)
580
+ last_batch = set(view_ids)
342
581
  found = ViewList([])
343
582
  found_ids: set[ViewId] = set()
344
583
  while last_batch:
345
584
  to_retrieve_from_cdf: set[ViewId] = set()
346
- batch_ids: list[ViewId] = []
585
+ batch_ids: set[ViewId] = set()
347
586
  for view_id in last_batch:
348
587
  if view_id in found_ids:
349
588
  continue
350
589
  elif view_id in self._items_by_id:
351
590
  view = self._items_by_id[view_id]
352
591
  found.append(view)
353
- batch_ids.extend(self.get_connected_views(view, include_ancestors, include_connections, found_ids))
592
+ batch_ids.update(self.get_connected_views(view, include_ancestors, include_connections, found_ids))
354
593
  else:
355
594
  to_retrieve_from_cdf.add(view_id)
356
595
 
@@ -360,7 +599,7 @@ class ViewLoader(DataModelingLoader[ViewId, ViewApply, View, ViewApplyList, View
360
599
  found.extend(retrieved_batch)
361
600
  found_ids.update({view.as_id() for view in retrieved_batch})
362
601
  for view in retrieved_batch:
363
- batch_ids.extend(self.get_connected_views(view, include_ancestors, include_connections, found_ids))
602
+ batch_ids.update(self.get_connected_views(view, include_ancestors, include_connections, found_ids))
364
603
 
365
604
  last_batch = batch_ids
366
605
 
@@ -400,58 +639,14 @@ class ViewLoader(DataModelingLoader[ViewId, ViewApply, View, ViewApplyList, View
400
639
  def _create_list(self, items: Sequence[View]) -> ViewList:
401
640
  return ViewList(items)
402
641
 
403
-
404
- class ContainerLoader(DataModelingLoader[ContainerId, ContainerApply, Container, ContainerApplyList, ContainerList]):
405
- resource_name = "containers"
406
-
407
642
  @classmethod
408
- def get_id(cls, item: Container | ContainerApply | ContainerId | dict) -> ContainerId:
409
- if isinstance(item, Container | ContainerApply):
410
- return item.as_id()
411
- if isinstance(item, dict):
412
- return ContainerId.load(item)
413
- return item
414
-
415
- def sort_by_dependencies(self, items: Sequence[ContainerApply]) -> list[ContainerApply]:
416
- container_by_id = {container.as_id(): container for container in items}
417
- container_dependencies = {
418
- container.as_id(): {
419
- const.require
420
- for const in container.constraints.values()
421
- if isinstance(const, RequiresConstraint) and const.require in container_by_id
422
- }
423
- for container in items
424
- }
425
- return [
426
- container_by_id[container_id] for container_id in TopologicalSorter(container_dependencies).static_order()
427
- ]
428
-
429
- def _create(self, items: Sequence[ContainerApply]) -> ContainerList:
430
- return self._client.data_modeling.containers.apply(items)
431
-
432
- def _retrieve(self, ids: SequenceNotStr[ContainerId]) -> ContainerList:
433
- return self._client.data_modeling.containers.retrieve(cast(Sequence, ids))
434
-
435
- def _update(self, items: Sequence[ContainerApply]) -> ContainerList:
436
- return self._create(items)
437
-
438
- def _delete(self, ids: SequenceNotStr[ContainerId]) -> list[ContainerId]:
439
- return self._client.data_modeling.containers.delete(cast(Sequence, ids))
440
-
441
- def _create_list(self, items: Sequence[Container]) -> ContainerList:
442
- return ContainerList(items)
443
-
444
- def are_equal(self, local: ContainerApply, remote: Container) -> bool:
445
- local_dumped = local.dump(camel_case=True)
446
- if "usedFor" not in local_dumped:
447
- # Setting used_for to "node" as it is the default value in the CDF.
448
- local_dumped["usedFor"] = "node"
449
-
450
- return local_dumped == remote.as_write().dump(camel_case=True)
643
+ def items_from_schema(cls, schema: DMSSchema) -> ViewApplyList:
644
+ return ViewApplyList(schema.views.values())
451
645
 
452
646
 
453
647
  class DataModelLoader(DataModelingLoader[DataModelId, DataModelApply, DataModel, DataModelApplyList, DataModelList]):
454
648
  resource_name = "data_models"
649
+ dependencies = frozenset({SpaceLoader, ViewLoader})
455
650
 
456
651
  @classmethod
457
652
  def get_id(cls, item: DataModel | DataModelApply | DataModelId | dict) -> DataModelId:
@@ -491,6 +686,72 @@ class DataModelLoader(DataModelingLoader[DataModelId, DataModelApply, DataModel,
491
686
 
492
687
  return local_dumped == cdf_resource_dumped
493
688
 
689
+ @classmethod
690
+ def items_from_schema(cls, schema: DMSSchema) -> DataModelApplyList:
691
+ return DataModelApplyList([schema.data_model])
692
+
693
+
694
+ class NodeLoader(DataModelingLoader[NodeId, NodeApply, Node, NodeApplyList, NodeList]):
695
+ resource_name = "nodes"
696
+ dependencies = frozenset({SpaceLoader, ContainerLoader, ViewLoader})
697
+
698
+ @classmethod
699
+ def get_id(cls, item: Node | NodeApply | NodeId | dict) -> NodeId:
700
+ if isinstance(item, Node | NodeApply):
701
+ return item.as_id()
702
+ if isinstance(item, dict):
703
+ return NodeId.load(item)
704
+ return item
705
+
706
+ def _create(self, items: Sequence[NodeApply]) -> NodeList:
707
+ self._client.data_modeling.instances.apply(items)
708
+ return self._retrieve([item.as_id() for item in items])
709
+
710
+ def _retrieve(self, ids: SequenceNotStr[NodeId]) -> NodeList:
711
+ return self._client.data_modeling.instances.retrieve(cast(Sequence, ids)).nodes
712
+
713
+ def _update(self, items: Sequence[NodeApply]) -> NodeList:
714
+ self._client.data_modeling.instances.apply(items, replace=True)
715
+ return self._retrieve([item.as_id() for item in items])
716
+
717
+ def _delete(self, ids: SequenceNotStr[NodeId]) -> list[NodeId]:
718
+ return list(self._client.data_modeling.instances.delete(nodes=cast(Sequence, ids)).nodes)
719
+
720
+ def _create_list(self, items: Sequence[Node]) -> NodeList:
721
+ return NodeList(items)
722
+
723
+ def are_equal(self, local: NodeApply, remote: Node) -> bool:
724
+ local_dumped = local.dump()
725
+
726
+ # Note reading from a container is not supported.
727
+ sources = [
728
+ source_prop_pair.source
729
+ for source_prop_pair in local.sources or []
730
+ if isinstance(source_prop_pair.source, ViewId)
731
+ ]
732
+ if sources:
733
+ try:
734
+ cdf_resource_with_properties = self._client.data_modeling.instances.retrieve(
735
+ nodes=remote.as_id(), sources=sources
736
+ ).nodes[0]
737
+ except CogniteAPIError:
738
+ # View does not exist, so node does not exist.
739
+ return False
740
+ else:
741
+ cdf_resource_with_properties = remote
742
+ cdf_resource_dumped = cdf_resource_with_properties.as_write().dump()
743
+
744
+ if "existingVersion" not in local_dumped:
745
+ # Existing version is typically not set when creating nodes, but we get it back
746
+ # when we retrieve the node from the server.
747
+ local_dumped["existingVersion"] = cdf_resource_dumped.get("existingVersion", None)
748
+
749
+ return local_dumped == cdf_resource_dumped
750
+
751
+ @classmethod
752
+ def items_from_schema(cls, schema: DMSSchema) -> NodeApplyList:
753
+ return NodeApplyList(schema.node_types.values())
754
+
494
755
 
495
756
  class DataModelLoaderAPI:
496
757
  def __init__(self, client: "NeatClient") -> None:
@@ -499,14 +760,27 @@ class DataModelLoaderAPI:
499
760
  self.views = ViewLoader(client)
500
761
  self.containers = ContainerLoader(client)
501
762
  self.data_models = DataModelLoader(client)
763
+ self.nodes = NodeLoader(client)
764
+ self._loaders: list[DataModelingLoader] = [
765
+ self.spaces,
766
+ self.views,
767
+ self.containers,
768
+ self.data_models,
769
+ self.nodes,
770
+ ]
502
771
 
503
- def get_loader(self, items: Any) -> DataModelingLoader:
504
- if isinstance(items, CogniteResourceList):
505
- resource_name = type(items).__name__.casefold().removesuffix("list").removesuffix("apply")
506
- elif isinstance(items, str):
507
- resource_name = items
508
- else:
509
- raise ValueError(f"Cannot determine resource name from {items}")
510
- if resource_name[-1] != "s":
511
- resource_name += "s"
512
- return getattr(self, resource_name)
772
+ def by_dependency_order(
773
+ self, component: Component | Collection[Component] | None = None
774
+ ) -> list[DataModelingLoader]:
775
+ loader_by_type = {type(loader): loader for loader in self._loaders}
776
+ loader_iterable = (
777
+ loader_by_type[loader_cls] # type: ignore[index]
778
+ for loader_cls in TopologicalSorter(
779
+ {type(loader): loader.dependencies for loader in self._loaders} # type: ignore[attr-defined]
780
+ ).static_order()
781
+ )
782
+ if component is None:
783
+ return list(loader_iterable)
784
+ components = {component} if isinstance(component, str) else set(component)
785
+ components = {{"node_type": "nodes"}.get(component, component) for component in components}
786
+ return [loader for loader in loader_iterable if loader.resource_name in components]