cognite-neat 0.75.9__tar.gz → 0.76.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.75.9 → cognite_neat-0.76.0}/PKG-INFO +1 -1
  2. cognite_neat-0.76.0/cognite/neat/_version.py +1 -0
  3. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_models.py +3 -0
  4. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_rules2dms.py +46 -4
  5. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_rules2excel.py +0 -9
  6. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_base.py +6 -0
  7. cognite_neat-0.76.0/cognite/neat/rules/importers/_dms2rules.py +410 -0
  8. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_spreadsheet2rules.py +14 -8
  9. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/base.py +3 -0
  10. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/dms.py +142 -54
  11. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/fileread.py +41 -0
  12. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/importing.py +155 -0
  13. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/spreadsheet.py +12 -9
  14. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/entities.py +29 -6
  15. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_base.py +5 -6
  16. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_dms_architect_rules.py +492 -332
  17. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_dms_rules_write.py +32 -30
  18. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_dms_schema.py +112 -22
  19. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_domain_rules.py +5 -0
  20. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_information_rules.py +13 -6
  21. cognite_neat-0.76.0/cognite/neat/rules/models/wrapped_entities.py +166 -0
  22. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/pyproject.toml +1 -1
  23. cognite_neat-0.75.9/cognite/neat/_version.py +0 -1
  24. cognite_neat-0.75.9/cognite/neat/rules/importers/_dms2rules.py +0 -216
  25. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/LICENSE +0 -0
  26. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/README.md +0 -0
  27. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/__init__.py +0 -0
  28. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/__init__.py +0 -0
  29. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/asgi/metrics.py +0 -0
  30. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/configuration.py +0 -0
  31. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/context_manager/__init__.py +0 -0
  32. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/context_manager/manager.py +0 -0
  33. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/data_classes/__init__.py +0 -0
  34. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/data_classes/rest.py +0 -0
  35. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/explorer.py +0 -0
  36. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/configuration.py +0 -0
  37. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/core.py +0 -0
  38. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/crud.py +0 -0
  39. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/data_exploration.py +0 -0
  40. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/metrics.py +0 -0
  41. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/rules.py +0 -0
  42. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/workflows.py +0 -0
  43. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/utils/__init__.py +0 -0
  44. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/utils/data_mapping.py +0 -0
  45. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/utils/logging.py +0 -0
  46. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/utils/query_templates.py +0 -0
  47. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/main.py +0 -0
  48. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/monitoring/__init__.py +0 -0
  49. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/monitoring/metrics.py +0 -0
  50. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/index.html +0 -0
  51. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/.gitignore +0 -0
  52. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/README.md +0 -0
  53. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/asset-manifest.json +0 -0
  54. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/favicon.ico +0 -0
  55. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/img/architect-icon.svg +0 -0
  56. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/img/developer-icon.svg +0 -0
  57. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/img/sme-icon.svg +0 -0
  58. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/index.html +0 -0
  59. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/logo192.png +0 -0
  60. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/manifest.json +0 -0
  61. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/robots.txt +0 -0
  62. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/css/main.38a62222.css +0 -0
  63. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/css/main.38a62222.css.map +0 -0
  64. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js +0 -0
  65. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js.LICENSE.txt +0 -0
  66. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js.map +0 -0
  67. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -0
  68. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/config.py +0 -0
  69. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/constants.py +0 -0
  70. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/exceptions.py +0 -0
  71. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/__init__.py +0 -0
  72. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  73. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/examples/Knowledge-Graph-Nordic44.xml +0 -0
  74. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/examples/__init__.py +0 -0
  75. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  76. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/exceptions.py +0 -0
  77. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/extractors/__init__.py +0 -0
  78. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/extractors/_base.py +0 -0
  79. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/extractors/_mock_graph_generator.py +0 -0
  80. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/models.py +0 -0
  81. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/__init__.py +0 -0
  82. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_base.py +0 -0
  83. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_graphdb_store.py +0 -0
  84. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_memory_store.py +0 -0
  85. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_oxigraph_store.py +0 -0
  86. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_oxrdflib.py +0 -0
  87. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_rdf_to_graph.py +0 -0
  88. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/__init__.py +0 -0
  89. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/__init__.py +0 -0
  90. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  91. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44.xml +0 -0
  92. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/examples/__init__.py +0 -0
  93. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  94. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/exceptions.py +0 -0
  95. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/__init__.py +0 -0
  96. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/_base.py +0 -0
  97. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/_dexpi.py +0 -0
  98. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/_graph_capturing_sheet.py +0 -0
  99. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/_mock_graph_generator.py +0 -0
  100. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/__init__.py +0 -0
  101. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/_asset_loader.py +0 -0
  102. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/_base.py +0 -0
  103. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/_exceptions.py +0 -0
  104. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/__init__.py +0 -0
  105. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/labels.py +0 -0
  106. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/models.py +0 -0
  107. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/rdf_to_assets.py +0 -0
  108. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/rdf_to_relationships.py +0 -0
  109. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/rdf_to_dms.py +0 -0
  110. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/validator.py +0 -0
  111. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/models.py +0 -0
  112. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/__init__.py +0 -0
  113. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_base.py +0 -0
  114. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_graphdb_store.py +0 -0
  115. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_memory_store.py +0 -0
  116. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_oxigraph_store.py +0 -0
  117. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_oxrdflib.py +0 -0
  118. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_rdf_to_graph.py +0 -0
  119. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/__init__.py +0 -0
  120. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/entity_matcher.py +0 -0
  121. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/query_generator/__init__.py +0 -0
  122. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/query_generator/sparql.py +0 -0
  123. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/transformer.py +0 -0
  124. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/__init__.py +0 -0
  125. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/analysis.py +0 -0
  126. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/Rules-Nordic44-to-TNT.xlsx +0 -0
  127. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/Rules-Nordic44-to-graphql.xlsx +0 -0
  128. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/__init__.py +0 -0
  129. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/power-grid-containers.yaml +0 -0
  130. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/power-grid-example.xlsx +0 -0
  131. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/power-grid-model.yaml +0 -0
  132. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/rules-template.xlsx +0 -0
  133. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/sheet2cdf-transformation-rules.xlsx +0 -0
  134. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/skos-rules.xlsx +0 -0
  135. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/source-to-solution-mapping-rules.xlsx +0 -0
  136. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/wind-energy.owl +0 -0
  137. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exceptions.py +0 -0
  138. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/__init__.py +0 -0
  139. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_base.py +0 -0
  140. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_core/__init__.py +0 -0
  141. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_core/rules2labels.py +0 -0
  142. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2dms.py +0 -0
  143. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2excel.py +0 -0
  144. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2graphql.py +0 -0
  145. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2ontology.py +0 -0
  146. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2pydantic_models.py +0 -0
  147. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2rules.py +0 -0
  148. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2triples.py +0 -0
  149. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_validation.py +0 -0
  150. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/__init__.py +0 -0
  151. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_base.py +0 -0
  152. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_dict2rules.py +0 -0
  153. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_dms2rules.py +0 -0
  154. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_graph2rules.py +0 -0
  155. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_json2rules.py +0 -0
  156. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/__init__.py +0 -0
  157. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/_owl2classes.py +0 -0
  158. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/_owl2metadata.py +0 -0
  159. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/_owl2properties.py +0 -0
  160. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/_owl2rules.py +0 -0
  161. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_spreadsheet2rules.py +0 -0
  162. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_xsd2rules.py +0 -0
  163. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_yaml2rules.py +0 -0
  164. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/__init__.py +0 -0
  165. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/_base.py +0 -0
  166. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/raw_rules.py +0 -0
  167. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/rdfpath.py +0 -0
  168. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/rules.py +0 -0
  169. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/tables.py +0 -0
  170. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/value_types.py +0 -0
  171. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Export_DMS/workflow.yaml +0 -0
  172. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Export_Rules_to_Ontology/workflow.yaml +0 -0
  173. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml +0 -0
  174. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -0
  175. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Import_DMS/workflow.yaml +0 -0
  176. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Ontology_to_Data_Model/workflow.yaml +0 -0
  177. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Validate_Rules/workflow.yaml +0 -0
  178. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Validate_Solution_Model/workflow.yaml +0 -0
  179. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Visualize_Data_Model_Using_Mock_Graph/workflow.yaml +0 -0
  180. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Visualize_Semantic_Data_Model/workflow.yaml +0 -0
  181. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/py.typed +0 -0
  182. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/__init__.py +0 -0
  183. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/_shared.py +0 -0
  184. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/analysis/__init__.py +0 -0
  185. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/analysis/_base.py +0 -0
  186. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/analysis/_information_rules.py +0 -0
  187. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/examples/__init__.py +0 -0
  188. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/examples/wind-energy.owl +0 -0
  189. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exceptions.py +0 -0
  190. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/__init__.py +0 -0
  191. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_base.py +0 -0
  192. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_rules2ontology.py +0 -0
  193. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_rules2yaml.py +0 -0
  194. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_validation.py +0 -0
  195. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/__init__.py +0 -0
  196. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/__init__.py +0 -0
  197. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/_unit_lookup.py +0 -0
  198. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py +0 -0
  199. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py +0 -0
  200. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/spec.py +0 -0
  201. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/__init__.py +0 -0
  202. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/_owl2classes.py +0 -0
  203. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/_owl2metadata.py +0 -0
  204. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/_owl2properties.py +0 -0
  205. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/_owl2rules.py +0 -0
  206. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_yaml2rules.py +0 -0
  207. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/__init__.py +0 -0
  208. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/formatters.py +0 -0
  209. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/spreadsheet_file.py +0 -0
  210. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/data_types.py +0 -0
  211. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rdfpath.py +0 -0
  212. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/__init__.py +0 -0
  213. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_types/__init__.py +0 -0
  214. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_types/_base.py +0 -0
  215. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_types/_field.py +0 -0
  216. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/__init__.py +0 -0
  217. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/auxiliary.py +0 -0
  218. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf.py +0 -0
  219. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/__init__.py +0 -0
  220. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/_base.py +0 -0
  221. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/_data_modeling.py +0 -0
  222. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/_ingestion.py +0 -0
  223. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/data_classes.py +0 -0
  224. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/exceptions.py +0 -0
  225. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/spreadsheet.py +0 -0
  226. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/text.py +0 -0
  227. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/utils.py +0 -0
  228. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/xml.py +0 -0
  229. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/__init__.py +0 -0
  230. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/_exceptions.py +0 -0
  231. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/base.py +0 -0
  232. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/cdf_store.py +0 -0
  233. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Export_DMS/workflow.yaml +0 -0
  234. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Export_Rules_to_Ontology/workflow.yaml +0 -0
  235. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml +0 -0
  236. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -0
  237. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Import_DMS/workflow.yaml +0 -0
  238. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Ontology_to_Data_Model/workflow.yaml +0 -0
  239. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Validate_Rules/workflow.yaml +0 -0
  240. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Validate_Solution_Model/workflow.yaml +0 -0
  241. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Visualize_Data_Model_Using_Mock_Graph/workflow.yaml +0 -0
  242. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Visualize_Semantic_Data_Model/workflow.yaml +0 -0
  243. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/manager.py +0 -0
  244. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/migration/__init__.py +0 -0
  245. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/migration/steps.py +0 -0
  246. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/migration/wf_manifests.py +0 -0
  247. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/model.py +0 -0
  248. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/__init__.py +0 -0
  249. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/data_contracts.py +0 -0
  250. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/__init__.py +0 -0
  251. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/__init__.py +0 -0
  252. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/graph_extractor.py +0 -0
  253. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/graph_loader.py +0 -0
  254. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/graph_store.py +0 -0
  255. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/rules_exporter.py +0 -0
  256. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/rules_importer.py +0 -0
  257. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/rules_validator.py +0 -0
  258. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/io/__init__.py +0 -0
  259. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/io/io_steps.py +0 -0
  260. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/__init__.py +0 -0
  261. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_contextualization.py +0 -0
  262. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_extractor.py +0 -0
  263. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_loader.py +0 -0
  264. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_store.py +0 -0
  265. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_transformer.py +0 -0
  266. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/rules_exporter.py +0 -0
  267. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/rules_importer.py +0 -0
  268. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/step_model.py +0 -0
  269. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps_registry.py +0 -0
  270. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/tasks.py +0 -0
  271. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/triggers.py +0 -0
  272. {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cognite-neat
3
- Version: 0.75.9
3
+ Version: 0.76.0
4
4
  Summary: Knowledge graph transformation
5
5
  Home-page: https://cognite-neat.readthedocs-hosted.com/
6
6
  License: Apache-2.0
@@ -0,0 +1 @@
1
+ __version__ = "0.76.0"
@@ -2,6 +2,8 @@ from abc import ABC
2
2
  from dataclasses import dataclass, field
3
3
  from functools import total_ordering
4
4
 
5
+ from cognite.neat.rules.issues import IssueList
6
+
5
7
 
6
8
  @total_ordering
7
9
  @dataclass
@@ -32,6 +34,7 @@ class UploadResult(UploadResultCore):
32
34
  failed_changed: int = 0
33
35
  failed_deleted: int = 0
34
36
  error_messages: list[str] = field(default_factory=list)
37
+ issues: IssueList = field(default_factory=IssueList)
35
38
 
36
39
  @property
37
40
  def total(self) -> int:
@@ -4,10 +4,13 @@ from pathlib import Path
4
4
  from typing import Literal, TypeAlias, cast
5
5
 
6
6
  from cognite.client import CogniteClient
7
- from cognite.client.data_classes._base import CogniteResourceList
7
+ from cognite.client.data_classes._base import CogniteResource, CogniteResourceList
8
+ from cognite.client.data_classes.data_modeling import DataModelApply, DataModelId
8
9
  from cognite.client.exceptions import CogniteAPIError
9
10
 
11
+ from cognite.neat.rules import issues
10
12
  from cognite.neat.rules._shared import Rules
13
+ from cognite.neat.rules.issues import IssueList
11
14
  from cognite.neat.rules.models.rules import InformationRules
12
15
  from cognite.neat.rules.models.rules._base import ExtensionCategory, SheetList
13
16
  from cognite.neat.rules.models.rules._dms_architect_rules import DMSContainer, DMSRules
@@ -43,6 +46,8 @@ class DMSExporter(CDFExporter[DMSSchema]):
43
46
  export_pipeline (bool, optional): Whether to export the pipeline. Defaults to False. This means setting
44
47
  up transformations, RAW databases and tables to populate the data model.
45
48
  instance_space (str, optional): The space to use for the instance. Defaults to None.
49
+ suppress_warnings (bool, optional): Suppress warnings. Defaults to False.
50
+
46
51
  ... note::
47
52
 
48
53
  - "fail": If any component already exists, the export will fail.
@@ -59,12 +64,14 @@ class DMSExporter(CDFExporter[DMSSchema]):
59
64
  existing_handling: Literal["fail", "skip", "update", "force"] = "update",
60
65
  export_pipeline: bool = False,
61
66
  instance_space: str | None = None,
67
+ suppress_warnings: bool = False,
62
68
  ):
63
69
  self.export_components = {export_components} if isinstance(export_components, str) else set(export_components)
64
70
  self.include_space = include_space
65
71
  self.existing_handling = existing_handling
66
72
  self.export_pipeline = export_pipeline
67
73
  self.instance_space = instance_space
74
+ self.suppress_warnings = suppress_warnings
68
75
  self._schema: DMSSchema | None = None
69
76
 
70
77
  def export_to_file(self, rules: Rules, filepath: Path) -> None:
@@ -115,11 +122,11 @@ class DMSExporter(CDFExporter[DMSSchema]):
115
122
  )
116
123
  is_new_model = dms_rules.reference is None
117
124
  if is_new_model or is_solution_model:
118
- return dms_rules.as_schema(self.export_pipeline, self.instance_space)
125
+ return dms_rules.as_schema(False, self.export_pipeline, self.instance_space)
119
126
 
120
127
  # This is an extension of an existing model.
121
128
  reference_rules = cast(DMSRules, dms_rules.reference).model_copy(deep=True)
122
- reference_schema = reference_rules.as_schema(self.export_pipeline)
129
+ reference_schema = reference_rules.as_schema(include_ref=False, include_pipeline=self.export_pipeline)
123
130
 
124
131
  # Todo Move this to an appropriate location
125
132
  # Merging Reference with User Rules
@@ -142,7 +149,7 @@ class DMSExporter(CDFExporter[DMSSchema]):
142
149
  property_.reference = None
143
150
  combined_rules.properties.append(property_)
144
151
 
145
- schema = combined_rules.as_schema(self.export_pipeline, self.instance_space)
152
+ schema = combined_rules.as_schema(True, self.export_pipeline, self.instance_space)
146
153
 
147
154
  if dms_rules.metadata.extension in (ExtensionCategory.addition, ExtensionCategory.reshape):
148
155
  # We do not freeze views as they might be changed, even for addition,
@@ -206,6 +213,7 @@ class DMSExporter(CDFExporter[DMSSchema]):
206
213
  redeploy_data_model = False
207
214
 
208
215
  for all_items, loader in to_export:
216
+ issue_list = IssueList()
209
217
  all_item_ids = loader.get_ids(all_items)
210
218
  skipped = sum(1 for item_id in all_item_ids if item_id in schema.frozen_ids)
211
219
  item_ids = [item_id for item_id in all_item_ids if item_id not in schema.frozen_ids]
@@ -249,6 +257,9 @@ class DMSExporter(CDFExporter[DMSSchema]):
249
257
  else:
250
258
  raise ValueError(f"Unsupported existing_handling {self.existing_handling}")
251
259
 
260
+ warning_list = self._validate(loader, items)
261
+ issue_list.extend(warning_list)
262
+
252
263
  error_messages: list[str] = []
253
264
  if not dry_run:
254
265
  if to_delete:
@@ -284,6 +295,7 @@ class DMSExporter(CDFExporter[DMSSchema]):
284
295
  failed_created=failed_created,
285
296
  failed_changed=failed_changed,
286
297
  error_messages=error_messages,
298
+ issues=issue_list,
287
299
  )
288
300
 
289
301
  if loader.resource_name == "views" and (created or changed) and not redeploy_data_model:
@@ -307,3 +319,33 @@ class DMSExporter(CDFExporter[DMSSchema]):
307
319
  to_export.append((schema.raw_tables, RawTableLoader(client)))
308
320
  to_export.append((schema.transformations, TransformationLoader(client)))
309
321
  return schema, to_export
322
+
323
+ def _validate(self, loader: ResourceLoader, items: list[CogniteResource]) -> IssueList:
324
+ issue_list = IssueList()
325
+ if isinstance(loader, DataModelLoader):
326
+ models = cast(list[DataModelApply], items)
327
+ if other_models := self._exist_other_data_models(loader, models):
328
+ warning = issues.dms.OtherDataModelsInSpaceWarning(models[0].space, other_models)
329
+ if not self.suppress_warnings:
330
+ warnings.warn(warning, stacklevel=2)
331
+ issue_list.append(warning)
332
+
333
+ return issue_list
334
+
335
+ @classmethod
336
+ def _exist_other_data_models(cls, loader: DataModelLoader, models: list[DataModelApply]) -> list[DataModelId]:
337
+ if not models:
338
+ return []
339
+ space = models[0].space
340
+ external_id = models[0].external_id
341
+ try:
342
+ data_models = loader.client.data_modeling.data_models.list(space=space, limit=25, all_versions=False)
343
+ except CogniteAPIError as e:
344
+ warnings.warn(issues.importing.APIWarning(str(e)), stacklevel=2)
345
+ return []
346
+ else:
347
+ return [
348
+ data_model.as_id()
349
+ for data_model in data_models
350
+ if (data_model.space, data_model.external_id) != (space, external_id)
351
+ ]
@@ -120,13 +120,6 @@ class ExcelExporter(BaseExporter[Workbook]):
120
120
  else:
121
121
  sheet = workbook.create_sheet(sheet_name)
122
122
 
123
- # Reorder such that the first column is class + the first field of the subclass
124
- # of sheet entity. This is to make the properties/classes/views/containers sheet more readable.
125
- # For example, for the properties these that means class, property, name, description
126
- # instead of class, name, description, property
127
- move = len(SheetEntity.model_fields) - 1 # -1 is for the class field
128
- headers = headers[:1] + headers[move : move + 1] + headers[1:move] + headers[move + 1 :]
129
-
130
123
  main_header = self._main_header_by_sheet_name[sheet_name]
131
124
  sheet.append([main_header] + [""] * (len(headers) - 1))
132
125
  sheet.merge_cells(start_row=1, start_column=1, end_row=1, end_column=len(headers))
@@ -150,8 +143,6 @@ class ExcelExporter(BaseExporter[Workbook]):
150
143
  cell.border = Border(left=side, right=side, top=side, bottom=side)
151
144
  fill_color = next(fill_colors)
152
145
 
153
- # Need to do the same reordering as for the headers above
154
- row = row[:1] + row[move : move + 1] + row[1:move] + row[move + 1 :]
155
146
  sheet.append(row)
156
147
  if self._styling_level > 2 and is_properties:
157
148
  for cell in sheet[sheet.max_row]:
@@ -60,6 +60,12 @@ class BaseImporter(ABC):
60
60
  else:
61
61
  return output, issues
62
62
 
63
+ @classmethod
64
+ def _return_or_raise(cls, issue_list: IssueList, errors: Literal["raise", "continue"]) -> tuple[None, IssueList]:
65
+ if errors == "raise":
66
+ raise issue_list.as_errors()
67
+ return None, issue_list
68
+
63
69
  def _default_metadata(self):
64
70
  return {
65
71
  "prefix": "neat",
@@ -0,0 +1,410 @@
1
+ from collections import Counter
2
+ from collections.abc import Sequence
3
+ from datetime import datetime
4
+ from pathlib import Path
5
+ from typing import Literal, cast, overload
6
+
7
+ from cognite.client import CogniteClient
8
+ from cognite.client import data_modeling as dm
9
+ from cognite.client.data_classes.data_modeling import DataModelIdentifier
10
+ from cognite.client.data_classes.data_modeling.containers import BTreeIndex, InvertedIndex
11
+ from cognite.client.data_classes.data_modeling.views import (
12
+ MultiEdgeConnectionApply,
13
+ MultiReverseDirectRelationApply,
14
+ SingleEdgeConnectionApply,
15
+ SingleReverseDirectRelationApply,
16
+ ViewPropertyApply,
17
+ )
18
+ from cognite.client.utils import ms_to_datetime
19
+
20
+ from cognite.neat.rules import issues
21
+ from cognite.neat.rules.importers._base import BaseImporter, Rules, _handle_issues
22
+ from cognite.neat.rules.issues import IssueList, ValidationIssue
23
+ from cognite.neat.rules.models.data_types import DataType
24
+ from cognite.neat.rules.models.entities import (
25
+ ClassEntity,
26
+ ContainerEntity,
27
+ DataModelEntity,
28
+ DMSUnknownEntity,
29
+ ViewEntity,
30
+ ViewPropertyEntity,
31
+ )
32
+ from cognite.neat.rules.models.rules import DMSRules, DMSSchema, RoleTypes
33
+ from cognite.neat.rules.models.rules._base import DataModelType, ExtensionCategory, SchemaCompleteness
34
+ from cognite.neat.rules.models.rules._dms_architect_rules import (
35
+ DMSContainer,
36
+ DMSMetadata,
37
+ DMSProperty,
38
+ DMSView,
39
+ SheetList,
40
+ )
41
+
42
+
43
+ class DMSImporter(BaseImporter):
44
+ def __init__(
45
+ self,
46
+ schema: DMSSchema,
47
+ read_issues: Sequence[ValidationIssue] | None = None,
48
+ metadata: DMSMetadata | None = None,
49
+ ):
50
+ self.schema = schema
51
+ self.metadata = metadata
52
+ self.issue_list = IssueList(read_issues)
53
+ self._container_by_id = {container.as_id(): container for container in schema.containers}
54
+
55
+ @classmethod
56
+ def from_data_model_id(cls, client: CogniteClient, data_model_id: DataModelIdentifier) -> "DMSImporter":
57
+ """Create a DMSImporter ready to convert the given data model to rules.
58
+
59
+ Args:
60
+ client: Instantiated CogniteClient to retrieve data model.
61
+ data_model_id: Data Model to retrieve.
62
+
63
+ Returns:
64
+ DMSImporter: DMSImporter instance
65
+ """
66
+ data_models = client.data_modeling.data_models.retrieve(data_model_id, inline_views=True)
67
+ if len(data_models) == 0:
68
+ return cls(DMSSchema(), [issues.importing.NoDataModelError(f"Data model {data_model_id} not found")])
69
+ data_model = data_models.latest_version()
70
+
71
+ try:
72
+ schema = DMSSchema.from_data_model(client, data_model)
73
+ except Exception as e:
74
+ return cls(DMSSchema(), [issues.importing.APIError(str(e))])
75
+
76
+ created = ms_to_datetime(data_model.created_time)
77
+ updated = ms_to_datetime(data_model.last_updated_time)
78
+
79
+ metadata = cls._create_metadata_from_model(data_model, created, updated)
80
+
81
+ return cls(schema, [], metadata)
82
+
83
+ @classmethod
84
+ def _create_metadata_from_model(
85
+ cls,
86
+ model: dm.DataModel[dm.View] | dm.DataModelApply,
87
+ created: datetime | None = None,
88
+ updated: datetime | None = None,
89
+ ) -> DMSMetadata:
90
+ description, creator = DMSMetadata._get_description_and_creator(model.description)
91
+ now = datetime.now().replace(microsecond=0)
92
+ return DMSMetadata(
93
+ schema_=SchemaCompleteness.complete,
94
+ extension=ExtensionCategory.addition,
95
+ space=model.space,
96
+ external_id=model.external_id,
97
+ name=model.name or model.external_id,
98
+ version=model.version or "0.1.0",
99
+ updated=updated or now,
100
+ created=created or now,
101
+ creator=creator,
102
+ description=description,
103
+ )
104
+
105
+ @classmethod
106
+ def from_directory(cls, directory: str | Path) -> "DMSImporter":
107
+ issue_list = IssueList()
108
+ with _handle_issues(issue_list) as _:
109
+ schema = DMSSchema.from_directory(directory)
110
+ # If there were errors during the import, the to_rules
111
+ return cls(schema, issue_list)
112
+
113
+ @classmethod
114
+ def from_zip_file(cls, zip_file: str | Path) -> "DMSImporter":
115
+ if Path(zip_file).suffix != ".zip":
116
+ return cls(DMSSchema(), [issues.fileread.InvalidFileFormatError(Path(zip_file), [".zip"])])
117
+ issue_list = IssueList()
118
+ with _handle_issues(issue_list) as _:
119
+ schema = DMSSchema.from_zip(zip_file)
120
+ return cls(schema, issue_list)
121
+
122
+ @overload
123
+ def to_rules(self, errors: Literal["raise"], role: RoleTypes | None = None) -> Rules: ...
124
+
125
+ @overload
126
+ def to_rules(
127
+ self, errors: Literal["continue"] = "continue", role: RoleTypes | None = None
128
+ ) -> tuple[Rules | None, IssueList]: ...
129
+
130
+ def to_rules(
131
+ self, errors: Literal["raise", "continue"] = "continue", role: RoleTypes | None = None
132
+ ) -> tuple[Rules | None, IssueList] | Rules:
133
+ if self.issue_list.has_errors:
134
+ # In case there were errors during the import, the to_rules method will return None
135
+ return self._return_or_raise(self.issue_list, errors)
136
+
137
+ if len(self.schema.data_models) == 0:
138
+ self.issue_list.append(issues.importing.NoDataModelError("No data model found."))
139
+ return self._return_or_raise(self.issue_list, errors)
140
+
141
+ if len(self.schema.data_models) > 2:
142
+ # Creating a DataModelEntity to convert the data model id to a string.
143
+ self.issue_list.append(
144
+ issues.importing.MultipleDataModelsWarning(
145
+ [str(DataModelEntity.from_id(model.as_id())) for model in self.schema.data_models]
146
+ )
147
+ )
148
+
149
+ data_model = self.schema.data_models[0]
150
+
151
+ properties = SheetList[DMSProperty]()
152
+ ref_properties = SheetList[DMSProperty]()
153
+ for view in self.schema.views:
154
+ view_id = view.as_id()
155
+ view_entity = ViewEntity.from_id(view_id)
156
+ class_entity = view_entity.as_class()
157
+ for prop_id, prop in (view.properties or {}).items():
158
+ dms_property = self._create_dms_property(prop_id, prop, view_entity, class_entity)
159
+ if dms_property is not None:
160
+ if view_id in self.schema.frozen_ids:
161
+ ref_properties.append(dms_property)
162
+ else:
163
+ properties.append(dms_property)
164
+
165
+ data_model_view_ids: set[dm.ViewId] = {
166
+ view.as_id() if isinstance(view, dm.View | dm.ViewApply) else view for view in data_model.views or []
167
+ }
168
+
169
+ metadata = self.metadata or DMSMetadata.from_data_model(data_model)
170
+ metadata.data_model_type = self._infer_data_model_type(metadata.space)
171
+ if ref_properties:
172
+ metadata.schema_ = SchemaCompleteness.extended
173
+
174
+ with _handle_issues(
175
+ self.issue_list,
176
+ ) as future:
177
+ user_rules = DMSRules(
178
+ metadata=metadata,
179
+ properties=properties,
180
+ containers=SheetList[DMSContainer](
181
+ data=[
182
+ DMSContainer.from_container(container)
183
+ for container in self.schema.containers
184
+ if container.as_id() not in self.schema.frozen_ids
185
+ ]
186
+ ),
187
+ views=SheetList[DMSView](
188
+ data=[
189
+ DMSView.from_view(view, in_model=view.as_id() in data_model_view_ids)
190
+ for view in self.schema.views
191
+ if view.as_id() not in self.schema.frozen_ids
192
+ ]
193
+ ),
194
+ reference=self._create_reference_rules(ref_properties),
195
+ )
196
+
197
+ if future.result == "failure" or self.issue_list.has_errors:
198
+ return self._return_or_raise(self.issue_list, errors)
199
+
200
+ return self._to_output(user_rules, self.issue_list, errors, role)
201
+
202
+ def _create_reference_rules(self, properties: SheetList[DMSProperty]) -> DMSRules | None:
203
+ if not properties:
204
+ return None
205
+
206
+ if len(self.schema.data_models) == 2:
207
+ data_model = self.schema.data_models[1]
208
+ data_model_view_ids: set[dm.ViewId] = {
209
+ view.as_id() if isinstance(view, dm.View | dm.ViewApply) else view for view in data_model.views or []
210
+ }
211
+ metadata = self._create_metadata_from_model(data_model)
212
+ else:
213
+ data_model_view_ids = set()
214
+ now = datetime.now().replace(microsecond=0)
215
+ space = Counter(prop.view.space for prop in properties).most_common(1)[0][0]
216
+ metadata = DMSMetadata(
217
+ schema_=SchemaCompleteness.complete,
218
+ extension=ExtensionCategory.addition,
219
+ space=space,
220
+ external_id="Unknown",
221
+ version="0.1.0",
222
+ creator=["Unknown"],
223
+ created=now,
224
+ updated=now,
225
+ )
226
+
227
+ metadata.data_model_type = DataModelType.enterprise
228
+ return DMSRules(
229
+ metadata=metadata,
230
+ properties=properties,
231
+ views=SheetList[DMSView](
232
+ data=[
233
+ DMSView.from_view(view, in_model=not data_model_view_ids or (view.as_id() in data_model_view_ids))
234
+ for view in self.schema.views
235
+ if view.as_id() in self.schema.frozen_ids
236
+ ]
237
+ ),
238
+ containers=SheetList[DMSContainer](
239
+ data=[
240
+ DMSContainer.from_container(container)
241
+ for container in self.schema.containers
242
+ if container.as_id() in self.schema.frozen_ids
243
+ ]
244
+ ),
245
+ reference=None,
246
+ )
247
+
248
+ def _infer_data_model_type(self, space: str) -> DataModelType:
249
+ if self.schema.referenced_spaces() - {space}:
250
+ # If the data model has containers, views, node types in another space
251
+ # we assume it is a solution model.
252
+ return DataModelType.solution
253
+ else:
254
+ # All containers, views, node types are in the same space as the data model
255
+ return DataModelType.enterprise
256
+
257
+ def _create_dms_property(
258
+ self, prop_id: str, prop: ViewPropertyApply, view_entity: ViewEntity, class_entity: ClassEntity
259
+ ) -> DMSProperty | None:
260
+ if isinstance(prop, dm.MappedPropertyApply) and prop.container not in self._container_by_id:
261
+ self.issue_list.append(
262
+ issues.importing.MissingContainerWarning(
263
+ view_id=str(view_entity),
264
+ property_=prop_id,
265
+ container_id=str(ContainerEntity.from_id(prop.container)),
266
+ )
267
+ )
268
+ return None
269
+ if (
270
+ isinstance(prop, dm.MappedPropertyApply)
271
+ and prop.container_property_identifier not in self._container_by_id[prop.container].properties
272
+ ):
273
+ self.issue_list.append(
274
+ issues.importing.MissingContainerPropertyWarning(
275
+ view_id=str(view_entity),
276
+ property_=prop_id,
277
+ container_id=str(ContainerEntity.from_id(prop.container)),
278
+ )
279
+ )
280
+ return None
281
+ if not isinstance(
282
+ prop,
283
+ dm.MappedPropertyApply
284
+ | SingleEdgeConnectionApply
285
+ | MultiEdgeConnectionApply
286
+ | SingleReverseDirectRelationApply
287
+ | MultiReverseDirectRelationApply,
288
+ ):
289
+ self.issue_list.append(
290
+ issues.importing.UnknownPropertyTypeWarning(view_entity.versioned_id, prop_id, type(prop).__name__)
291
+ )
292
+ return None
293
+
294
+ value_type = self._get_value_type(prop, view_entity, prop_id)
295
+ if value_type is None:
296
+ return None
297
+
298
+ return DMSProperty(
299
+ class_=class_entity,
300
+ property_=prop_id,
301
+ description=prop.description,
302
+ name=prop.name,
303
+ connection=self._get_relation_type(prop),
304
+ value_type=value_type,
305
+ is_list=self._get_is_list(prop),
306
+ nullable=self._get_nullable(prop),
307
+ default=self._get_default(prop),
308
+ container=ContainerEntity.from_id(prop.container) if isinstance(prop, dm.MappedPropertyApply) else None,
309
+ container_property=prop.container_property_identifier if isinstance(prop, dm.MappedPropertyApply) else None,
310
+ view=view_entity,
311
+ view_property=prop_id,
312
+ index=self._get_index(prop, prop_id),
313
+ constraint=self._get_constraint(prop, prop_id),
314
+ )
315
+
316
+ def _container_prop_unsafe(self, prop: dm.MappedPropertyApply) -> dm.ContainerProperty:
317
+ """This method assumes you have already checked that the container with property exists."""
318
+ return self._container_by_id[prop.container].properties[prop.container_property_identifier]
319
+
320
+ def _get_relation_type(self, prop: ViewPropertyApply) -> Literal["edge", "reverse", "direct"] | None:
321
+ if isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "outwards":
322
+ return "edge"
323
+ elif isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "inwards":
324
+ return "reverse"
325
+ elif isinstance(prop, SingleReverseDirectRelationApply | MultiReverseDirectRelationApply):
326
+ return "reverse"
327
+ elif isinstance(prop, dm.MappedPropertyApply) and isinstance(
328
+ self._container_prop_unsafe(prop).type, dm.DirectRelation
329
+ ):
330
+ return "direct"
331
+ else:
332
+ return None
333
+
334
+ def _get_value_type(
335
+ self, prop: ViewPropertyApply, view_entity: ViewEntity, prop_id
336
+ ) -> DataType | ViewEntity | ViewPropertyEntity | DMSUnknownEntity | None:
337
+ if isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "outwards":
338
+ return ViewEntity.from_id(prop.source)
339
+ elif isinstance(prop, SingleReverseDirectRelationApply | MultiReverseDirectRelationApply):
340
+ return ViewPropertyEntity.from_id(prop.through)
341
+ elif isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "inwards":
342
+ return ViewEntity.from_id(prop.source)
343
+ elif isinstance(prop, dm.MappedPropertyApply):
344
+ container_prop = self._container_prop_unsafe(cast(dm.MappedPropertyApply, prop))
345
+ if isinstance(container_prop.type, dm.DirectRelation):
346
+ if prop.source is None:
347
+ # The warning is issued when the DMS Rules are created.
348
+ return DMSUnknownEntity()
349
+ else:
350
+ return ViewEntity.from_id(prop.source)
351
+ else:
352
+ return DataType.load(container_prop.type._type)
353
+ else:
354
+ self.issue_list.append(issues.importing.FailedToInferValueTypeWarning(str(view_entity), prop_id))
355
+ return None
356
+
357
+ def _get_nullable(self, prop: ViewPropertyApply) -> bool | None:
358
+ if isinstance(prop, dm.MappedPropertyApply):
359
+ return self._container_prop_unsafe(prop).nullable
360
+ else:
361
+ return None
362
+
363
+ def _get_is_list(self, prop: ViewPropertyApply) -> bool | None:
364
+ if isinstance(prop, dm.MappedPropertyApply):
365
+ return self._container_prop_unsafe(prop).type.is_list
366
+ elif isinstance(prop, MultiEdgeConnectionApply | MultiReverseDirectRelationApply):
367
+ return True
368
+ elif isinstance(prop, SingleEdgeConnectionApply | SingleReverseDirectRelationApply):
369
+ return False
370
+ else:
371
+ return None
372
+
373
+ def _get_default(self, prop: ViewPropertyApply) -> str | None:
374
+ if isinstance(prop, dm.MappedPropertyApply):
375
+ default = self._container_prop_unsafe(prop).default_value
376
+ if default is not None:
377
+ return str(default)
378
+ return None
379
+
380
+ def _get_index(self, prop: ViewPropertyApply, prop_id) -> list[str] | None:
381
+ if not isinstance(prop, dm.MappedPropertyApply):
382
+ return None
383
+ container = self._container_by_id[prop.container]
384
+ index: list[str] = []
385
+ for index_name, index_obj in (container.indexes or {}).items():
386
+ if isinstance(index_obj, BTreeIndex | InvertedIndex) and prop_id in index_obj.properties:
387
+ index.append(index_name)
388
+ return index or None
389
+
390
+ def _get_constraint(self, prop: ViewPropertyApply, prop_id: str) -> list[str] | None:
391
+ if not isinstance(prop, dm.MappedPropertyApply):
392
+ return None
393
+ container = self._container_by_id[prop.container]
394
+ unique_constraints: list[str] = []
395
+ for constraint_name, constraint_obj in (container.constraints or {}).items():
396
+ if isinstance(constraint_obj, dm.RequiresConstraint):
397
+ # This is handled in the .from_container method of DMSContainer
398
+ continue
399
+ elif isinstance(constraint_obj, dm.UniquenessConstraint) and prop_id in constraint_obj.properties:
400
+ unique_constraints.append(constraint_name)
401
+ elif isinstance(constraint_obj, dm.UniquenessConstraint):
402
+ # This does not apply to this property
403
+ continue
404
+ else:
405
+ self.issue_list.append(
406
+ issues.importing.UnknownContainerConstraintWarning(
407
+ str(ContainerEntity.from_id(prop.container)), prop_id, type(constraint_obj).__name__
408
+ )
409
+ )
410
+ return unique_constraints or None
@@ -22,7 +22,15 @@ from cognite.neat.utils.spreadsheet import SpreadsheetRead, read_individual_shee
22
22
  from ._base import BaseImporter, Rules, _handle_issues
23
23
 
24
24
  SOURCE_SHEET__TARGET_FIELD__HEADERS = [
25
- ("Properties", "Properties", "Class"),
25
+ (
26
+ "Properties",
27
+ "Properties",
28
+ {
29
+ RoleTypes.domain_expert: "Property",
30
+ RoleTypes.information_architect: "Property",
31
+ RoleTypes.dms_architect: "View Property",
32
+ },
33
+ ),
26
34
  ("Classes", "Classes", "Class"),
27
35
  ("Containers", "Containers", "Container"),
28
36
  ("Views", "Views", "View"),
@@ -131,11 +139,15 @@ class SpreadsheetReader:
131
139
  )
132
140
  return None, read_info_by_sheet
133
141
 
134
- for source_sheet_name, target_sheet_name, headers in SOURCE_SHEET__TARGET_FIELD__HEADERS:
142
+ for source_sheet_name, target_sheet_name, headers_input in SOURCE_SHEET__TARGET_FIELD__HEADERS:
135
143
  source_sheet_name = self.to_reference_sheet(source_sheet_name) if self._is_reference else source_sheet_name
136
144
 
137
145
  if source_sheet_name not in excel_file.sheet_names:
138
146
  continue
147
+ if isinstance(headers_input, dict):
148
+ headers = headers_input[metadata.role]
149
+ else:
150
+ headers = headers_input
139
151
 
140
152
  try:
141
153
  sheets[target_sheet_name], read_info_by_sheet[source_sheet_name] = read_individual_sheet(
@@ -229,12 +241,6 @@ class ExcelImporter(BaseImporter):
229
241
  role=role,
230
242
  )
231
243
 
232
- @classmethod
233
- def _return_or_raise(cls, issue_list: IssueList, errors: Literal["raise", "continue"]) -> tuple[None, IssueList]:
234
- if errors == "raise":
235
- raise issue_list.as_errors()
236
- return None, issue_list
237
-
238
244
 
239
245
  class GoogleSheetImporter(BaseImporter):
240
246
  def __init__(self, sheet_id: str, skiprows: int = 1):
@@ -78,6 +78,9 @@ class NeatValidationError(ValidationIssue, ABC):
78
78
  all_errors.append(DefaultPydanticError.from_pydantic_error(error))
79
79
  return all_errors
80
80
 
81
+ def as_exception(self) -> Exception:
82
+ return ValueError(self.message())
83
+
81
84
 
82
85
  @dataclass(frozen=True)
83
86
  class DefaultPydanticError(NeatValidationError):