cognite-neat 0.101.0__tar.gz → 0.102.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.

Potentially problematic release.


This version of cognite-neat might be problematic. Click here for more details.

Files changed (272) hide show
  1. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/PKG-INFO +1 -1
  2. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_constants.py +5 -1
  3. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/loaders/_rdf2dms.py +1 -1
  4. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/queries/_base.py +22 -2
  5. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/queries/_shared.py +4 -4
  6. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/transformers/__init__.py +13 -1
  7. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/transformers/_base.py +1 -1
  8. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/transformers/_iodd.py +2 -2
  9. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/transformers/_prune_graph.py +98 -24
  10. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/exporters/_rules2excel.py +7 -2
  11. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_dms2rules.py +51 -19
  12. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_rdf/_base.py +2 -2
  13. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/information/_rules.py +3 -3
  14. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_prepare.py +85 -2
  15. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/engine/_load.py +3 -1
  16. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_store/_base.py +23 -2
  17. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/auth.py +6 -4
  18. cognite_neat-0.102.0/cognite/neat/_version.py +2 -0
  19. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/pyproject.toml +1 -1
  20. cognite_neat-0.101.0/cognite/neat/_version.py +0 -2
  21. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/LICENSE +0 -0
  22. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/README.md +0 -0
  23. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/__init__.py +0 -0
  24. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/__init__.py +0 -0
  25. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/asgi/metrics.py +0 -0
  26. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/configuration.py +0 -0
  27. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/context_manager/__init__.py +0 -0
  28. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/context_manager/manager.py +0 -0
  29. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/data_classes/__init__.py +0 -0
  30. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/data_classes/rest.py +0 -0
  31. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/explorer.py +0 -0
  32. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/routers/configuration.py +0 -0
  33. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/routers/crud.py +0 -0
  34. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/routers/metrics.py +0 -0
  35. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/routers/workflows.py +0 -0
  36. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/utils/__init__.py +0 -0
  37. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/utils/data_mapping.py +0 -0
  38. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/utils/logging.py +0 -0
  39. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/api/utils/query_templates.py +0 -0
  40. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/main.py +0 -0
  41. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/monitoring/__init__.py +0 -0
  42. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/monitoring/metrics.py +0 -0
  43. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/index.html +0 -0
  44. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/.gitignore +0 -0
  45. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/README.md +0 -0
  46. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/asset-manifest.json +0 -0
  47. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/favicon.ico +0 -0
  48. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/img/architect-icon.svg +0 -0
  49. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/img/developer-icon.svg +0 -0
  50. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/img/sme-icon.svg +0 -0
  51. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/index.html +0 -0
  52. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/logo192.png +0 -0
  53. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/manifest.json +0 -0
  54. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/robots.txt +0 -0
  55. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/static/css/main.72e3d92e.css +0 -0
  56. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/static/css/main.72e3d92e.css.map +0 -0
  57. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js +0 -0
  58. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js.LICENSE.txt +0 -0
  59. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/static/js/main.5a52cf09.js.map +0 -0
  60. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -0
  61. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/package-lock.json +0 -0
  62. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/package.json +0 -0
  63. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/public/favicon.ico +0 -0
  64. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/public/img/architect-icon.svg +0 -0
  65. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/public/img/developer-icon.svg +0 -0
  66. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/public/img/sme-icon.svg +0 -0
  67. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/public/index.html +0 -0
  68. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/public/logo192.png +0 -0
  69. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/public/manifest.json +0 -0
  70. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/public/robots.txt +0 -0
  71. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/App.css +0 -0
  72. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/App.js +0 -0
  73. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/App.test.js +0 -0
  74. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/MainContainer.tsx +0 -0
  75. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/JsonViewer.tsx +0 -0
  76. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/LocalUploader.tsx +0 -0
  77. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/OverviewComponentEditorDialog.tsx +0 -0
  78. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/StepEditorDialog.tsx +0 -0
  79. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/TabPanel.tsx +0 -0
  80. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/Utils.tsx +0 -0
  81. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/WorkflowDeleteDialog.tsx +0 -0
  82. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/WorkflowExecutionReport.tsx +0 -0
  83. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/WorkflowImportExportDialog.tsx +0 -0
  84. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/components/WorkflowMetadataDialog.tsx +0 -0
  85. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/index.css +0 -0
  86. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/index.js +0 -0
  87. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/logo.svg +0 -0
  88. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/reportWebVitals.js +0 -0
  89. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/setupTests.js +0 -0
  90. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/types/WorkflowTypes.ts +0 -0
  91. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/views/AboutView.tsx +0 -0
  92. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/views/ConfigView.tsx +0 -0
  93. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/views/GlobalConfigView.tsx +0 -0
  94. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/src/views/WorkflowView.tsx +0 -0
  95. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_app/ui/neat-app/tsconfig.json +0 -0
  96. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_client/__init__.py +0 -0
  97. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_client/_api/__init__.py +0 -0
  98. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_client/_api/data_modeling_loaders.py +0 -0
  99. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_client/_api/schema.py +0 -0
  100. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_client/_api_client.py +0 -0
  101. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_client/data_classes/__init__.py +0 -0
  102. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_client/data_classes/data_modeling.py +0 -0
  103. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_client/data_classes/schema.py +0 -0
  104. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_config.py +0 -0
  105. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/__init__.py +0 -0
  106. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/_shared.py +0 -0
  107. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/_tracking/__init__.py +0 -0
  108. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/_tracking/base.py +0 -0
  109. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/_tracking/log.py +0 -0
  110. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  111. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44.xml +0 -0
  112. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/examples/__init__.py +0 -0
  113. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  114. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/__init__.py +0 -0
  115. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_base.py +0 -0
  116. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/__init__.py +0 -0
  117. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_assets.py +0 -0
  118. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_base.py +0 -0
  119. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_classic.py +0 -0
  120. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_data_sets.py +0 -0
  121. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_events.py +0 -0
  122. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_files.py +0 -0
  123. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_labels.py +0 -0
  124. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_relationships.py +0 -0
  125. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_sequences.py +0 -0
  126. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_classic_cdf/_timeseries.py +0 -0
  127. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_dexpi.py +0 -0
  128. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_dms.py +0 -0
  129. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_iodd.py +0 -0
  130. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_mock_graph_generator.py +0 -0
  131. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/extractors/_rdf_file.py +0 -0
  132. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/loaders/__init__.py +0 -0
  133. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/loaders/_base.py +0 -0
  134. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/queries/__init__.py +0 -0
  135. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/queries/_construct.py +0 -0
  136. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/transformers/_classic_cdf.py +0 -0
  137. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/transformers/_rdfpath.py +0 -0
  138. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_graph/transformers/_value_type.py +0 -0
  139. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/__init__.py +0 -0
  140. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/_base.py +0 -0
  141. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/errors/__init__.py +0 -0
  142. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/errors/_external.py +0 -0
  143. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/errors/_general.py +0 -0
  144. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/errors/_properties.py +0 -0
  145. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/errors/_resources.py +0 -0
  146. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/errors/_workflow.py +0 -0
  147. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/formatters.py +0 -0
  148. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/warnings/__init__.py +0 -0
  149. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/warnings/_external.py +0 -0
  150. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/warnings/_general.py +0 -0
  151. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/warnings/_models.py +0 -0
  152. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/warnings/_properties.py +0 -0
  153. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/warnings/_resources.py +0 -0
  154. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_issues/warnings/user_modeling.py +0 -0
  155. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/__init__.py +0 -0
  156. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/_constants.py +0 -0
  157. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/_shared.py +0 -0
  158. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/analysis/__init__.py +0 -0
  159. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/analysis/_base.py +0 -0
  160. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/analysis/_dms.py +0 -0
  161. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/analysis/_information.py +0 -0
  162. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/catalog/__init__.py +0 -0
  163. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
  164. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/exporters/__init__.py +0 -0
  165. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/exporters/_base.py +0 -0
  166. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/exporters/_rules2dms.py +0 -0
  167. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/exporters/_rules2instance_template.py +0 -0
  168. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/exporters/_rules2ontology.py +0 -0
  169. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/exporters/_rules2yaml.py +0 -0
  170. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/exporters/_validation.py +0 -0
  171. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/__init__.py +0 -0
  172. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_base.py +0 -0
  173. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_dtdl2rules/__init__.py +0 -0
  174. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_dtdl2rules/_unit_lookup.py +0 -0
  175. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_converter.py +0 -0
  176. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_importer.py +0 -0
  177. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_dtdl2rules/spec.py +0 -0
  178. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_rdf/__init__.py +0 -0
  179. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_rdf/_imf2rules.py +0 -0
  180. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_rdf/_inference2rules.py +0 -0
  181. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_rdf/_owl2rules.py +0 -0
  182. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_rdf/_shared.py +0 -0
  183. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_spreadsheet2rules.py +0 -0
  184. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/importers/_yaml2rules.py +0 -0
  185. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/__init__.py +0 -0
  186. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/_base_input.py +0 -0
  187. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/_base_rules.py +0 -0
  188. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/_rdfpath.py +0 -0
  189. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/_types.py +0 -0
  190. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/data_types.py +0 -0
  191. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/dms/__init__.py +0 -0
  192. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/dms/_exporter.py +0 -0
  193. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/dms/_rules.py +0 -0
  194. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/dms/_rules_input.py +0 -0
  195. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/dms/_validation.py +0 -0
  196. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/entities/__init__.py +0 -0
  197. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/entities/_constants.py +0 -0
  198. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/entities/_loaders.py +0 -0
  199. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/entities/_multi_value.py +0 -0
  200. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/entities/_single_value.py +0 -0
  201. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/entities/_types.py +0 -0
  202. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/entities/_wrapped.py +0 -0
  203. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/information/__init__.py +0 -0
  204. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/information/_rules_input.py +0 -0
  205. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/information/_validation.py +0 -0
  206. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/mapping/__init__.py +0 -0
  207. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/mapping/_classic2core.py +0 -0
  208. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/models/mapping/_classic2core.yaml +0 -0
  209. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/transformers/__init__.py +0 -0
  210. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/transformers/_base.py +0 -0
  211. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/transformers/_converters.py +0 -0
  212. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/transformers/_mapping.py +0 -0
  213. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/transformers/_pipelines.py +0 -0
  214. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_rules/transformers/_verification.py +0 -0
  215. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/__init__.py +0 -0
  216. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_base.py +0 -0
  217. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_collector.py +0 -0
  218. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_drop.py +0 -0
  219. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_inspect.py +0 -0
  220. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_mapping.py +0 -0
  221. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_read.py +0 -0
  222. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_set.py +0 -0
  223. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_show.py +0 -0
  224. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_state.py +0 -0
  225. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_to.py +0 -0
  226. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/_wizard.py +0 -0
  227. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/engine/__init__.py +0 -0
  228. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/engine/_import.py +0 -0
  229. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/engine/_interface.py +0 -0
  230. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_session/exceptions.py +0 -0
  231. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_shared.py +0 -0
  232. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_store/__init__.py +0 -0
  233. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_store/_provenance.py +0 -0
  234. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/__init__.py +0 -0
  235. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/auxiliary.py +0 -0
  236. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/collection_.py +0 -0
  237. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/rdf_.py +0 -0
  238. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/reader/__init__.py +0 -0
  239. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/reader/_base.py +0 -0
  240. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/spreadsheet.py +0 -0
  241. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/text.py +0 -0
  242. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/time_.py +0 -0
  243. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/upload.py +0 -0
  244. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_utils/xml_.py +0 -0
  245. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/__init__.py +0 -0
  246. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/base.py +0 -0
  247. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/cdf_store.py +0 -0
  248. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/examples/Export_DMS/workflow.yaml +0 -0
  249. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/examples/Export_Semantic_Data_Model/workflow.yaml +0 -0
  250. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/examples/Import_DMS/workflow.yaml +0 -0
  251. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/examples/Validate_Rules/workflow.yaml +0 -0
  252. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/examples/Validate_Solution_Model/workflow.yaml +0 -0
  253. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/manager.py +0 -0
  254. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/model.py +0 -0
  255. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/__init__.py +0 -0
  256. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/data_contracts.py +0 -0
  257. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/__init__.py +0 -0
  258. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/current/__init__.py +0 -0
  259. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/current/graph_extractor.py +0 -0
  260. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/current/graph_loader.py +0 -0
  261. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/current/graph_store.py +0 -0
  262. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/current/rules_exporter.py +0 -0
  263. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/current/rules_importer.py +0 -0
  264. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/current/rules_validator.py +0 -0
  265. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/io/__init__.py +0 -0
  266. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/lib/io/io_steps.py +0 -0
  267. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps/step_model.py +0 -0
  268. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/steps_registry.py +0 -0
  269. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/tasks.py +0 -0
  270. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/triggers.py +0 -0
  271. {cognite_neat-0.101.0 → cognite_neat-0.102.0}/cognite/neat/_workflows/utils.py +0 -0
  272. {cognite_neat-0.101.0 → cognite_neat-0.102.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.101.0
3
+ Version: 0.102.0
4
4
  Summary: Knowledge graph transformation
5
5
  Home-page: https://cognite-neat.readthedocs-hosted.com/
6
6
  License: Apache-2.0
@@ -71,7 +71,7 @@ UNKNOWN_TYPE = DEFAULT_NAMESPACE.UnknownType
71
71
  XML_SCHEMA_NAMESPACE = Namespace("http://www.w3.org/2001/XMLSchema#")
72
72
 
73
73
 
74
- def get_default_prefixes() -> dict[str, Namespace]:
74
+ def get_default_prefixes_and_namespaces() -> dict[str, Namespace]:
75
75
  return {
76
76
  "owl": OWL._NS,
77
77
  "rdf": RDF._NS,
@@ -84,6 +84,10 @@ def get_default_prefixes() -> dict[str, Namespace]:
84
84
  "imf": Namespace("http://ns.imfid.org/imf#"),
85
85
  "pav": Namespace("http://purl.org/pav/"),
86
86
  "foaf": FOAF._NS,
87
+ "dexpi": Namespace("http://sandbox.dexpi.org/rdl/"),
88
+ "qudt": Namespace("https://qudt.org/vocab/unit/"),
89
+ "iodd": Namespace("http://www.io-link.com/IODD/2010/10/"),
90
+ "aml": Namespace("https://www.automationml.org/"),
87
91
  }
88
92
 
89
93
 
@@ -197,7 +197,7 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
197
197
  json_fields: list[str] = []
198
198
  for prop_name, prop in view.properties.items():
199
199
  if isinstance(prop, dm.EdgeConnection):
200
- edge_by_property[prop.type.external_id] = prop_name, prop
200
+ edge_by_property[prop_name] = prop_name, prop
201
201
  if isinstance(prop, dm.MappedProperty):
202
202
  if isinstance(prop.type, dm.DirectRelation):
203
203
  direct_relation_by_property[prop_name] = prop.type
@@ -209,7 +209,10 @@ class Queries:
209
209
  elif (
210
210
  isinstance(object_, URIRef)
211
211
  and property_types
212
- and property_types.get(property_, None) == EntityTypes.object_property
212
+ and (
213
+ property_types.get(property_, None) == EntityTypes.object_property
214
+ or property_types.get(property_, None) == EntityTypes.undefined
215
+ )
213
216
  ):
214
217
  value = remove_namespace_from_uri(object_, validation="prefix")
215
218
 
@@ -233,7 +236,6 @@ class Queries:
233
236
  else:
234
237
  # we should not have multiple rdf:type values
235
238
  continue
236
-
237
239
  if property_values:
238
240
  return (
239
241
  identifier,
@@ -358,3 +360,21 @@ class Queries:
358
360
  dropped_types[t] = len(instance_ids)
359
361
  remove_instance_ids_in_batch(self.graph, instance_ids)
360
362
  return dropped_types
363
+
364
+ def multi_type_instances(self) -> dict[str, list[str]]:
365
+ """Find instances with multiple types"""
366
+
367
+ query = """
368
+ SELECT ?instance (GROUP_CONCAT(str(?type); SEPARATOR=",") AS ?types)
369
+ WHERE {
370
+ ?instance a ?type .
371
+ }
372
+ GROUP BY ?instance
373
+ HAVING (COUNT(?type) > 1)
374
+ """
375
+
376
+ result = {}
377
+ for instance, types in self.graph.query(query): # type: ignore
378
+ result[remove_namespace_from_uri(instance)] = remove_namespace_from_uri(types.split(","))
379
+
380
+ return result
@@ -6,7 +6,7 @@ from pydantic import BaseModel, ConfigDict, Field
6
6
  from rdflib import Graph, Literal, Namespace
7
7
  from rdflib.term import URIRef
8
8
 
9
- from cognite.neat._constants import get_default_prefixes
9
+ from cognite.neat._constants import get_default_prefixes_and_namespaces
10
10
  from cognite.neat._rules.models._rdfpath import (
11
11
  Hop,
12
12
  Step,
@@ -51,7 +51,7 @@ def generate_prefix_header(prefixes: dict[str, Namespace] | None = None) -> str:
51
51
  Prefix header
52
52
  """
53
53
 
54
- prefixes = prefixes or get_default_prefixes()
54
+ prefixes = prefixes or get_default_prefixes_and_namespaces()
55
55
 
56
56
  return "".join(f"PREFIX {key}:<{value}>\n" for key, value in prefixes.items())
57
57
 
@@ -81,7 +81,7 @@ def get_predicate_id(
81
81
  ID of predicate (aka property) connecting subject and object
82
82
  """
83
83
 
84
- prefixes = prefixes or get_default_prefixes()
84
+ prefixes = prefixes or get_default_prefixes_and_namespaces()
85
85
 
86
86
  query = """
87
87
 
@@ -123,7 +123,7 @@ def hop2property_path(
123
123
  str
124
124
  Property path string for hop traversal (e.g. ^rdf:type/rdfs:subClassOf)
125
125
  """
126
- prefixes = prefixes if prefixes else get_default_prefixes()
126
+ prefixes = prefixes if prefixes else get_default_prefixes_and_namespaces()
127
127
 
128
128
  # setting previous step to origin, as we are starting from there
129
129
  previous_step = Step(class_=hop.class_, direction="origin")
@@ -7,7 +7,13 @@ from ._classic_cdf import (
7
7
  AssetTimeSeriesConnector,
8
8
  RelationshipAsEdgeTransformer,
9
9
  )
10
- from ._prune_graph import AttachPropertyFromTargetToSource, PruneDanglingNodes
10
+ from ._prune_graph import (
11
+ AttachPropertyFromTargetToSource,
12
+ PruneDanglingNodes,
13
+ PruneDeadEndEdges,
14
+ PruneInstancesOfUnknownType,
15
+ PruneTypes,
16
+ )
11
17
  from ._rdfpath import AddSelfReferenceProperty, MakeConnectionOnExactMatch
12
18
  from ._value_type import SplitMultiValueProperty
13
19
 
@@ -24,6 +30,9 @@ __all__ = [
24
30
  "MakeConnectionOnExactMatch",
25
31
  "AttachPropertyFromTargetToSource",
26
32
  "PruneDanglingNodes",
33
+ "PruneTypes",
34
+ "PruneDeadEndEdges",
35
+ "PruneInstancesOfUnknownType",
27
36
  ]
28
37
 
29
38
  Transformers = (
@@ -39,4 +48,7 @@ Transformers = (
39
48
  | MakeConnectionOnExactMatch
40
49
  | AttachPropertyFromTargetToSource
41
50
  | PruneDanglingNodes
51
+ | PruneTypes
52
+ | PruneDeadEndEdges
53
+ | PruneInstancesOfUnknownType
42
54
  )
@@ -6,7 +6,7 @@ from rdflib import Graph
6
6
 
7
7
  class BaseTransformer(ABC):
8
8
  description: str
9
- _use_only_once: bool
9
+ _use_only_once: bool = False
10
10
  _need_changes: ClassVar[frozenset[str]] = frozenset()
11
11
 
12
12
  @abstractmethod
@@ -17,9 +17,9 @@ class IODDAttachPropertyFromTargetToSource(AttachPropertyFromTargetToSource):
17
17
  def __init__(self):
18
18
  super().__init__(
19
19
  target_node_type=IODD.TextObject,
20
- namespace=IODD,
21
- target_property="value",
20
+ target_property=IODD.value,
22
21
  delete_target_node=True,
22
+ namespace=IODD,
23
23
  )
24
24
 
25
25
 
@@ -1,6 +1,9 @@
1
+ from typing import cast
2
+
1
3
  from rdflib import Graph, Namespace, URIRef
2
- from rdflib.query import ResultRow
3
4
 
5
+ from cognite.neat._constants import DEFAULT_NAMESPACE
6
+ from cognite.neat._shared import Triple
4
7
  from cognite.neat._utils.rdf_ import as_neat_compliant_uri
5
8
  from cognite.neat._utils.text import sentence_or_string_to_camel
6
9
 
@@ -55,12 +58,13 @@ class AttachPropertyFromTargetToSource(BaseTransformer):
55
58
 
56
59
  Args:
57
60
  target_node_type: RDF.type of edge Node
58
- namespace: RDF Namespace to use when querying the graph
59
- target_property: str with name of the property that holds the value attached to the intermediate node
60
- target_property_holding_new_property_name: Optional str of the property name that holds
61
- the new predicate to use when attaching the new property to the source node.
61
+ target_property: URIRef of the property that holds the value attached to the intermediate node
62
+ target_property_holding_new_property: URIRef of the property which value will be new
63
+ property that will be added to the source node
62
64
  delete_target_node: bool if the intermediate Node and Edge between source Node
63
65
  and target property should be deleted. Defaults to False.
66
+ convert_literal_to_uri: bool if the value of the new property should be converted to URIRef. Defaults to False.
67
+ namespace: Namespace to use when converting value to URIRef. Defaults to DEFAULT_NAMESPACE.
64
68
  """
65
69
 
66
70
  description: str = "Attaches a target property from a target node that is connected to a source node."
@@ -82,25 +86,26 @@ class AttachPropertyFromTargetToSource(BaseTransformer):
82
86
  def __init__(
83
87
  self,
84
88
  target_node_type: URIRef,
85
- namespace: Namespace,
86
- target_property: str,
87
- target_property_holding_new_property_name: str | None = None,
89
+ target_property: URIRef,
90
+ target_property_holding_new_property: URIRef | None = None,
88
91
  delete_target_node: bool = False,
92
+ convert_literal_to_uri: bool = False,
93
+ namespace: Namespace | None = None,
89
94
  ):
90
95
  self.target_node_type = target_node_type
91
- self.namespace = namespace
92
- self.target_property = self.namespace[target_property]
96
+ self.target_property = target_property
93
97
  self.delete_target_node = delete_target_node
94
- self.target_property_holding_new_property_name = target_property_holding_new_property_name
98
+ self.target_property_holding_new_property = target_property_holding_new_property
99
+ self.convert_literal_to_uri = convert_literal_to_uri
100
+ self.namespace = namespace or DEFAULT_NAMESPACE
95
101
 
96
102
  def transform(self, graph) -> None:
97
103
  nodes_to_delete: list[tuple] = []
98
104
 
99
- if self.target_property_holding_new_property_name is not None:
100
- target_property_holding_new_property_name = self.namespace[self.target_property_holding_new_property_name]
105
+ if self.target_property_holding_new_property is not None:
101
106
  query = self._query_template_use_case_b.format(
102
107
  target_node_type=self.target_node_type,
103
- target_property_holding_new_property_name=target_property_holding_new_property_name,
108
+ target_property_holding_new_property_name=self.target_property_holding_new_property,
104
109
  target_property=self.target_property,
105
110
  )
106
111
  else:
@@ -116,15 +121,20 @@ class AttachPropertyFromTargetToSource(BaseTransformer):
116
121
  new_predicate_value,
117
122
  new_property_value,
118
123
  ) in graph.query(query):
119
- if self.target_property_holding_new_property_name is not None:
124
+ if self.target_property_holding_new_property is not None:
120
125
  # Ensure new predicate is URI compliant as we are creating a new predicate
121
126
  new_predicate_value_string = sentence_or_string_to_camel(str(new_predicate_value))
122
127
  predicate = as_neat_compliant_uri(self.namespace[new_predicate_value_string])
123
128
  else:
124
129
  predicate = old_predicate
125
-
126
130
  # Create new connection from source node to value
127
- graph.add((source_node, predicate, new_property_value))
131
+ graph.add(
132
+ (
133
+ source_node,
134
+ predicate,
135
+ (self.namespace[new_property_value] if self.convert_literal_to_uri else new_property_value),
136
+ )
137
+ )
128
138
  # Remove old relationship between source node and destination node
129
139
  graph.remove((source_node, old_predicate, target_node))
130
140
 
@@ -158,7 +168,7 @@ class PruneDanglingNodes(BaseTransformer):
158
168
  node_prune_types: list of RDF types to prune from the Graph if they are stand-alone Nodes
159
169
  """
160
170
 
161
- description: str = "Prunes the graph of specified rdf types that do not have connections to other nodes."
171
+ description: str = "Prunes nodes of specific rdf types that do not have any connection to them."
162
172
  _query_template = """
163
173
  SELECT ?subject
164
174
  WHERE {{
@@ -174,10 +184,74 @@ class PruneDanglingNodes(BaseTransformer):
174
184
  self.node_prune_types = node_prune_types
175
185
 
176
186
  def transform(self, graph: Graph) -> None:
177
- for object_type in self.node_prune_types:
178
- nodes_without_neighbours = list(graph.query(self._query_template.format(rdf_type=object_type)))
187
+ for type_ in self.node_prune_types:
188
+ for (subject,) in list(graph.query(self._query_template.format(rdf_type=type_))): # type: ignore
189
+ graph.remove((subject, None, None))
190
+
191
+
192
+ class PruneTypes(BaseTransformer):
193
+ """
194
+ Removes all the instances of specific type
195
+ """
196
+
197
+ description: str = "Prunes nodes of specific rdf types"
198
+ _query_template = """
199
+ SELECT ?subject
200
+ WHERE {{
201
+ ?subject a <{rdf_type}> .
202
+ }}
203
+ """
204
+
205
+ def __init__(
206
+ self,
207
+ node_prune_types: list[URIRef],
208
+ ):
209
+ self.node_prune_types = node_prune_types
210
+
211
+ def transform(self, graph: Graph) -> None:
212
+ for type_ in self.node_prune_types:
213
+ for (subject,) in list(graph.query(self._query_template.format(rdf_type=type_))): # type: ignore
214
+ graph.remove((subject, None, None))
179
215
 
180
- for node in nodes_without_neighbours:
181
- # Remove node and its property triples in the graph
182
- if isinstance(node, ResultRow):
183
- graph.remove((node["subject"], None, None))
216
+
217
+ class PruneDeadEndEdges(BaseTransformer):
218
+ """
219
+ Removes all the triples where object is a node that is not found in graph
220
+ """
221
+
222
+ description: str = "Prunes the graph of specified rdf types that do not have connections to other nodes."
223
+ _query_template = """
224
+ SELECT ?subject ?predicate ?object
225
+ WHERE {
226
+ ?subject ?predicate ?object .
227
+ FILTER (isIRI(?object) && ?predicate != rdf:type)
228
+ FILTER NOT EXISTS {?object ?p ?o .}
229
+
230
+ }
231
+
232
+ """
233
+
234
+ def transform(self, graph: Graph) -> None:
235
+ for triple in graph.query(self._query_template):
236
+ graph.remove(cast(Triple, triple))
237
+
238
+
239
+ class PruneInstancesOfUnknownType(BaseTransformer):
240
+ """
241
+ Removes all the triples where object is a node that is not found in graph
242
+ """
243
+
244
+ description: str = "Prunes the graph of specified rdf types that do not have connections to other nodes."
245
+ _query_template = """
246
+ SELECT DISTINCT ?subject
247
+ WHERE {
248
+ ?subject ?p ?o .
249
+ FILTER NOT EXISTS {?subject a ?object .}
250
+
251
+ }
252
+
253
+ """
254
+
255
+ def transform(self, graph: Graph) -> None:
256
+ for (subject,) in graph.query(self._query_template): # type: ignore
257
+ graph.remove((subject, None, None))
@@ -34,8 +34,6 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
34
34
  Args:
35
35
  styling: The styling to use for the Excel file. Defaults to "default". See below for details
36
36
  on the different styles.
37
- output_role: The role to use for the exported spreadsheet. If provided, the rules will be converted to
38
- this role formate before being written to excel. If not provided, the role from the rules will be used.
39
37
  new_model_id: The new model ID to use for the exported spreadsheet. This is only applicable if the input
40
38
  rules have 'is_reference' set. If provided, the model ID will be used to automatically create the
41
39
  new metadata sheet in the Excel file. The model id is expected to be a tuple of (prefix, title)
@@ -120,6 +118,10 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
120
118
  main_header = self._main_header_by_sheet_name[sheet_name]
121
119
  sheet.append([main_header] + [""] * (len(headers) - 1))
122
120
  sheet.merge_cells(start_row=1, start_column=1, end_row=1, end_column=len(headers))
121
+ if headers[0] == "Neat ID":
122
+ # Move the Neat ID to the end of the columns
123
+ headers = headers[1:] + ["Neat ID"]
124
+
123
125
  sheet.append(headers)
124
126
 
125
127
  fill_colors = itertools.cycle(["CADCFC", "FFFFFF"])
@@ -127,6 +129,9 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
127
129
  last_class: str | None = None
128
130
  item: dict[str, Any]
129
131
  for item in dumped_rules.get(sheet_name) or []:
132
+ if "Neat ID" in item:
133
+ # Move the Neat ID to the end of the columns
134
+ item["Neat ID"] = item.pop("Neat ID")
130
135
  row = list(item.values())
131
136
  class_ = row[0]
132
137
 
@@ -1,4 +1,4 @@
1
- from collections import Counter
1
+ from collections import Counter, defaultdict
2
2
  from collections.abc import Collection, Iterable, Sequence
3
3
  from datetime import datetime, timezone
4
4
  from pathlib import Path
@@ -222,12 +222,18 @@ class DMSImporter(BaseImporter[DMSInputRules]):
222
222
  schema: DMSSchema,
223
223
  metadata: DMSInputMetadata | None = None,
224
224
  ) -> DMSInputRules:
225
+ enum_by_container_property = self._create_enum_collections(schema.containers.values())
226
+ enum_collection_by_container_property = {
227
+ key: enum_list[0].collection for key, enum_list in enum_by_container_property.items() if enum_list
228
+ }
229
+
225
230
  properties: list[DMSInputProperty] = []
226
231
  for view_id, view in schema.views.items():
227
232
  view_entity = ViewEntity.from_id(view_id)
228
- class_entity = view_entity.as_class()
229
233
  for prop_id, prop in (view.properties or {}).items():
230
- dms_property = self._create_dms_property(prop_id, prop, view_entity, class_entity)
234
+ dms_property = self._create_dms_property(
235
+ prop_id, prop, view_entity, enum_collection_by_container_property
236
+ )
231
237
  if dms_property is not None:
232
238
  properties.append(dms_property)
233
239
 
@@ -237,8 +243,6 @@ class DMSImporter(BaseImporter[DMSInputRules]):
237
243
 
238
244
  metadata = metadata or DMSInputMetadata.from_data_model(data_model)
239
245
 
240
- enum = self._create_enum_collections(schema.containers.values())
241
-
242
246
  return DMSInputRules(
243
247
  metadata=metadata,
244
248
  properties=properties,
@@ -248,7 +252,7 @@ class DMSImporter(BaseImporter[DMSInputRules]):
248
252
  for view_id, view in schema.views.items()
249
253
  ],
250
254
  nodes=[DMSInputNode.from_node_type(node_type) for node_type in schema.node_types.values()],
251
- enum=enum,
255
+ enum=[enum for enum_list in enum_by_container_property.values() for enum in enum_list] or None,
252
256
  )
253
257
 
254
258
  @classmethod
@@ -267,7 +271,11 @@ class DMSImporter(BaseImporter[DMSInputRules]):
267
271
  )
268
272
 
269
273
  def _create_dms_property(
270
- self, prop_id: str, prop: ViewPropertyApply, view_entity: ViewEntity, class_entity: ClassEntity
274
+ self,
275
+ prop_id: str,
276
+ prop: ViewPropertyApply,
277
+ view_entity: ViewEntity,
278
+ enum_collection_by_container_property: dict[tuple[dm.ContainerId, str], str],
271
279
  ) -> DMSInputProperty | None:
272
280
  if isinstance(prop, dm.MappedPropertyApply) and prop.container not in self._all_containers_by_id:
273
281
  self.issue_list.append(
@@ -300,7 +308,7 @@ class DMSImporter(BaseImporter[DMSInputRules]):
300
308
  )
301
309
  return None
302
310
 
303
- value_type = self._get_value_type(prop, view_entity, prop_id)
311
+ value_type = self._get_value_type(prop, view_entity, prop_id, enum_collection_by_container_property)
304
312
  if value_type is None:
305
313
  return None
306
314
 
@@ -347,7 +355,11 @@ class DMSImporter(BaseImporter[DMSInputRules]):
347
355
  return None
348
356
 
349
357
  def _get_value_type(
350
- self, prop: ViewPropertyApply, view_entity: ViewEntity, prop_id
358
+ self,
359
+ prop: ViewPropertyApply,
360
+ view_entity: ViewEntity,
361
+ prop_id: str,
362
+ enum_collection_by_container_property: dict[tuple[dm.ContainerId, str], str],
351
363
  ) -> DataType | ViewEntity | DMSUnknownEntity | None:
352
364
  if isinstance(
353
365
  prop,
@@ -367,7 +379,16 @@ class DMSImporter(BaseImporter[DMSInputRules]):
367
379
  elif isinstance(container_prop.type, PropertyTypeWithUnit) and container_prop.type.unit:
368
380
  return DataType.load(f"{container_prop.type._type}(unit={container_prop.type.unit.external_id})")
369
381
  elif isinstance(container_prop.type, DMSEnum):
370
- return Enum(collection=ClassEntity(suffix=prop_id), unknownValue=container_prop.type.unknown_value)
382
+ collection = enum_collection_by_container_property.get(
383
+ (prop.container, prop.container_property_identifier)
384
+ )
385
+ if collection is None:
386
+ # This should never happen
387
+ raise ValueError(
388
+ f"BUG in Neat: Enum for {prop.container}.{prop.container_property_identifier} not found."
389
+ )
390
+
391
+ return Enum(collection=ClassEntity(suffix=collection), unknownValue=container_prop.type.unknown_value)
371
392
  else:
372
393
  return DataType.load(container_prop.type._type)
373
394
  else:
@@ -477,15 +498,26 @@ class DMSImporter(BaseImporter[DMSInputRules]):
477
498
  return candidates[0]
478
499
 
479
500
  @staticmethod
480
- def _create_enum_collections(containers: Collection[dm.ContainerApply]) -> list[DMSInputEnum] | None:
481
- enum_collections: list[DMSInputEnum] = []
501
+ def _create_enum_collections(
502
+ containers: Collection[dm.ContainerApply],
503
+ ) -> dict[tuple[dm.ContainerId, str], list[DMSInputEnum]]:
504
+ enum_by_container_property: dict[tuple[dm.ContainerId, str], list[DMSInputEnum]] = defaultdict(list)
505
+
506
+ is_external_id_unique = len({container.external_id for container in containers}) == len(containers)
507
+
482
508
  for container in containers:
509
+ container_id = container.as_id()
483
510
  for prop_id, prop in container.properties.items():
484
- if isinstance(prop.type, DMSEnum):
485
- for identifier, value in prop.type.values.items():
486
- enum_collections.append(
487
- DMSInputEnum(
488
- collection=prop_id, value=identifier, name=value.name, description=value.description
489
- )
511
+ if not isinstance(prop.type, DMSEnum):
512
+ continue
513
+ if is_external_id_unique:
514
+ collection = f"{container.external_id}.{prop_id}"
515
+ else:
516
+ collection = f"{container.space}:{container.external_id}.{prop_id}"
517
+ for identifier, value in prop.type.values.items():
518
+ enum_by_container_property[(container_id, prop_id)].append(
519
+ DMSInputEnum(
520
+ collection=collection, value=identifier, name=value.name, description=value.description
490
521
  )
491
- return enum_collections
522
+ )
523
+ return enum_by_container_property
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
  from cognite.client import data_modeling as dm
5
5
  from rdflib import Graph, Namespace, URIRef
6
6
 
7
- from cognite.neat._constants import get_default_prefixes
7
+ from cognite.neat._constants import get_default_prefixes_and_namespaces
8
8
  from cognite.neat._issues import IssueList
9
9
  from cognite.neat._issues.errors import FileReadError
10
10
  from cognite.neat._issues.errors._general import NeatValueError
@@ -97,7 +97,7 @@ class BaseRDFImporter(BaseImporter[InformationInputRules]):
97
97
  issue_list.append(FileReadError(filepath, str(e)))
98
98
 
99
99
  # bind key namespaces
100
- for prefix, namespace in get_default_prefixes().items():
100
+ for prefix, namespace in get_default_prefixes_and_namespaces().items():
101
101
  graph.bind(prefix, namespace)
102
102
 
103
103
  return cls(
@@ -7,7 +7,7 @@ from pydantic import Field, field_serializer, field_validator, model_validator
7
7
  from pydantic_core.core_schema import SerializationInfo
8
8
  from rdflib import Namespace, URIRef
9
9
 
10
- from cognite.neat._constants import get_default_prefixes
10
+ from cognite.neat._constants import get_default_prefixes_and_namespaces
11
11
  from cognite.neat._issues.errors import NeatValueError, PropertyDefinitionError
12
12
  from cognite.neat._rules._constants import EntityTypes
13
13
  from cognite.neat._rules.models._base_rules import (
@@ -255,7 +255,7 @@ class InformationRules(BaseRules):
255
255
  classes: SheetList[InformationClass] = Field(alias="Classes", description="List of classes")
256
256
  prefixes: dict[str, Namespace] = Field(
257
257
  alias="Prefixes",
258
- default_factory=get_default_prefixes,
258
+ default_factory=get_default_prefixes_and_namespaces,
259
259
  description="the definition of the prefixes that are used in the semantic data model",
260
260
  )
261
261
 
@@ -264,7 +264,7 @@ class InformationRules(BaseRules):
264
264
  if isinstance(values, dict):
265
265
  return {key: Namespace(value) if isinstance(value, str) else value for key, value in values.items()}
266
266
  elif values is None:
267
- values = get_default_prefixes()
267
+ values = get_default_prefixes_and_namespaces()
268
268
  return values
269
269
 
270
270
  def as_dms_rules(self) -> "DMSRules":
@@ -7,8 +7,18 @@ from cognite.client.data_classes.data_modeling import DataModelIdentifier
7
7
  from rdflib import URIRef
8
8
 
9
9
  from cognite.neat._client import NeatClient
10
- from cognite.neat._constants import DEFAULT_NAMESPACE
11
- from cognite.neat._graph.transformers import RelationshipAsEdgeTransformer
10
+ from cognite.neat._constants import (
11
+ DEFAULT_NAMESPACE,
12
+ get_default_prefixes_and_namespaces,
13
+ )
14
+ from cognite.neat._graph.transformers import (
15
+ AttachPropertyFromTargetToSource,
16
+ PruneDeadEndEdges,
17
+ PruneInstancesOfUnknownType,
18
+ PruneTypes,
19
+ RelationshipAsEdgeTransformer,
20
+ Transformers,
21
+ )
12
22
  from cognite.neat._graph.transformers._rdfpath import MakeConnectionOnExactMatch
13
23
  from cognite.neat._rules._shared import InputRules, ReadRules
14
24
  from cognite.neat._rules.importers import DMSImporter
@@ -50,6 +60,79 @@ class InstancePrepareAPI:
50
60
  self._state = state
51
61
  self._verbose = verbose
52
62
 
63
+ def dexpi(self) -> None:
64
+ """Prepares extracted DEXPI graph for further usage in CDF
65
+
66
+ This method bundles several graph transformers which:
67
+ - attach values of generic attributes to nodes
68
+ - create associations between nodes
69
+ - remove unused generic attributes
70
+ - remove associations between nodes that do not exist in the extracted graph
71
+ - remove edges to nodes that do not exist in the extracted graph
72
+
73
+ and therefore safeguard CDF from a bad graph
74
+ """
75
+
76
+ DEXPI = get_default_prefixes_and_namespaces()["dexpi"]
77
+
78
+ transformers = [
79
+ # Remove any instance which type is unknown
80
+ PruneInstancesOfUnknownType(),
81
+ # Directly connect generic attributes
82
+ AttachPropertyFromTargetToSource(
83
+ target_property=DEXPI.Value,
84
+ target_property_holding_new_property=DEXPI.Name,
85
+ target_node_type=DEXPI.GenericAttribute,
86
+ delete_target_node=True,
87
+ ),
88
+ # Directly connect associations
89
+ AttachPropertyFromTargetToSource(
90
+ target_property=DEXPI.ItemID,
91
+ target_property_holding_new_property=DEXPI.Type,
92
+ target_node_type=DEXPI.Association,
93
+ delete_target_node=True,
94
+ ),
95
+ # Remove unused generic attributes and associations
96
+ PruneTypes([DEXPI.GenericAttribute, DEXPI.Association]),
97
+ # Remove edges to nodes that do not exist in the extracted graph
98
+ PruneDeadEndEdges(),
99
+ ]
100
+
101
+ for transformer in transformers:
102
+ self._state.instances.store.transform(cast(Transformers, transformer))
103
+
104
+ def aml(self) -> None:
105
+ """Prepares extracted AutomationML graph for further usage in CDF
106
+
107
+ This method bundles several graph transformers which:
108
+ - attach values of attributes to nodes
109
+ - remove unused attributes
110
+ - remove edges to nodes that do not exist in the extracted graph
111
+
112
+ and therefore safeguard CDF from a bad graph
113
+ """
114
+
115
+ AML = get_default_prefixes_and_namespaces()["aml"]
116
+
117
+ transformers = [
118
+ # Remove any instance which type is unknown
119
+ PruneInstancesOfUnknownType(),
120
+ # Directly connect generic attributes
121
+ AttachPropertyFromTargetToSource(
122
+ target_property=AML.Value,
123
+ target_property_holding_new_property=AML.Name,
124
+ target_node_type=AML.Attribute,
125
+ delete_target_node=True,
126
+ ),
127
+ # Prune unused attributes
128
+ PruneTypes([AML.Attribute]),
129
+ # # Remove edges to nodes that do not exist in the extracted graph
130
+ PruneDeadEndEdges(),
131
+ ]
132
+
133
+ for transformer in transformers:
134
+ self._state.instances.store.transform(cast(Transformers, transformer))
135
+
53
136
  def make_connection_on_exact_match(
54
137
  self,
55
138
  source: tuple[str, str],