cognite-neat 0.105.1__tar.gz → 0.106.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 (181) hide show
  1. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/PKG-INFO +1 -7
  2. cognite_neat-0.106.0/cognite/neat/_config.py +11 -0
  3. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_base.py +26 -13
  4. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_classic.py +4 -1
  5. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_sequences.py +2 -2
  6. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/loaders/_rdf2dms.py +7 -2
  7. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/transformers/_base.py +4 -8
  8. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/transformers/_classic_cdf.py +164 -80
  9. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/transformers/_rdfpath.py +1 -1
  10. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/warnings/_external.py +1 -1
  11. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_rdf/_inference2rules.py +4 -2
  12. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/mapping/_classic2core.yaml +70 -58
  13. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/transformers/_mapping.py +3 -2
  14. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_base.py +6 -7
  15. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_inspect.py +6 -2
  16. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_mapping.py +6 -8
  17. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_prepare.py +9 -10
  18. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_read.py +35 -26
  19. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_set.py +9 -0
  20. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_state.py +3 -1
  21. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_to.py +11 -13
  22. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_store/_graph_store.py +33 -28
  23. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/auth.py +35 -15
  24. cognite_neat-0.106.0/cognite/neat/_utils/collection_.py +66 -0
  25. cognite_neat-0.106.0/cognite/neat/_version.py +2 -0
  26. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/pyproject.toml +3 -18
  27. cognite_neat-0.105.1/cognite/neat/_config.py +0 -265
  28. cognite_neat-0.105.1/cognite/neat/_utils/collection_.py +0 -45
  29. cognite_neat-0.105.1/cognite/neat/_version.py +0 -2
  30. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/LICENSE +0 -0
  31. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/README.md +0 -0
  32. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/__init__.py +0 -0
  33. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/__init__.py +0 -0
  34. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/_api/__init__.py +0 -0
  35. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/_api/data_modeling_loaders.py +0 -0
  36. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/_api/schema.py +0 -0
  37. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/_api_client.py +0 -0
  38. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/data_classes/__init__.py +0 -0
  39. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/data_classes/data_modeling.py +0 -0
  40. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/data_classes/neat_sequence.py +0 -0
  41. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/data_classes/schema.py +0 -0
  42. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_client/testing.py +0 -0
  43. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_constants.py +0 -0
  44. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/__init__.py +0 -0
  45. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/_shared.py +0 -0
  46. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/_tracking/__init__.py +0 -0
  47. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/_tracking/base.py +0 -0
  48. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/_tracking/log.py +0 -0
  49. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  50. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44.xml +0 -0
  51. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/examples/__init__.py +0 -0
  52. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  53. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/__init__.py +0 -0
  54. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_base.py +0 -0
  55. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/__init__.py +0 -0
  56. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_assets.py +0 -0
  57. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_data_sets.py +0 -0
  58. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_events.py +0 -0
  59. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_files.py +0 -0
  60. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_labels.py +0 -0
  61. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_relationships.py +0 -0
  62. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_classic_cdf/_timeseries.py +0 -0
  63. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_dexpi.py +0 -0
  64. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_dms.py +0 -0
  65. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_iodd.py +0 -0
  66. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_mock_graph_generator.py +0 -0
  67. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/extractors/_rdf_file.py +0 -0
  68. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/loaders/__init__.py +0 -0
  69. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/loaders/_base.py +0 -0
  70. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/queries/__init__.py +0 -0
  71. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/queries/_base.py +0 -0
  72. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/queries/_construct.py +0 -0
  73. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/queries/_shared.py +0 -0
  74. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/transformers/__init__.py +0 -0
  75. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/transformers/_iodd.py +0 -0
  76. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/transformers/_prune_graph.py +0 -0
  77. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_graph/transformers/_value_type.py +0 -0
  78. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/__init__.py +0 -0
  79. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/_base.py +0 -0
  80. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/errors/__init__.py +0 -0
  81. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/errors/_external.py +0 -0
  82. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/errors/_general.py +0 -0
  83. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/errors/_properties.py +0 -0
  84. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/errors/_resources.py +0 -0
  85. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/errors/_workflow.py +0 -0
  86. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/formatters.py +0 -0
  87. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/warnings/__init__.py +0 -0
  88. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/warnings/_general.py +0 -0
  89. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/warnings/_models.py +0 -0
  90. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/warnings/_properties.py +0 -0
  91. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/warnings/_resources.py +0 -0
  92. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_issues/warnings/user_modeling.py +0 -0
  93. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/__init__.py +0 -0
  94. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/_constants.py +0 -0
  95. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/_shared.py +0 -0
  96. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/analysis/__init__.py +0 -0
  97. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/analysis/_base.py +0 -0
  98. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/analysis/_dms.py +0 -0
  99. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/analysis/_information.py +0 -0
  100. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/catalog/__init__.py +0 -0
  101. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/catalog/hello_world_pump.xlsx +0 -0
  102. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
  103. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/exporters/__init__.py +0 -0
  104. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/exporters/_base.py +0 -0
  105. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/exporters/_rules2dms.py +0 -0
  106. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/exporters/_rules2excel.py +0 -0
  107. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/exporters/_rules2instance_template.py +0 -0
  108. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/exporters/_rules2ontology.py +0 -0
  109. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/exporters/_rules2yaml.py +0 -0
  110. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/exporters/_validation.py +0 -0
  111. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/__init__.py +0 -0
  112. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_base.py +0 -0
  113. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_dms2rules.py +0 -0
  114. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_dtdl2rules/__init__.py +0 -0
  115. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_dtdl2rules/_unit_lookup.py +0 -0
  116. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_converter.py +0 -0
  117. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_importer.py +0 -0
  118. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_dtdl2rules/spec.py +0 -0
  119. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_rdf/__init__.py +0 -0
  120. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_rdf/_base.py +0 -0
  121. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_rdf/_imf2rules.py +0 -0
  122. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_rdf/_owl2rules.py +0 -0
  123. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_rdf/_shared.py +0 -0
  124. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_spreadsheet2rules.py +0 -0
  125. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/importers/_yaml2rules.py +0 -0
  126. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/__init__.py +0 -0
  127. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/_base_input.py +0 -0
  128. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/_base_rules.py +0 -0
  129. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/_rdfpath.py +0 -0
  130. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/_types.py +0 -0
  131. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/data_types.py +0 -0
  132. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/dms/__init__.py +0 -0
  133. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/dms/_exporter.py +0 -0
  134. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/dms/_rules.py +0 -0
  135. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/dms/_rules_input.py +0 -0
  136. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/dms/_validation.py +0 -0
  137. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/entities/__init__.py +0 -0
  138. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/entities/_constants.py +0 -0
  139. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/entities/_loaders.py +0 -0
  140. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/entities/_multi_value.py +0 -0
  141. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/entities/_single_value.py +0 -0
  142. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/entities/_types.py +0 -0
  143. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/entities/_wrapped.py +0 -0
  144. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/information/__init__.py +0 -0
  145. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/information/_rules.py +0 -0
  146. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/information/_rules_input.py +0 -0
  147. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/information/_validation.py +0 -0
  148. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/mapping/__init__.py +0 -0
  149. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/models/mapping/_classic2core.py +0 -0
  150. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/transformers/__init__.py +0 -0
  151. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/transformers/_base.py +0 -0
  152. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/transformers/_converters.py +0 -0
  153. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_rules/transformers/_verification.py +0 -0
  154. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/__init__.py +0 -0
  155. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_collector.py +0 -0
  156. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_drop.py +0 -0
  157. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_show.py +0 -0
  158. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/_wizard.py +0 -0
  159. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/engine/__init__.py +0 -0
  160. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/engine/_import.py +0 -0
  161. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/engine/_interface.py +0 -0
  162. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/engine/_load.py +0 -0
  163. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_session/exceptions.py +0 -0
  164. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_shared.py +0 -0
  165. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_store/__init__.py +0 -0
  166. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_store/_provenance.py +0 -0
  167. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_store/_rules_store.py +0 -0
  168. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_store/exceptions.py +0 -0
  169. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/__init__.py +0 -0
  170. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/auxiliary.py +0 -0
  171. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/graph_transformations_report.py +0 -0
  172. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/io_.py +0 -0
  173. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/rdf_.py +0 -0
  174. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/reader/__init__.py +0 -0
  175. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/reader/_base.py +0 -0
  176. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/spreadsheet.py +0 -0
  177. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/text.py +0 -0
  178. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/time_.py +0 -0
  179. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/upload.py +0 -0
  180. {cognite_neat-0.105.1 → cognite_neat-0.106.0}/cognite/neat/_utils/xml_.py +0 -0
  181. {cognite_neat-0.105.1 → cognite_neat-0.106.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.105.1
3
+ Version: 0.106.0
4
4
  Summary: Knowledge graph transformation
5
5
  Home-page: https://cognite-neat.readthedocs-hosted.com/
6
6
  License: Apache-2.0
@@ -17,13 +17,11 @@ Provides-Extra: all
17
17
  Provides-Extra: docs
18
18
  Provides-Extra: google
19
19
  Provides-Extra: oxi
20
- Provides-Extra: service
21
20
  Requires-Dist: PyYAML
22
21
  Requires-Dist: backports.strenum (>=1.2,<2.0) ; python_version < "3.11"
23
22
  Requires-Dist: cognite-sdk (>=7.71.2,<8.0.0)
24
23
  Requires-Dist: elementpath (>=4.0.0,<5.0.0)
25
24
  Requires-Dist: exceptiongroup (>=1.1.3,<2.0.0) ; python_version < "3.11"
26
- Requires-Dist: fastapi (>=0,<1) ; extra == "service" or extra == "all"
27
25
  Requires-Dist: google-api-python-client ; extra == "google"
28
26
  Requires-Dist: google-auth-oauthlib ; extra == "google"
29
27
  Requires-Dist: gspread ; extra == "google"
@@ -45,20 +43,16 @@ Requires-Dist: openpyxl
45
43
  Requires-Dist: oxrdflib[oxigraph] (>=0.4.0,<0.5.0) ; extra == "oxi" or extra == "all"
46
44
  Requires-Dist: packaging (>=22.0,<25.0)
47
45
  Requires-Dist: pandas
48
- Requires-Dist: prometheus-client (>=0,<1) ; extra == "service" or extra == "all"
49
46
  Requires-Dist: pydantic (>=2,<3)
50
47
  Requires-Dist: pymdown-extensions ; extra == "docs"
51
48
  Requires-Dist: pyoxigraph (==0.4.3) ; extra == "oxi" or extra == "all"
52
- Requires-Dist: python-multipart (==0.0.9) ; extra == "service" or extra == "all"
53
49
  Requires-Dist: pyvis (>=0.3.2,<0.4.0)
54
50
  Requires-Dist: rdflib
55
51
  Requires-Dist: requests
56
52
  Requires-Dist: rich[jupyter] (>=13.7.1,<14.0.0)
57
- Requires-Dist: schedule (>=1,<2) ; extra == "service" or extra == "all"
58
53
  Requires-Dist: tomli (>=2.0.1,<3.0.0) ; python_version < "3.11"
59
54
  Requires-Dist: typing_extensions (>=4.8,<5.0) ; python_version < "3.11"
60
55
  Requires-Dist: urllib3 (>=2,<3)
61
- Requires-Dist: uvicorn[standard] (>=0,<1) ; extra == "service" or extra == "all"
62
56
  Project-URL: Documentation, https://cognite-neat.readthedocs-hosted.com/
63
57
  Project-URL: Repository, https://github.com/cognitedata/neat
64
58
  Description-Content-Type: text/markdown
@@ -0,0 +1,11 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class NeatConfig(BaseModel, validate_assignment=True):
7
+ progress_bar: Literal["tqdm", "rich", "tqdm-notebook", "infer"] | None = "infer"
8
+ use_iterate_bar_threshold: int | None = 500
9
+
10
+
11
+ GLOBAL_CONFIG = NeatConfig()
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  import re
3
3
  import sys
4
+ import warnings
4
5
  from abc import ABC, abstractmethod
5
6
  from collections.abc import Callable, Iterable, Sequence, Set
6
7
  from datetime import datetime, timezone
@@ -9,13 +10,16 @@ from typing import Any, Generic, TypeVar
9
10
 
10
11
  from cognite.client import CogniteClient
11
12
  from cognite.client.data_classes._base import WriteableCogniteResource
13
+ from cognite.client.exceptions import CogniteAPIError
12
14
  from pydantic import AnyHttpUrl, ValidationError
13
15
  from rdflib import RDF, XSD, Literal, Namespace, URIRef
14
16
 
15
17
  from cognite.neat._constants import DEFAULT_NAMESPACE
16
18
  from cognite.neat._graph.extractors._base import BaseExtractor
19
+ from cognite.neat._issues.warnings import CDFAuthWarning
17
20
  from cognite.neat._shared import Triple
18
21
  from cognite.neat._utils.auxiliary import string_to_ideal_type
22
+ from cognite.neat._utils.collection_ import iterate_progress_bar_if_above_config_threshold
19
23
 
20
24
  T_CogniteResource = TypeVar("T_CogniteResource", bound=WriteableCogniteResource)
21
25
 
@@ -98,17 +102,11 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
98
102
 
99
103
  def extract(self) -> Iterable[Triple]:
100
104
  """Extracts an asset with the given asset_id."""
101
- if self.total:
102
- try:
103
- from rich.progress import track
104
- except ModuleNotFoundError:
105
- to_iterate = self.items
106
- else:
107
- to_iterate = track(
108
- self.items,
109
- total=self.limit or self.total,
110
- description=f"Extracting {type(self).__name__.removesuffix('Extractor')}",
111
- )
105
+
106
+ if self.total is not None and self.total > 0:
107
+ to_iterate = iterate_progress_bar_if_above_config_threshold(
108
+ self.items, self.total, f"Extracting {type(self).__name__.removesuffix('Extractor')}"
109
+ )
112
110
  else:
113
111
  to_iterate = self.items
114
112
  for no, asset in enumerate(to_iterate):
@@ -221,7 +219,7 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
221
219
  camel_case: bool = True,
222
220
  as_write: bool = False,
223
221
  ):
224
- total, items = cls._from_dataset(client, data_set_external_id)
222
+ total, items = cls._handle_no_access(lambda: cls._from_dataset(client, data_set_external_id))
225
223
  return cls(items, namespace, to_type, total, limit, unpack_metadata, skip_metadata_values, camel_case, as_write)
226
224
 
227
225
  @classmethod
@@ -244,7 +242,7 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
244
242
  camel_case: bool = True,
245
243
  as_write: bool = False,
246
244
  ):
247
- total, items = cls._from_hierarchy(client, root_asset_external_id)
245
+ total, items = cls._handle_no_access(lambda: cls._from_hierarchy(client, root_asset_external_id))
248
246
  return cls(items, namespace, to_type, total, limit, unpack_metadata, skip_metadata_values, camel_case, as_write)
249
247
 
250
248
  @classmethod
@@ -273,3 +271,18 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
273
271
  @abstractmethod
274
272
  def _from_file(cls, file_path: str | Path) -> tuple[int | None, Iterable[T_CogniteResource]]:
275
273
  raise NotImplementedError
274
+
275
+ @classmethod
276
+ def _handle_no_access(
277
+ cls, action: Callable[[], tuple[int | None, Iterable[T_CogniteResource]]]
278
+ ) -> tuple[int | None, Iterable[T_CogniteResource]]:
279
+ try:
280
+ return action()
281
+ except CogniteAPIError as e:
282
+ if e.code == 403:
283
+ warnings.warn(
284
+ CDFAuthWarning(f"extract {cls.__name__.removesuffix('Extractor').casefold()}", str(e)), stacklevel=2
285
+ )
286
+ return 0, []
287
+ else:
288
+ raise e
@@ -226,4 +226,7 @@ class ClassicGraphExtractor(BaseExtractor):
226
226
  @staticmethod
227
227
  def _chunk(items: Sequence, description: str) -> Iterable:
228
228
  to_iterate: Iterable = chunker(items, chunk_size=1000)
229
- return iterate_progress_bar(to_iterate, (len(items) // 1_000) + 1, description)
229
+ if items:
230
+ return iterate_progress_bar(to_iterate, (len(items) // 1_000) + 1, description)
231
+ else:
232
+ return to_iterate
@@ -73,7 +73,7 @@ class SequencesExtractor(ClassicCDFBaseExtractor[NeatSequence]):
73
73
  as_write: bool = False,
74
74
  unpack_columns: bool = False,
75
75
  ):
76
- total, items = cls._from_dataset(client, data_set_external_id)
76
+ total, items = cls._handle_no_access(lambda: cls._from_dataset(client, data_set_external_id))
77
77
  return cls(
78
78
  items,
79
79
  namespace,
@@ -101,7 +101,7 @@ class SequencesExtractor(ClassicCDFBaseExtractor[NeatSequence]):
101
101
  as_write: bool = False,
102
102
  unpack_columns: bool = False,
103
103
  ):
104
- total, items = cls._from_hierarchy(client, root_asset_external_id)
104
+ total, items = cls._handle_no_access(lambda: cls._from_hierarchy(client, root_asset_external_id))
105
105
  return cls(
106
106
  items,
107
107
  namespace,
@@ -37,6 +37,7 @@ from cognite.neat._rules.models.entities._single_value import ViewEntity
37
37
  from cognite.neat._shared import InstanceType
38
38
  from cognite.neat._store import NeatGraphStore
39
39
  from cognite.neat._utils.auxiliary import create_sha256_hash
40
+ from cognite.neat._utils.collection_ import iterate_progress_bar_if_above_config_threshold
40
41
  from cognite.neat._utils.rdf_ import remove_namespace_from_uri
41
42
  from cognite.neat._utils.upload import UploadResult
42
43
 
@@ -157,7 +158,7 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
157
158
  view_ids.append(f"{view_id!r} (self)")
158
159
 
159
160
  tracker = self._tracker(type(self).__name__, view_ids, "views")
160
- for view_id, (view, _) in view_and_count_by_id.items():
161
+ for view_id, (view, instance_count) in view_and_count_by_id.items():
161
162
  pydantic_cls, edge_by_type, issues = self._create_validation_classes(view) # type: ignore[var-annotated]
162
163
  yield from issues
163
164
  tracker.issue(issues)
@@ -194,7 +195,11 @@ class DMSLoader(CDFLoader[dm.InstanceApply]):
194
195
  # this assumes no changes in the suffix of view and class
195
196
  reader = self.graph_store.read(view.external_id)
196
197
 
197
- for identifier, properties in reader:
198
+ instance_iterable = iterate_progress_bar_if_above_config_threshold(
199
+ reader, instance_count, f"Loading {track_id}"
200
+ )
201
+
202
+ for identifier, properties in instance_iterable:
198
203
  if skip_properties:
199
204
  properties = {k: v for k, v in properties.items() if k not in skip_properties}
200
205
  try:
@@ -8,7 +8,7 @@ from rdflib.query import ResultRow
8
8
 
9
9
  from cognite.neat._issues.warnings import NeatValueWarning
10
10
  from cognite.neat._shared import Triple
11
- from cognite.neat._utils.collection_ import iterate_progress_bar
11
+ from cognite.neat._utils.collection_ import iterate_progress_bar_if_above_config_threshold
12
12
  from cognite.neat._utils.graph_transformations_report import GraphTransformationResult
13
13
 
14
14
  To_Add_Triples: TypeAlias = list[Triple]
@@ -42,7 +42,6 @@ class BaseTransformerStandardised(ABC):
42
42
  description: str
43
43
  _use_only_once: bool = False
44
44
  _need_changes: ClassVar[frozenset[str]] = frozenset()
45
- _use_iterate_bar_threshold: int = 500
46
45
 
47
46
  @abstractmethod
48
47
  def operation(self, query_result_row: ResultRow) -> RowTransformationOutput:
@@ -99,12 +98,9 @@ class BaseTransformerStandardised(ABC):
99
98
  return outcome
100
99
 
101
100
  result_iterable = graph.query(self._iterate_query())
102
- if iteration_count > self._use_iterate_bar_threshold:
103
- result_iterable = iterate_progress_bar( # type: ignore[misc, assignment]
104
- result_iterable,
105
- total=iteration_count,
106
- description=self.description,
107
- )
101
+ result_iterable = iterate_progress_bar_if_above_config_threshold(
102
+ result_iterable, iteration_count, self.description
103
+ )
108
104
 
109
105
  for row in result_iterable:
110
106
  row = cast(ResultRow, row)
@@ -1,4 +1,3 @@
1
- import textwrap
2
1
  import warnings
3
2
  from abc import ABC
4
3
  from collections.abc import Callable, Iterable
@@ -15,6 +14,7 @@ from cognite.neat._utils.collection_ import iterate_progress_bar
15
14
  from cognite.neat._utils.rdf_ import (
16
15
  Triple,
17
16
  add_triples_in_batch,
17
+ get_namespace,
18
18
  remove_instance_ids_in_batch,
19
19
  remove_namespace_from_uri,
20
20
  )
@@ -72,91 +72,165 @@ class AddAssetDepth(BaseTransformerStandardised):
72
72
  return row_output
73
73
 
74
74
 
75
- # TODO: standardise
76
- class BaseAssetConnector(BaseTransformer, ABC):
77
- _asset_type: URIRef = DEFAULT_NAMESPACE.Asset
78
- _item_type: URIRef
79
- _default_attribute: URIRef
80
- _connection_type: URIRef
75
+ class BaseAssetConnector(BaseTransformerStandardised, ABC):
76
+ description: str = "Connects assets to other cognite resources, thus forming bi-directional connection"
77
+ _use_only_once: bool = True
81
78
 
82
- _select_item_ids = "SELECT DISTINCT ?item_id WHERE {{?item_id a <{item_type}>}}"
83
- _select_connected_assets: str = textwrap.dedent("""SELECT ?asset_id WHERE {{
84
- <{item_id}> <{attribute}> ?asset_id .
85
- ?asset_id a <{asset_type}>}}""")
79
+ def _count_query(self) -> str:
80
+ query = """SELECT (COUNT(?asset) as ?count)
81
+ WHERE {{
82
+ ?resource a <{resource_type}> .
83
+ ?resource <{connection}> ?asset .
84
+ ?asset a <{asset_type}> .
85
+ }}"""
86
86
 
87
- def __init__(self, attribute: URIRef | None = None) -> None:
88
- self._attribute = attribute or self._default_attribute
87
+ return query.format(
88
+ asset_type=self.asset_type,
89
+ resource_type=self.resource_type,
90
+ connection=self.resource_to_asset_connection,
91
+ )
89
92
 
90
- def transform(self, graph: Graph) -> None:
91
- for item_id, *_ in graph.query(self._select_item_ids.format(item_type=self._item_type)): # type: ignore[misc]
92
- triples: list[Triple] = []
93
- for asset_id, *_ in graph.query( # type: ignore[misc]
94
- self._select_connected_assets.format(
95
- item_id=item_id, attribute=self._attribute, asset_type=self._asset_type
96
- )
97
- ):
98
- triples.append((asset_id, self._connection_type, item_id)) # type: ignore[arg-type]
99
- add_triples_in_batch(graph, triples)
93
+ def _iterate_query(self) -> str:
94
+ query = """SELECT ?asset ?resource
95
+ WHERE {{
96
+ ?resource a <{resource_type}> .
97
+ ?resource <{connection}> ?asset .
98
+ ?asset a <{asset_type}> .
99
+ }}"""
100
+
101
+ return query.format(
102
+ asset_type=self.asset_type,
103
+ resource_type=self.resource_type,
104
+ connection=self.resource_to_asset_connection,
105
+ )
106
+
107
+ def __init__(
108
+ self,
109
+ resource_to_asset_connection: URIRef,
110
+ resource_type: URIRef,
111
+ asset_to_resource_connection: URIRef | None = None,
112
+ asset_type: URIRef | None = None,
113
+ ) -> None:
114
+ self.asset_type = asset_type or DEFAULT_NAMESPACE.Asset
115
+ self.resource_to_asset_connection = resource_to_asset_connection
116
+ self.resource_type = resource_type
117
+
118
+ if asset_to_resource_connection:
119
+ self.asset_to_resource_connection = asset_to_resource_connection
120
+ else:
121
+ namespace = Namespace(get_namespace(resource_type))
122
+ type_ = remove_namespace_from_uri(resource_type)
123
+ self.asset_to_resource_connection = namespace[type_[0].lower() + type_[1:]]
124
+
125
+ def operation(self, query_result_row: ResultRow) -> RowTransformationOutput:
126
+ row_output = RowTransformationOutput()
127
+ subject, object = query_result_row
128
+
129
+ row_output.add_triples.append(cast(Triple, (subject, self.asset_to_resource_connection, object)))
130
+
131
+ row_output.instances_modified_count += 1
132
+
133
+ return row_output
100
134
 
101
135
 
102
136
  class AssetTimeSeriesConnector(BaseAssetConnector):
103
137
  description: str = "Connects assets to timeseries, thus forming bi-directional connection"
104
- _use_only_once: bool = True
105
138
  _need_changes = frozenset(
106
139
  {
107
140
  str(extractors.AssetsExtractor.__name__),
108
141
  str(extractors.TimeSeriesExtractor.__name__),
109
142
  }
110
143
  )
111
- _item_type = DEFAULT_NAMESPACE.TimeSeries
112
- _default_attribute = DEFAULT_NAMESPACE.assetId
113
- _connection_type = DEFAULT_NAMESPACE.timeSeries
144
+
145
+ def __init__(
146
+ self,
147
+ resource_to_asset_connection: URIRef | None = None,
148
+ resource_type: URIRef | None = None,
149
+ asset_to_resource_connection: URIRef | None = None,
150
+ asset_type: URIRef | None = None,
151
+ ):
152
+ super().__init__(
153
+ resource_to_asset_connection=resource_to_asset_connection or DEFAULT_NAMESPACE.assetId,
154
+ resource_type=resource_type or DEFAULT_NAMESPACE.TimeSeries,
155
+ asset_to_resource_connection=asset_to_resource_connection or DEFAULT_NAMESPACE.timeSeries,
156
+ asset_type=asset_type or DEFAULT_NAMESPACE.Asset,
157
+ )
114
158
 
115
159
 
116
160
  class AssetSequenceConnector(BaseAssetConnector):
117
161
  description: str = "Connects assets to sequences, thus forming bi-directional connection"
118
- _use_only_once: bool = True
119
162
  _need_changes = frozenset(
120
163
  {
121
164
  str(extractors.AssetsExtractor.__name__),
122
165
  str(extractors.SequencesExtractor.__name__),
123
166
  }
124
167
  )
125
- _item_type = DEFAULT_NAMESPACE.Sequence
126
- _default_attribute = DEFAULT_NAMESPACE.assetId
127
- _connection_type = DEFAULT_NAMESPACE.sequence
168
+
169
+ def __init__(
170
+ self,
171
+ resource_to_asset_connection: URIRef | None = None,
172
+ resource_type: URIRef | None = None,
173
+ asset_to_resource_connection: URIRef | None = None,
174
+ asset_type: URIRef | None = None,
175
+ ):
176
+ super().__init__(
177
+ resource_to_asset_connection=resource_to_asset_connection or DEFAULT_NAMESPACE.assetId,
178
+ resource_type=resource_type or DEFAULT_NAMESPACE.Sequence,
179
+ asset_to_resource_connection=asset_to_resource_connection or DEFAULT_NAMESPACE.sequence,
180
+ asset_type=asset_type or DEFAULT_NAMESPACE.Asset,
181
+ )
128
182
 
129
183
 
130
184
  class AssetFileConnector(BaseAssetConnector):
131
185
  description: str = "Connects assets to files, thus forming bi-directional connection"
132
- _use_only_once: bool = True
133
186
  _need_changes = frozenset(
134
187
  {
135
188
  str(extractors.AssetsExtractor.__name__),
136
189
  str(extractors.FilesExtractor.__name__),
137
190
  }
138
191
  )
139
- _item_type = DEFAULT_NAMESPACE.File
140
- _default_attribute = DEFAULT_NAMESPACE.assetIds
141
- _connection_type = DEFAULT_NAMESPACE.file
192
+
193
+ def __init__(
194
+ self,
195
+ resource_to_asset_connection: URIRef | None = None,
196
+ resource_type: URIRef | None = None,
197
+ asset_to_resource_connection: URIRef | None = None,
198
+ asset_type: URIRef | None = None,
199
+ ):
200
+ super().__init__(
201
+ resource_to_asset_connection=resource_to_asset_connection or DEFAULT_NAMESPACE.assetIds,
202
+ resource_type=resource_type or DEFAULT_NAMESPACE.File,
203
+ asset_to_resource_connection=asset_to_resource_connection or DEFAULT_NAMESPACE.file,
204
+ asset_type=asset_type or DEFAULT_NAMESPACE.Asset,
205
+ )
142
206
 
143
207
 
144
208
  class AssetEventConnector(BaseAssetConnector):
145
209
  description: str = "Connects assets to events, thus forming bi-directional connection"
146
- _use_only_once: bool = True
147
210
  _need_changes = frozenset(
148
211
  {
149
212
  str(extractors.AssetsExtractor.__name__),
150
213
  str(extractors.EventsExtractor.__name__),
151
214
  }
152
215
  )
153
- _item_type = DEFAULT_NAMESPACE.Event
154
- _default_attribute = DEFAULT_NAMESPACE.assetIds
155
- _connection_type = DEFAULT_NAMESPACE.event
216
+
217
+ def __init__(
218
+ self,
219
+ resource_to_asset_connection: URIRef | None = None,
220
+ resource_type: URIRef | None = None,
221
+ asset_to_resource_connection: URIRef | None = None,
222
+ asset_type: URIRef | None = None,
223
+ ):
224
+ super().__init__(
225
+ resource_to_asset_connection=resource_to_asset_connection or DEFAULT_NAMESPACE.assetIds,
226
+ resource_type=resource_type or DEFAULT_NAMESPACE.Event,
227
+ asset_to_resource_connection=asset_to_resource_connection or DEFAULT_NAMESPACE.event,
228
+ asset_type=asset_type or DEFAULT_NAMESPACE.Asset,
229
+ )
156
230
 
157
231
 
158
232
  # TODO: standardise
159
- class AssetRelationshipConnector(BaseTransformer):
233
+ class AssetRelationshipConnector(BaseTransformerStandardised):
160
234
  description: str = "Connects assets via relationships"
161
235
  _use_only_once: bool = True
162
236
  _need_changes = frozenset(
@@ -174,6 +248,44 @@ class AssetRelationshipConnector(BaseTransformer):
174
248
  ?target <{asset_xid_property}> ?target_xid .
175
249
  ?target a <{asset_type}> .}}"""
176
250
 
251
+ def _count_query(self) -> str:
252
+ query = """SELECT (COUNT(?target) as ?count) WHERE {{
253
+ ?relationship a <{relationship_type}> .
254
+ ?relationship <{relationship_source_xid_prop}> ?source_xid .
255
+ ?source <{asset_xid_property}> ?source_xid .
256
+ ?source a <{asset_type}> .
257
+
258
+ ?relationship <{relationship_target_xid_prop}> ?target_xid .
259
+ ?target <{asset_xid_property}> ?target_xid .
260
+ ?target a <{asset_type}> .}}"""
261
+
262
+ return query.format(
263
+ relationship_type=self.relationship_type,
264
+ relationship_source_xid_prop=self.relationship_source_xid_prop,
265
+ relationship_target_xid_prop=self.relationship_target_xid_prop,
266
+ asset_xid_property=self.asset_xid_property,
267
+ asset_type=self.asset_type,
268
+ )
269
+
270
+ def _iterate_query(self) -> str:
271
+ query = """SELECT ?source ?relationship ?target WHERE {{
272
+ ?relationship a <{relationship_type}> .
273
+ ?relationship <{relationship_source_xid_prop}> ?source_xid .
274
+ ?source <{asset_xid_property}> ?source_xid .
275
+ ?source a <{asset_type}> .
276
+
277
+ ?relationship <{relationship_target_xid_prop}> ?target_xid .
278
+ ?target <{asset_xid_property}> ?target_xid .
279
+ ?target a <{asset_type}> .}}"""
280
+
281
+ return query.format(
282
+ relationship_type=self.relationship_type,
283
+ relationship_source_xid_prop=self.relationship_source_xid_prop,
284
+ relationship_target_xid_prop=self.relationship_target_xid_prop,
285
+ asset_xid_property=self.asset_xid_property,
286
+ asset_type=self.asset_type,
287
+ )
288
+
177
289
  def __init__(
178
290
  self,
179
291
  asset_type: URIRef | None = None,
@@ -188,48 +300,20 @@ class AssetRelationshipConnector(BaseTransformer):
188
300
  self.relationship_target_xid_prop = relationship_target_xid_prop or DEFAULT_NAMESPACE.targetExternalId
189
301
  self.asset_xid_property = asset_xid_property or DEFAULT_NAMESPACE.externalId
190
302
 
191
- def transform(self, graph: Graph) -> None:
192
- for relationship_id_result in graph.query(
193
- f"SELECT DISTINCT ?relationship_id WHERE {{?relationship_id a <{self.relationship_type}>}}"
194
- ):
195
- relationship_id: URIRef = cast(tuple, relationship_id_result)[0]
196
-
197
- if assets_id_res := list(
198
- graph.query(
199
- self._asset_template.format(
200
- relationship_id=relationship_id,
201
- asset_xid_property=self.asset_xid_property,
202
- relationship_source_xid_prop=self.relationship_source_xid_prop,
203
- relationship_target_xid_prop=self.relationship_target_xid_prop,
204
- asset_type=self.asset_type,
205
- )
206
- )
207
- ):
208
- # files can be connected to multiple assets in the graph
209
- for source_asset_id, target_asset_id in cast(list[tuple], assets_id_res):
210
- # create a relationship between the two assets
211
- graph.add(
212
- (
213
- source_asset_id,
214
- DEFAULT_NAMESPACE.relationship,
215
- relationship_id,
216
- )
217
- )
218
- graph.add(
219
- (
220
- target_asset_id,
221
- DEFAULT_NAMESPACE.relationship,
222
- relationship_id,
223
- )
224
- )
303
+ def operation(self, query_result_row: ResultRow) -> RowTransformationOutput:
304
+ row_output = RowTransformationOutput()
305
+ source, relationship, target = query_result_row
306
+
307
+ row_output.add_triples.append(cast(Triple, (source, DEFAULT_NAMESPACE.relationship, target)))
308
+ row_output.add_triples.append(cast(Triple, (relationship, DEFAULT_NAMESPACE.source, source)))
309
+ row_output.add_triples.append(cast(Triple, (relationship, DEFAULT_NAMESPACE.target, target)))
225
310
 
226
- # add source and target to the relationship
227
- graph.add((relationship_id, DEFAULT_NAMESPACE.source, source_asset_id))
228
- graph.add((relationship_id, DEFAULT_NAMESPACE.target, target_asset_id))
311
+ row_output.remove_triples.append(cast(Triple, (relationship, self.relationship_source_xid_prop, None)))
312
+ row_output.remove_triples.append(cast(Triple, (relationship, self.relationship_target_xid_prop, None)))
229
313
 
230
- # remove properties that are not needed, specifically the external ids
231
- graph.remove((relationship_id, self.relationship_source_xid_prop, None))
232
- graph.remove((relationship_id, self.relationship_target_xid_prop, None))
314
+ row_output.instances_modified_count += 2
315
+
316
+ return row_output
233
317
 
234
318
 
235
319
  # TODO: standardise
@@ -59,7 +59,7 @@ class AddSelfReferenceProperty(BaseTransformer):
59
59
 
60
60
  class MakeConnectionOnExactMatch(BaseTransformerStandardised):
61
61
  description: str = "Adds property that contains id of reference to all references of given class in Rules"
62
- _use_only_once: bool = True
62
+ _use_only_once: bool = False
63
63
  _need_changes = frozenset({})
64
64
 
65
65
  def __init__(
@@ -42,7 +42,7 @@ class FileItemNotSupportedWarning(NeatWarning):
42
42
 
43
43
  @dataclass(unsafe_hash=True)
44
44
  class CDFAuthWarning(NeatWarning):
45
- """Failed to {action} due to {reason}"""
45
+ """Failed to {action}: {reason}"""
46
46
 
47
47
  action: str
48
48
  reason: str
@@ -17,6 +17,7 @@ from cognite.neat._rules.models.information import (
17
17
  )
18
18
  from cognite.neat._store import NeatGraphStore
19
19
  from cognite.neat._store._provenance import INSTANCES_ENTITY
20
+ from cognite.neat._utils.collection_ import iterate_progress_bar
20
21
  from cognite.neat._utils.rdf_ import remove_namespace_from_uri, uri_to_short_form
21
22
 
22
23
  from ._base import DEFAULT_NON_EXISTING_NODE_TYPE, BaseRDFImporter
@@ -27,7 +28,6 @@ ORDERED_CLASSES_QUERY = """SELECT ?class (count(?s) as ?instances )
27
28
  WHERE { ?s a ?class . }
28
29
  group by ?class order by DESC(?instances)"""
29
30
 
30
-
31
31
  INSTANCES_OF_CLASS_QUERY = """SELECT ?s ?propertyCount WHERE { ?s a <class> . BIND ('Unknown' as ?propertyCount) }"""
32
32
 
33
33
 
@@ -171,8 +171,10 @@ class InferenceImporter(BaseRDFImporter):
171
171
  INSTANCES_OF_CLASS_QUERY if self.max_number_of_instance == -1 else INSTANCES_OF_CLASS_RICHNESS_ORDERED_QUERY
172
172
  )
173
173
 
174
+ classes_iterable = iterate_progress_bar(classes.items(), len(classes), "Inferring classes")
175
+
174
176
  # Infers all the properties of the class
175
- for class_id, class_definition in classes.items():
177
+ for class_id, class_definition in classes_iterable:
176
178
  for ( # type: ignore[misc]
177
179
  instance,
178
180
  _,