cognite-neat 0.117.12__tar.gz → 0.118.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/PKG-INFO +1 -1
  2. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_alpha.py +1 -0
  3. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_dms2rules.py +148 -40
  4. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/information/_rules_input.py +4 -1
  5. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/transformers/__init__.py +2 -0
  6. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/transformers/_converters.py +140 -2
  7. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_template.py +59 -2
  8. cognite_neat-0.118.0/cognite/neat/_version.py +2 -0
  9. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/pyproject.toml +1 -1
  10. cognite_neat-0.117.12/cognite/neat/_version.py +0 -2
  11. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/LICENSE +0 -0
  12. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/README.md +0 -0
  13. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/__init__.py +0 -0
  14. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/__init__.py +0 -0
  15. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/_api/__init__.py +0 -0
  16. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/_api/data_modeling_loaders.py +0 -0
  17. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/_api/neat_instances.py +0 -0
  18. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/_api/schema.py +0 -0
  19. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/_api_client.py +0 -0
  20. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/data_classes/__init__.py +0 -0
  21. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/data_classes/data_modeling.py +0 -0
  22. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/data_classes/neat_sequence.py +0 -0
  23. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/data_classes/schema.py +0 -0
  24. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_client/testing.py +0 -0
  25. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_config.py +0 -0
  26. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_constants.py +0 -0
  27. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/__init__.py +0 -0
  28. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/_shared.py +0 -0
  29. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/_tracking/__init__.py +0 -0
  30. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/_tracking/base.py +0 -0
  31. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/_tracking/log.py +0 -0
  32. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  33. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44.xml +0 -0
  34. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/examples/__init__.py +0 -0
  35. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  36. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/__init__.py +0 -0
  37. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_base.py +0 -0
  38. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/__init__.py +0 -0
  39. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_assets.py +0 -0
  40. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_base.py +0 -0
  41. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_classic.py +0 -0
  42. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_data_sets.py +0 -0
  43. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_events.py +0 -0
  44. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_files.py +0 -0
  45. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_labels.py +0 -0
  46. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_relationships.py +0 -0
  47. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_sequences.py +0 -0
  48. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_classic_cdf/_timeseries.py +0 -0
  49. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_dexpi.py +0 -0
  50. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_dict.py +0 -0
  51. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_dms.py +0 -0
  52. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_dms_graph.py +0 -0
  53. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_iodd.py +0 -0
  54. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_mock_graph_generator.py +0 -0
  55. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_raw.py +0 -0
  56. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/extractors/_rdf_file.py +0 -0
  57. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/loaders/__init__.py +0 -0
  58. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/loaders/_base.py +0 -0
  59. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/loaders/_rdf2dms.py +0 -0
  60. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/queries/__init__.py +0 -0
  61. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/queries/_base.py +0 -0
  62. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/transformers/__init__.py +0 -0
  63. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/transformers/_base.py +0 -0
  64. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/transformers/_classic_cdf.py +0 -0
  65. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/transformers/_iodd.py +0 -0
  66. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/transformers/_prune_graph.py +0 -0
  67. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/transformers/_rdfpath.py +0 -0
  68. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_graph/transformers/_value_type.py +0 -0
  69. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/__init__.py +0 -0
  70. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/_base.py +0 -0
  71. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/_contextmanagers.py +0 -0
  72. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/_factory.py +0 -0
  73. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/errors/__init__.py +0 -0
  74. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/errors/_external.py +0 -0
  75. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/errors/_general.py +0 -0
  76. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/errors/_properties.py +0 -0
  77. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/errors/_resources.py +0 -0
  78. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/errors/_wrapper.py +0 -0
  79. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/formatters.py +0 -0
  80. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/warnings/__init__.py +0 -0
  81. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/warnings/_external.py +0 -0
  82. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/warnings/_general.py +0 -0
  83. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/warnings/_models.py +0 -0
  84. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/warnings/_properties.py +0 -0
  85. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/warnings/_resources.py +0 -0
  86. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_issues/warnings/user_modeling.py +0 -0
  87. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/__init__.py +0 -0
  88. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/_constants.py +0 -0
  89. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/_shared.py +0 -0
  90. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/analysis/__init__.py +0 -0
  91. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/analysis/_base.py +0 -0
  92. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/catalog/__init__.py +0 -0
  93. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/catalog/classic_model.xlsx +0 -0
  94. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/catalog/hello_world_pump.xlsx +0 -0
  95. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
  96. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/exporters/__init__.py +0 -0
  97. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/exporters/_base.py +0 -0
  98. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/exporters/_rules2dms.py +0 -0
  99. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/exporters/_rules2excel.py +0 -0
  100. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/exporters/_rules2instance_template.py +0 -0
  101. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/exporters/_rules2ontology.py +0 -0
  102. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/exporters/_rules2yaml.py +0 -0
  103. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/exporters/_validation.py +0 -0
  104. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/__init__.py +0 -0
  105. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_base.py +0 -0
  106. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_dtdl2rules/__init__.py +0 -0
  107. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_dtdl2rules/_unit_lookup.py +0 -0
  108. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_converter.py +0 -0
  109. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_importer.py +0 -0
  110. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_dtdl2rules/spec.py +0 -0
  111. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_rdf/__init__.py +0 -0
  112. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_rdf/_base.py +0 -0
  113. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_rdf/_imf2rules.py +0 -0
  114. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_rdf/_inference2rules.py +0 -0
  115. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_rdf/_owl2rules.py +0 -0
  116. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_rdf/_shared.py +0 -0
  117. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_spreadsheet2rules.py +0 -0
  118. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/importers/_yaml2rules.py +0 -0
  119. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/__init__.py +0 -0
  120. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/_base_input.py +0 -0
  121. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/_base_rules.py +0 -0
  122. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/_types.py +0 -0
  123. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/data_types.py +0 -0
  124. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/dms/__init__.py +0 -0
  125. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/dms/_exporter.py +0 -0
  126. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/dms/_rules.py +0 -0
  127. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/dms/_rules_input.py +0 -0
  128. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/dms/_validation.py +0 -0
  129. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/entities/__init__.py +0 -0
  130. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/entities/_constants.py +0 -0
  131. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/entities/_loaders.py +0 -0
  132. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/entities/_multi_value.py +0 -0
  133. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/entities/_single_value.py +0 -0
  134. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/entities/_types.py +0 -0
  135. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/entities/_wrapped.py +0 -0
  136. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/information/__init__.py +0 -0
  137. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/information/_rules.py +0 -0
  138. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/information/_validation.py +0 -0
  139. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/mapping/__init__.py +0 -0
  140. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/mapping/_classic2core.py +0 -0
  141. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/models/mapping/_classic2core.yaml +0 -0
  142. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/transformers/_base.py +0 -0
  143. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/transformers/_mapping.py +0 -0
  144. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_rules/transformers/_verification.py +0 -0
  145. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/__init__.py +0 -0
  146. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_base.py +0 -0
  147. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_collector.py +0 -0
  148. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_drop.py +0 -0
  149. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_explore.py +0 -0
  150. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_fix.py +0 -0
  151. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_inspect.py +0 -0
  152. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_mapping.py +0 -0
  153. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_prepare.py +0 -0
  154. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_read.py +0 -0
  155. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_set.py +0 -0
  156. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_show.py +0 -0
  157. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_state.py +0 -0
  158. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_subset.py +0 -0
  159. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_to.py +0 -0
  160. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/_wizard.py +0 -0
  161. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/engine/__init__.py +0 -0
  162. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/engine/_import.py +0 -0
  163. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/engine/_interface.py +0 -0
  164. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/engine/_load.py +0 -0
  165. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_session/exceptions.py +0 -0
  166. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_shared.py +0 -0
  167. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_store/__init__.py +0 -0
  168. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_store/_graph_store.py +0 -0
  169. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_store/_provenance.py +0 -0
  170. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_store/_rules_store.py +0 -0
  171. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_store/exceptions.py +0 -0
  172. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/__init__.py +0 -0
  173. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/auth.py +0 -0
  174. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/auxiliary.py +0 -0
  175. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/collection_.py +0 -0
  176. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/graph_transformations_report.py +0 -0
  177. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/io_.py +0 -0
  178. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/rdf_.py +0 -0
  179. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/reader/__init__.py +0 -0
  180. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/reader/_base.py +0 -0
  181. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/spreadsheet.py +0 -0
  182. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/text.py +0 -0
  183. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/time_.py +0 -0
  184. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/upload.py +0 -0
  185. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/_utils/xml_.py +0 -0
  186. {cognite_neat-0.117.12 → cognite_neat-0.118.0}/cognite/neat/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: cognite-neat
3
- Version: 0.117.12
3
+ Version: 0.118.0
4
4
  Summary: Knowledge graph transformation
5
5
  License: Apache-2.0
6
6
  Author: Nikola Vasiljevic
@@ -22,3 +22,4 @@ class ExperimentalFlags:
22
22
  aml_read = ExperimentalFeatureWarning("aml_read")
23
23
  csv_read = ExperimentalFeatureWarning("csv_read")
24
24
  to_ontology = ExperimentalFeatureWarning("to_ontology")
25
+ extension = ExperimentalFeatureWarning("extension")
@@ -1,8 +1,9 @@
1
+ import warnings
1
2
  from collections import defaultdict
2
3
  from collections.abc import Collection, Iterable, Sequence
3
4
  from datetime import datetime
4
5
  from pathlib import Path
5
- from typing import Literal, cast
6
+ from typing import Literal
6
7
 
7
8
  from cognite.client import data_modeling as dm
8
9
  from cognite.client.data_classes.data_modeling import DataModelId, DataModelIdentifier
@@ -16,8 +17,13 @@ from cognite.client.data_classes.data_modeling.data_types import Enum as DMSEnum
16
17
  from cognite.client.data_classes.data_modeling.views import (
17
18
  MultiEdgeConnectionApply,
18
19
  MultiReverseDirectRelationApply,
20
+ ReverseDirectRelation,
21
+ SingleEdgeConnection,
19
22
  SingleEdgeConnectionApply,
23
+ SingleReverseDirectRelation,
20
24
  SingleReverseDirectRelationApply,
25
+ View,
26
+ ViewProperty,
21
27
  ViewPropertyApply,
22
28
  )
23
29
  from cognite.client.utils import ms_to_datetime
@@ -28,11 +34,13 @@ from cognite.neat._issues import IssueList, MultiValueError, NeatIssue, catch_is
28
34
  from cognite.neat._issues.errors import (
29
35
  FileTypeUnexpectedError,
30
36
  NeatValueError,
37
+ PropertyTypeNotSupportedError,
31
38
  ResourceMissingIdentifierError,
32
39
  ResourceRetrievalError,
33
40
  )
34
41
  from cognite.neat._issues.warnings import (
35
42
  MissingCogniteClientWarning,
43
+ NeatValueWarning,
36
44
  PropertyNotFoundWarning,
37
45
  PropertyTypeNotSupportedWarning,
38
46
  ResourceNotFoundWarning,
@@ -45,7 +53,7 @@ from cognite.neat._rules.models import (
45
53
  DMSInputRules,
46
54
  DMSSchema,
47
55
  )
48
- from cognite.neat._rules.models.data_types import DataType, Enum
56
+ from cognite.neat._rules.models.data_types import DataType, Enum, String
49
57
  from cognite.neat._rules.models.dms import (
50
58
  DMSInputContainer,
51
59
  DMSInputEnum,
@@ -63,6 +71,10 @@ from cognite.neat._rules.models.entities import (
63
71
  ReverseConnectionEntity,
64
72
  ViewEntity,
65
73
  )
74
+ from cognite.neat._rules.models.information import (
75
+ InformationInputClass,
76
+ InformationInputProperty,
77
+ )
66
78
 
67
79
 
68
80
  class DMSImporter(BaseImporter[DMSInputRules]):
@@ -332,19 +344,27 @@ class DMSImporter(BaseImporter[DMSInputRules]):
332
344
  )
333
345
  return None
334
346
 
335
- value_type = self._get_value_type(prop, view_entity, prop_id, enum_collection_by_container_property)
347
+ container_property = (
348
+ self._get_container_property_definition(prop) if isinstance(prop, dm.MappedPropertyApply) else None
349
+ )
350
+ value_type = self._get_value_type(prop, container_property, enum_collection_by_container_property)
336
351
  if value_type is None:
352
+ self.issue_list.append(
353
+ PropertyTypeNotSupportedWarning(view_entity.as_id(), "view", prop_id, type(prop).__name__)
354
+ )
337
355
  return None
356
+ if isinstance(value_type, ViewEntity) and value_type.as_id() not in self._all_views_by_id:
357
+ self.issue_list.append(ResourceUnknownWarning(prop.source, "view", view_entity.as_id(), "view"))
338
358
 
339
359
  return DMSInputProperty(
340
360
  description=prop.description,
341
361
  name=prop.name,
342
362
  connection=self._get_connection_type(prop),
343
363
  value_type=str(value_type),
344
- min_count=self._get_min_count(prop),
345
- max_count=self._get_max_count(prop),
364
+ min_count=self._get_min_count(prop, container_property),
365
+ max_count=self._get_max_count(prop, container_property),
346
366
  immutable=self._get_immutable(prop),
347
- default=self._get_default(prop),
367
+ default=self._get_default(prop, container_property),
348
368
  container=(
349
369
  str(ContainerEntity.from_id(prop.container)) if isinstance(prop, dm.MappedPropertyApply) else None
350
370
  ),
@@ -357,7 +377,7 @@ class DMSImporter(BaseImporter[DMSInputRules]):
357
377
  constraint=self._get_constraint(prop, prop_id),
358
378
  )
359
379
 
360
- def _container_prop_unsafe(self, prop: dm.MappedPropertyApply) -> dm.ContainerProperty:
380
+ def _get_container_property_definition(self, prop: dm.MappedPropertyApply) -> dm.ContainerProperty:
361
381
  """This method assumes you have already checked that the container with property exists."""
362
382
  return self._all_containers_by_id[prop.container].properties[prop.container_property_identifier]
363
383
 
@@ -372,40 +392,48 @@ class DMSImporter(BaseImporter[DMSInputRules]):
372
392
  elif isinstance(prop, SingleReverseDirectRelationApply | MultiReverseDirectRelationApply):
373
393
  return ReverseConnectionEntity(property=prop.through.property)
374
394
  elif isinstance(prop, dm.MappedPropertyApply) and isinstance(
375
- self._container_prop_unsafe(prop).type, dm.DirectRelation
395
+ self._get_container_property_definition(prop).type, dm.DirectRelation
376
396
  ):
377
397
  return "direct"
378
398
  else:
379
399
  return None
380
400
 
401
+ @classmethod
381
402
  def _get_value_type(
382
- self,
383
- prop: ViewPropertyApply,
384
- view_entity: ViewEntity,
385
- prop_id: str,
386
- enum_collection_by_container_property: dict[tuple[dm.ContainerId, str], str],
403
+ cls,
404
+ prop: ViewPropertyApply | ViewProperty,
405
+ container_property: dm.ContainerProperty | None = None,
406
+ enum_collection_by_container_property: dict[tuple[dm.ContainerId, str], str] | None = None,
387
407
  ) -> DataType | ViewEntity | DMSUnknownEntity | None:
388
408
  if isinstance(
389
409
  prop,
390
410
  SingleEdgeConnectionApply
391
411
  | MultiEdgeConnectionApply
392
412
  | SingleReverseDirectRelationApply
393
- | MultiReverseDirectRelationApply,
413
+ | MultiReverseDirectRelationApply
414
+ | SingleEdgeConnection
415
+ | dm.MultiEdgeConnection
416
+ | SingleReverseDirectRelation
417
+ | dm.MultiReverseDirectRelation,
394
418
  ):
395
419
  return ViewEntity.from_id(prop.source)
396
- elif isinstance(prop, dm.MappedPropertyApply):
397
- container_prop = self._container_prop_unsafe(cast(dm.MappedPropertyApply, prop))
398
- if isinstance(container_prop.type, dm.DirectRelation):
420
+ elif isinstance(prop, dm.MappedPropertyApply | dm.MappedProperty):
421
+ if isinstance(prop, dm.MappedPropertyApply):
422
+ if container_property is None:
423
+ raise ValueError("container property must be provided when prop is a MappedProperty")
424
+ prop_type = container_property.type
425
+ else:
426
+ prop_type = prop.type
427
+ if isinstance(prop_type, dm.DirectRelation):
399
428
  if prop.source is None:
400
429
  return DMSUnknownEntity()
401
- elif prop.source not in self._all_views_by_id:
402
- self.issue_list.append(ResourceUnknownWarning(prop.source, "view", view_entity.as_id(), "view"))
403
- return ViewEntity.from_id(prop.source)
404
430
  else:
405
431
  return ViewEntity.from_id(prop.source)
406
- elif isinstance(container_prop.type, PropertyTypeWithUnit) and container_prop.type.unit:
407
- return DataType.load(f"{container_prop.type._type}(unit={container_prop.type.unit.external_id})")
408
- elif isinstance(container_prop.type, DMSEnum):
432
+ elif isinstance(prop_type, PropertyTypeWithUnit) and prop_type.unit:
433
+ return DataType.load(f"{prop_type._type}(unit={prop_type.unit.external_id})")
434
+ elif isinstance(prop_type, DMSEnum):
435
+ if enum_collection_by_container_property is None:
436
+ return String()
409
437
  collection = enum_collection_by_container_property.get(
410
438
  (prop.container, prop.container_property_identifier)
411
439
  )
@@ -415,30 +443,46 @@ class DMSImporter(BaseImporter[DMSInputRules]):
415
443
  f"BUG in Neat: Enum for {prop.container}.{prop.container_property_identifier} not found."
416
444
  )
417
445
 
418
- return Enum(collection=ClassEntity(suffix=collection), unknownValue=container_prop.type.unknown_value)
446
+ return Enum(collection=ClassEntity(suffix=collection), unknownValue=prop_type.unknown_value)
419
447
  else:
420
- return DataType.load(container_prop.type._type)
448
+ return DataType.load(prop_type._type)
421
449
  else:
422
- self.issue_list.append(
423
- PropertyTypeNotSupportedWarning[dm.ViewId](view_entity.as_id(), "view", prop_id, type(prop).__name__)
424
- )
425
450
  return None
426
451
 
427
- def _get_min_count(self, prop: ViewPropertyApply) -> int | None:
452
+ @classmethod
453
+ def _get_min_count(
454
+ cls,
455
+ prop: ViewPropertyApply | ViewProperty,
456
+ container_property: dm.ContainerProperty | None = None,
457
+ ) -> int | None:
428
458
  if isinstance(prop, dm.MappedPropertyApply):
429
- return int(not self._container_prop_unsafe(prop).nullable)
459
+ if container_property is None:
460
+ raise ValueError("container_property must be provided when prop is a MappedPropertyApply")
461
+ return int(not container_property.nullable)
462
+ elif isinstance(prop, dm.MappedProperty):
463
+ return int(not prop.nullable)
430
464
  else:
431
465
  return None
432
466
 
433
467
  def _get_immutable(self, prop: ViewPropertyApply) -> bool | None:
434
468
  if isinstance(prop, dm.MappedPropertyApply):
435
- return self._container_prop_unsafe(prop).immutable
469
+ return self._get_container_property_definition(prop).immutable
436
470
  else:
437
471
  return None
438
472
 
439
- def _get_max_count(self, prop: ViewPropertyApply) -> int | float | None:
440
- if isinstance(prop, dm.MappedPropertyApply):
441
- prop_type = self._container_prop_unsafe(prop).type
473
+ @classmethod
474
+ def _get_max_count(
475
+ cls,
476
+ prop: ViewPropertyApply | ViewProperty,
477
+ container_property: dm.ContainerProperty | None = None,
478
+ ) -> int | float | None:
479
+ if isinstance(prop, dm.MappedPropertyApply | dm.MappedProperty):
480
+ if isinstance(prop, dm.MappedPropertyApply):
481
+ if container_property is None:
482
+ raise ValueError("get_container must be provided when prop is a MappedPropertyApply")
483
+ prop_type = container_property.type
484
+ else:
485
+ prop_type = prop.type
442
486
  if isinstance(prop_type, ListablePropertyType):
443
487
  if prop_type.is_list is False:
444
488
  return 1
@@ -450,17 +494,41 @@ class DMSImporter(BaseImporter[DMSInputRules]):
450
494
  return DMS_PRIMITIVE_LIST_DEFAULT_LIMIT
451
495
  else:
452
496
  return 1
453
- elif isinstance(prop, MultiEdgeConnectionApply | MultiReverseDirectRelationApply):
497
+ elif isinstance(
498
+ prop,
499
+ MultiEdgeConnectionApply
500
+ | MultiReverseDirectRelationApply
501
+ | dm.MultiEdgeConnection
502
+ | dm.MultiReverseDirectRelation,
503
+ ):
454
504
  return float("inf")
455
- elif isinstance(prop, SingleEdgeConnectionApply | SingleReverseDirectRelationApply):
505
+ elif isinstance(
506
+ prop,
507
+ SingleEdgeConnectionApply
508
+ | SingleReverseDirectRelationApply
509
+ | SingleEdgeConnection
510
+ | SingleReverseDirectRelation,
511
+ ):
456
512
  return 1
457
513
  else:
458
- # Unknown type.
514
+ warnings.warn(
515
+ NeatValueWarning(f"Unknown property type {type(prop)}. Assuming max count is inf"), stacklevel=2
516
+ )
459
517
  return None
460
518
 
461
- def _get_default(self, prop: ViewPropertyApply) -> str | None:
462
- if isinstance(prop, dm.MappedPropertyApply):
463
- default = self._container_prop_unsafe(prop).default_value
519
+ @classmethod
520
+ def _get_default(
521
+ cls,
522
+ prop: ViewPropertyApply | ViewProperty,
523
+ container_property: dm.ContainerProperty | None = None,
524
+ ) -> str | None:
525
+ if isinstance(prop, dm.MappedPropertyApply | dm.MappedProperty):
526
+ if isinstance(prop, dm.MappedPropertyApply):
527
+ if container_property is None:
528
+ raise ValueError("container_property must be provided when prop is a MappedPropertyApply")
529
+ default = container_property.default_value
530
+ else:
531
+ default = prop.default_value
464
532
  if default is not None:
465
533
  return str(default)
466
534
  return None
@@ -559,3 +627,43 @@ class DMSImporter(BaseImporter[DMSInputRules]):
559
627
  )
560
628
  )
561
629
  return enum_by_container_property
630
+
631
+ @classmethod
632
+ def as_information_input_property(
633
+ cls, entity: ClassEntity, prop_id: str, view_property: ViewProperty
634
+ ) -> InformationInputProperty:
635
+ if not isinstance(view_property, dm.MappedProperty | dm.EdgeConnection | ReverseDirectRelation):
636
+ raise PropertyTypeNotSupportedError(
637
+ dm.ViewId(str(entity.prefix), str(entity.suffix), entity.version),
638
+ "view",
639
+ prop_id,
640
+ type(view_property).__name__,
641
+ )
642
+
643
+ value_type = cls._get_value_type(view_property)
644
+ if value_type is None:
645
+ raise NeatValueError(f"Failed to get value type for {entity} property {prop_id}")
646
+
647
+ return InformationInputProperty(
648
+ class_=entity,
649
+ property_=prop_id,
650
+ value_type=str(value_type),
651
+ name=view_property.name,
652
+ description=view_property.description,
653
+ min_count=cls._get_min_count(view_property),
654
+ max_count=cls._get_max_count(view_property),
655
+ default=cls._get_default(view_property),
656
+ )
657
+
658
+ @classmethod
659
+ def as_information_input_class(cls, view: View) -> InformationInputClass:
660
+ return InformationInputClass(
661
+ class_=ClassEntity(prefix=view.space, suffix=view.external_id, version=view.version),
662
+ name=view.name,
663
+ description=view.description,
664
+ implements=[
665
+ ClassEntity(prefix=parent.space, suffix=parent.external_id, version=parent.version)
666
+ for parent in view.implements or []
667
+ ]
668
+ or None,
669
+ )
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass, field
2
2
  from datetime import datetime
3
- from typing import Any
3
+ from typing import Any, cast
4
4
 
5
5
  import pandas as pd
6
6
  from cognite.client import data_modeling as dm
@@ -103,6 +103,9 @@ class InformationInputProperty(InputComponent[InformationProperty]):
103
103
  output["Value Type"] = load_value_type(self.value_type, default_prefix)
104
104
  return output
105
105
 
106
+ def copy(self, update: dict[str, Any], default_prefix: str) -> "InformationInputProperty":
107
+ return cast(InformationInputProperty, type(self)._load({**self.dump(default_prefix), **update}))
108
+
106
109
 
107
110
  @dataclass
108
111
  class InformationInputClass(InputComponent[InformationClass]):
@@ -1,6 +1,7 @@
1
1
  from ._base import RulesTransformer, VerifiedRulesTransformer
2
2
  from ._converters import (
3
3
  AddClassImplements,
4
+ AddCogniteProperties,
4
5
  ChangeViewPrefix,
5
6
  ClassicPrepareCore,
6
7
  ConversionTransformer,
@@ -29,6 +30,7 @@ from ._verification import VerifyAnyRules, VerifyDMSRules, VerifyInformationRule
29
30
 
30
31
  __all__ = [
31
32
  "AddClassImplements",
33
+ "AddCogniteProperties",
32
34
  "AsParentPropertyId",
33
35
  "ChangeViewPrefix",
34
36
  "ClassicPrepareCore",
@@ -6,10 +6,11 @@ from collections import Counter, defaultdict
6
6
  from collections.abc import Collection, Mapping
7
7
  from datetime import date, datetime
8
8
  from functools import cached_property
9
+ from graphlib import CycleError, TopologicalSorter
9
10
  from typing import Any, ClassVar, Literal, TypeVar, cast, overload
10
11
 
11
12
  from cognite.client.data_classes import data_modeling as dms
12
- from cognite.client.data_classes.data_modeling import DataModelId, DataModelIdentifier, ViewId
13
+ from cognite.client.data_classes.data_modeling import DataModelId, DataModelIdentifier, View, ViewId
13
14
  from cognite.client.utils.useful_types import SequenceNotStr
14
15
  from pydantic import ValidationError
15
16
  from rdflib import Namespace
@@ -25,6 +26,8 @@ from cognite.neat._constants import (
25
26
  DMS_RESERVED_PROPERTIES,
26
27
  get_default_prefixes_and_namespaces,
27
28
  )
29
+ from cognite.neat._issues import IssueList
30
+ from cognite.neat._issues._factory import from_pydantic_errors
28
31
  from cognite.neat._issues.errors import NeatValueError
29
32
  from cognite.neat._issues.warnings import NeatValueWarning
30
33
  from cognite.neat._issues.warnings._models import (
@@ -60,8 +63,15 @@ from cognite.neat._rules.models.entities import (
60
63
  UnknownEntity,
61
64
  ViewEntity,
62
65
  )
63
- from cognite.neat._rules.models.information import InformationClass, InformationMetadata, InformationProperty
66
+ from cognite.neat._rules.models.information import (
67
+ InformationClass,
68
+ InformationInputClass,
69
+ InformationInputProperty,
70
+ InformationMetadata,
71
+ InformationProperty,
72
+ )
64
73
  from cognite.neat._utils.rdf_ import get_inheritance_path
74
+ from cognite.neat._utils.spreadsheet import SpreadsheetRead
65
75
  from cognite.neat._utils.text import NamingStandardization, title, to_camel_case, to_words
66
76
 
67
77
  from ._base import RulesTransformer, T_VerifiedIn, T_VerifiedOut, VerifiedRulesTransformer
@@ -2017,3 +2027,131 @@ class SubsetInformationRules(VerifiedRulesTransformer[InformationRules, Informat
2017
2027
  return InformationRules.model_validate(subsetted_rules)
2018
2028
  except ValidationError as e:
2019
2029
  raise NeatValueError(f"Cannot subset rules: {e}") from e
2030
+
2031
+
2032
+ class AddCogniteProperties(RulesTransformer[ReadRules[InformationInputRules], ReadRules[InformationInputRules]]):
2033
+ """This transformer looks at the implements of the classes and adds all properties
2034
+ from the parent (and ancestors) classes that are not already included in the data model.
2035
+
2036
+ Args:
2037
+ client: The client is used to look up the properties of the parent classes.
2038
+
2039
+ """
2040
+
2041
+ def __init__(self, client: NeatClient) -> None:
2042
+ self._client = client
2043
+
2044
+ @property
2045
+ def description(self) -> str:
2046
+ """Get the description of the transformer."""
2047
+ return "Add Cognite properties for all concepts that implements a Cognite concept."
2048
+
2049
+ def transform(self, rules: ReadRules[InformationInputRules]) -> ReadRules[InformationInputRules]:
2050
+ input_ = rules.rules
2051
+ if input_ is None:
2052
+ raise NeatValueError("Rule read failed. Cannot add cognite properties to None rules.")
2053
+
2054
+ default_space = input_.metadata.space
2055
+ default_version = input_.metadata.version
2056
+
2057
+ dependencies_by_class = self._get_dependencies_by_class(input_.classes, rules.read_context, default_space)
2058
+ properties_by_class = self._get_properties_by_class(input_.properties, rules.read_context, default_space)
2059
+ cognite_implements_concepts = self._get_cognite_concepts(dependencies_by_class)
2060
+ views_by_class_entity = self._get_views_by_class(cognite_implements_concepts, default_space, default_version)
2061
+
2062
+ for class_entity, view in views_by_class_entity.items():
2063
+ for prop_id, view_prop in view.properties.items():
2064
+ if prop_id in properties_by_class[class_entity]:
2065
+ continue
2066
+ properties_by_class[class_entity][prop_id] = DMSImporter.as_information_input_property(
2067
+ class_entity, prop_id, view_prop
2068
+ )
2069
+
2070
+ try:
2071
+ topological_order = TopologicalSorter(dependencies_by_class).static_order()
2072
+ except CycleError as e:
2073
+ raise NeatValueError(f"Cycle detected in the class hierarchy: {e}") from e
2074
+
2075
+ new_properties: list[InformationInputProperty] = input_.properties.copy()
2076
+ for class_entity in topological_order:
2077
+ if class_entity not in dependencies_by_class:
2078
+ continue
2079
+ for parent in dependencies_by_class[class_entity]:
2080
+ for prop in properties_by_class[parent].values():
2081
+ if prop.property_ not in properties_by_class[class_entity]:
2082
+ new_prop = prop.copy(update={"Class": class_entity}, default_prefix=default_space)
2083
+ new_properties.append(new_prop)
2084
+ properties_by_class[class_entity][prop.property_] = new_prop
2085
+
2086
+ new_classes: list[InformationInputClass] = input_.classes.copy()
2087
+ existing_classes = {cls.class_ for cls in input_.classes}
2088
+ for class_entity, view in views_by_class_entity.items():
2089
+ if class_entity not in existing_classes:
2090
+ new_classes.append(DMSImporter.as_information_input_class(view))
2091
+ existing_classes.add(class_entity)
2092
+
2093
+ return ReadRules(
2094
+ rules=InformationInputRules(
2095
+ metadata=input_.metadata,
2096
+ properties=new_properties,
2097
+ classes=new_classes,
2098
+ prefixes=input_.prefixes,
2099
+ ),
2100
+ read_context={},
2101
+ )
2102
+
2103
+ @staticmethod
2104
+ def _get_properties_by_class(
2105
+ properties: list[InformationInputProperty], read_context: dict[str, SpreadsheetRead], default_space: str
2106
+ ) -> dict[ClassEntity, dict[str, InformationInputProperty]]:
2107
+ issues = IssueList()
2108
+ properties_by_class: dict[ClassEntity, dict[str, InformationInputProperty]] = defaultdict(dict)
2109
+ for prop in properties:
2110
+ try:
2111
+ dumped = prop.dump(default_prefix=default_space)
2112
+ except ValidationError as e:
2113
+ issues.extend(from_pydantic_errors(e.errors(), read_context))
2114
+ continue
2115
+ class_entity = cast(ClassEntity, dumped["Class"])
2116
+ properties_by_class[class_entity][prop.property_] = prop
2117
+ if issues.has_errors:
2118
+ raise issues.as_errors(operation="Reading properties")
2119
+ return properties_by_class
2120
+
2121
+ @staticmethod
2122
+ def _get_dependencies_by_class(
2123
+ classes: list[InformationInputClass], read_context: dict[str, SpreadsheetRead], default_space: str
2124
+ ) -> dict[ClassEntity, set[ClassEntity]]:
2125
+ dependencies_by_class: dict[ClassEntity, set[ClassEntity]] = {}
2126
+ issues = IssueList()
2127
+ for raw in classes:
2128
+ try:
2129
+ dumped = raw.dump(default_prefix=default_space)
2130
+ except ValidationError as e:
2131
+ issues.extend(from_pydantic_errors(e.errors(), read_context))
2132
+ continue
2133
+ class_entity = cast(ClassEntity, dumped["Class"])
2134
+ implements = cast(list[ClassEntity] | None, dumped["Implements"])
2135
+ dependencies_by_class[class_entity] = set(implements or [])
2136
+ if issues.has_errors:
2137
+ raise issues.as_errors(operation="Reading classes")
2138
+ return dependencies_by_class
2139
+
2140
+ @staticmethod
2141
+ def _get_cognite_concepts(dependencies_by_class: dict[ClassEntity, set[ClassEntity]]) -> set[ClassEntity]:
2142
+ cognite_implements_concepts = {
2143
+ dependency
2144
+ for dependencies in dependencies_by_class.values()
2145
+ for dependency in dependencies
2146
+ if dependency.prefix in COGNITE_SPACES
2147
+ }
2148
+ if not cognite_implements_concepts:
2149
+ raise NeatValueError("None of the classes implement Cognite Core concepts.")
2150
+ return cognite_implements_concepts
2151
+
2152
+ def _get_views_by_class(
2153
+ self, classes: set[ClassEntity], default_space: str, default_version: str
2154
+ ) -> dict[ClassEntity, View]:
2155
+ view_ids = [class_.as_view_entity(default_space, default_version).as_id() for class_ in classes]
2156
+ views = self._client.loaders.views.retrieve(view_ids, include_ancestor=True, include_connected=True)
2157
+ return {ClassEntity(prefix=view.space, suffix=view.external_id, version=view.version): view for view in views}
@@ -1,16 +1,24 @@
1
- from typing import Literal
1
+ from pathlib import Path
2
+ from typing import Any, Literal
2
3
 
3
4
  from cognite.client.data_classes.data_modeling import DataModelIdentifier
4
5
 
5
- from cognite.neat._issues import IssueList
6
+ from cognite.neat._alpha import ExperimentalFlags
7
+ from cognite.neat._issues import IssueList, catch_issues
8
+ from cognite.neat._rules._shared import ReadRules
9
+ from cognite.neat._rules.exporters import ExcelExporter
10
+ from cognite.neat._rules.importers import ExcelImporter
11
+ from cognite.neat._rules.models import InformationInputRules
6
12
  from cognite.neat._rules.models.dms import DMSValidation
7
13
  from cognite.neat._rules.transformers import (
14
+ AddCogniteProperties,
8
15
  IncludeReferenced,
9
16
  ToDataProductModel,
10
17
  ToEnterpriseModel,
11
18
  ToSolutionModel,
12
19
  VerifiedRulesTransformer,
13
20
  )
21
+ from cognite.neat._utils.reader import NeatReader, PathReader
14
22
 
15
23
  from ._state import SessionState
16
24
  from .exceptions import NeatSessionError, session_class_wrapper
@@ -165,3 +173,52 @@ class TemplateAPI:
165
173
  if last_rules and not issues.has_errors:
166
174
  self._state.last_reference = last_rules
167
175
  return issues
176
+
177
+ def extension(self, io: Any, output: str | Path | None = None) -> IssueList:
178
+ """Creates a template for an extension of a Cognite model.
179
+
180
+ The input is a spreadsheet of a conceptual model in which the concepts are defined
181
+ and marked with the Cognite concept they are extending. For example, if you have a pump
182
+ in the Classes sheet you will see
183
+ ```
184
+ Class: Pump
185
+ Implements: cdf_cdm:CogniteAsset(version=v1)
186
+ ```
187
+ The output will be a spreadsheet in which all the properties from the Cognite concept model
188
+ is added to the spreadsheet. In the example above, the pump concept will have all
189
+ the properties it inherits from the CogniteAsset concept added to the Properties spreadsheet.
190
+
191
+
192
+ Args:
193
+ io: The input spreadsheet.
194
+ output: The output spreadsheet. If None, the output will be the same
195
+ as the input with `_extension` added to the name.
196
+ """
197
+ ExperimentalFlags.extension.warn()
198
+ reader = NeatReader.create(io)
199
+ path = reader.materialize_path()
200
+ if output is None:
201
+ if isinstance(reader, PathReader):
202
+ output_path = path.with_name(f"{path.stem}_extension{path.suffix}")
203
+ else:
204
+ # The source is not a file, for example, a URL or a stream.
205
+ output_path = Path.cwd() / f"{path.stem}_extension{path.suffix}"
206
+ else:
207
+ output_path = Path(output)
208
+
209
+ with catch_issues() as issues:
210
+ read: ReadRules[InformationInputRules] = ExcelImporter(path).to_rules()
211
+ if read.rules is not None:
212
+ # If rules are None there will be issues that are already caught.
213
+ if not isinstance(read.rules, InformationInputRules):
214
+ raise NeatSessionError(f"The input {reader.name} must contain an InformationInputRules object. ")
215
+ if self._state.client is None:
216
+ raise NeatSessionError("Client must be set in the session to run the extension.")
217
+ modified = AddCogniteProperties(self._state.client).transform(read)
218
+ if modified.rules is not None:
219
+ # If rules are None there will be issues that are already caught.
220
+ info = modified.rules.as_verified_rules()
221
+
222
+ ExcelExporter(styling="maximal").export_to_file(info, output_path)
223
+ issues.action = "Created extension template"
224
+ return issues
@@ -0,0 +1,2 @@
1
+ __version__ = "0.118.0"
2
+ __engine__ = "^2.0.4"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cognite-neat"
3
- version = "0.117.12"
3
+ version = "0.118.0"
4
4
  readme = "README.md"
5
5
  description = "Knowledge graph transformation"
6
6
  authors = [
@@ -1,2 +0,0 @@
1
- __version__ = "0.117.12"
2
- __engine__ = "^2.0.4"
File without changes