cognite-neat 0.92.3__py3-none-any.whl → 0.94.0__py3-none-any.whl

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 (289) hide show
  1. cognite/neat/__init__.py +3 -2
  2. cognite/neat/{app → _app}/api/configuration.py +9 -7
  3. cognite/neat/_app/api/context_manager/__init__.py +3 -0
  4. cognite/neat/{app → _app}/api/context_manager/manager.py +1 -1
  5. cognite/neat/{app → _app}/api/explorer.py +5 -5
  6. cognite/neat/{app → _app}/api/routers/configuration.py +2 -2
  7. cognite/neat/{app → _app}/api/routers/crud.py +4 -4
  8. cognite/neat/{app → _app}/api/routers/workflows.py +7 -7
  9. cognite/neat/{app → _app}/main.py +1 -1
  10. cognite/neat/_app/ui/neat-app/package-lock.json +18306 -0
  11. cognite/neat/_app/ui/neat-app/package.json +62 -0
  12. cognite/neat/_app/ui/neat-app/public/favicon.ico +0 -0
  13. cognite/neat/_app/ui/neat-app/public/img/architect-icon.svg +116 -0
  14. cognite/neat/_app/ui/neat-app/public/img/developer-icon.svg +112 -0
  15. cognite/neat/_app/ui/neat-app/public/img/sme-icon.svg +34 -0
  16. cognite/neat/_app/ui/neat-app/public/index.html +43 -0
  17. cognite/neat/_app/ui/neat-app/public/logo192.png +0 -0
  18. cognite/neat/_app/ui/neat-app/public/manifest.json +25 -0
  19. cognite/neat/_app/ui/neat-app/public/robots.txt +3 -0
  20. cognite/neat/_app/ui/neat-app/src/App.css +38 -0
  21. cognite/neat/_app/ui/neat-app/src/App.js +17 -0
  22. cognite/neat/_app/ui/neat-app/src/App.test.js +8 -0
  23. cognite/neat/_app/ui/neat-app/src/MainContainer.tsx +70 -0
  24. cognite/neat/_app/ui/neat-app/src/components/JsonViewer.tsx +43 -0
  25. cognite/neat/_app/ui/neat-app/src/components/LocalUploader.tsx +124 -0
  26. cognite/neat/_app/ui/neat-app/src/components/OverviewComponentEditorDialog.tsx +63 -0
  27. cognite/neat/_app/ui/neat-app/src/components/StepEditorDialog.tsx +511 -0
  28. cognite/neat/_app/ui/neat-app/src/components/TabPanel.tsx +36 -0
  29. cognite/neat/_app/ui/neat-app/src/components/Utils.tsx +56 -0
  30. cognite/neat/_app/ui/neat-app/src/components/WorkflowDeleteDialog.tsx +60 -0
  31. cognite/neat/_app/ui/neat-app/src/components/WorkflowExecutionReport.tsx +112 -0
  32. cognite/neat/_app/ui/neat-app/src/components/WorkflowImportExportDialog.tsx +67 -0
  33. cognite/neat/_app/ui/neat-app/src/components/WorkflowMetadataDialog.tsx +79 -0
  34. cognite/neat/_app/ui/neat-app/src/index.css +13 -0
  35. cognite/neat/_app/ui/neat-app/src/index.js +13 -0
  36. cognite/neat/_app/ui/neat-app/src/logo.svg +1 -0
  37. cognite/neat/_app/ui/neat-app/src/reportWebVitals.js +13 -0
  38. cognite/neat/_app/ui/neat-app/src/setupTests.js +5 -0
  39. cognite/neat/_app/ui/neat-app/src/types/WorkflowTypes.ts +388 -0
  40. cognite/neat/_app/ui/neat-app/src/views/AboutView.tsx +61 -0
  41. cognite/neat/_app/ui/neat-app/src/views/ConfigView.tsx +184 -0
  42. cognite/neat/_app/ui/neat-app/src/views/GlobalConfigView.tsx +180 -0
  43. cognite/neat/_app/ui/neat-app/src/views/WorkflowView.tsx +570 -0
  44. cognite/neat/_app/ui/neat-app/tsconfig.json +27 -0
  45. cognite/neat/{config.py → _config.py} +3 -3
  46. cognite/neat/{constants.py → _constants.py} +13 -5
  47. cognite/neat/_graph/_shared.py +34 -0
  48. cognite/neat/{graph → _graph}/_tracking/base.py +1 -1
  49. cognite/neat/{graph → _graph}/_tracking/log.py +1 -1
  50. cognite/neat/{graph → _graph}/extractors/__init__.py +5 -0
  51. cognite/neat/{graph → _graph}/extractors/_base.py +2 -2
  52. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_assets.py +1 -1
  53. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_base.py +4 -4
  54. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_classic.py +5 -5
  55. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_data_sets.py +1 -1
  56. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_events.py +1 -1
  57. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_files.py +1 -1
  58. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_labels.py +1 -1
  59. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_relationships.py +2 -2
  60. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_sequences.py +1 -1
  61. cognite/neat/{graph → _graph}/extractors/_classic_cdf/_timeseries.py +1 -1
  62. cognite/neat/{graph → _graph}/extractors/_dexpi.py +5 -5
  63. cognite/neat/{graph → _graph}/extractors/_dms.py +3 -3
  64. cognite/neat/_graph/extractors/_iodd.py +402 -0
  65. cognite/neat/{graph → _graph}/extractors/_mock_graph_generator.py +9 -8
  66. cognite/neat/_graph/extractors/_rdf_file.py +49 -0
  67. cognite/neat/{graph → _graph}/loaders/_base.py +5 -5
  68. cognite/neat/{graph → _graph}/loaders/_rdf2asset.py +11 -10
  69. cognite/neat/{graph → _graph}/loaders/_rdf2dms.py +10 -10
  70. cognite/neat/{graph → _graph}/queries/_base.py +91 -19
  71. cognite/neat/{graph → _graph}/queries/_construct.py +5 -5
  72. cognite/neat/{graph → _graph}/queries/_shared.py +3 -3
  73. cognite/neat/{graph → _graph}/transformers/__init__.py +6 -0
  74. cognite/neat/{graph → _graph}/transformers/_classic_cdf.py +135 -3
  75. cognite/neat/_graph/transformers/_iodd.py +25 -0
  76. cognite/neat/_graph/transformers/_prune_graph.py +126 -0
  77. cognite/neat/{graph → _graph}/transformers/_rdfpath.py +3 -3
  78. cognite/neat/_graph/transformers/_value_type.py +66 -0
  79. cognite/neat/{issues → _issues}/_base.py +32 -17
  80. cognite/neat/{issues → _issues}/errors/__init__.py +1 -1
  81. cognite/neat/{issues → _issues}/errors/_external.py +8 -8
  82. cognite/neat/{issues → _issues}/errors/_general.py +5 -5
  83. cognite/neat/{issues → _issues}/errors/_properties.py +7 -7
  84. cognite/neat/{issues → _issues}/errors/_resources.py +11 -11
  85. cognite/neat/{issues → _issues}/errors/_workflow.py +5 -5
  86. cognite/neat/{issues → _issues}/warnings/__init__.py +1 -1
  87. cognite/neat/{issues → _issues}/warnings/_external.py +5 -5
  88. cognite/neat/{issues → _issues}/warnings/_general.py +4 -4
  89. cognite/neat/{issues → _issues}/warnings/_models.py +10 -10
  90. cognite/neat/{issues → _issues}/warnings/_properties.py +6 -6
  91. cognite/neat/{issues → _issues}/warnings/_resources.py +5 -5
  92. cognite/neat/{issues → _issues}/warnings/user_modeling.py +9 -9
  93. cognite/neat/_rules/_constants.py +190 -0
  94. cognite/neat/{rules → _rules}/_shared.py +5 -5
  95. cognite/neat/_rules/analysis/__init__.py +5 -0
  96. cognite/neat/{rules → _rules}/analysis/_asset.py +5 -5
  97. cognite/neat/{rules → _rules}/analysis/_base.py +5 -5
  98. cognite/neat/_rules/analysis/_dms.py +43 -0
  99. cognite/neat/{rules → _rules}/analysis/_information.py +12 -6
  100. cognite/neat/_rules/catalog/__init__.py +6 -0
  101. cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
  102. cognite/neat/{rules → _rules}/exporters/__init__.py +2 -0
  103. cognite/neat/{rules → _rules}/exporters/_base.py +3 -3
  104. cognite/neat/{rules → _rules}/exporters/_rules2dms.py +5 -5
  105. cognite/neat/{rules → _rules}/exporters/_rules2excel.py +12 -8
  106. cognite/neat/_rules/exporters/_rules2instance_template.py +152 -0
  107. cognite/neat/{rules → _rules}/exporters/_rules2ontology.py +10 -9
  108. cognite/neat/{rules → _rules}/exporters/_rules2yaml.py +1 -3
  109. cognite/neat/{rules → _rules}/exporters/_validation.py +2 -2
  110. cognite/neat/{rules → _rules}/importers/_base.py +3 -3
  111. cognite/neat/{rules → _rules}/importers/_dms2rules.py +9 -9
  112. cognite/neat/{rules → _rules}/importers/_dtdl2rules/dtdl_converter.py +7 -7
  113. cognite/neat/{rules → _rules}/importers/_dtdl2rules/dtdl_importer.py +9 -9
  114. cognite/neat/{rules → _rules}/importers/_dtdl2rules/spec.py +1 -1
  115. cognite/neat/_rules/importers/_rdf/_base.py +144 -0
  116. cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2classes.py +1 -1
  117. cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2metadata.py +4 -4
  118. cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2properties.py +2 -1
  119. cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2rules.py +8 -39
  120. cognite/neat/{rules → _rules}/importers/_rdf/_inference2rules.py +33 -106
  121. cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/_owl2classes.py +1 -1
  122. cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/_owl2metadata.py +5 -5
  123. cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/_owl2properties.py +1 -1
  124. cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2rules.py +39 -0
  125. cognite/neat/{rules → _rules}/importers/_rdf/_shared.py +4 -4
  126. cognite/neat/{rules → _rules}/importers/_spreadsheet2rules.py +7 -7
  127. cognite/neat/{rules → _rules}/importers/_yaml2rules.py +5 -5
  128. cognite/neat/{rules → _rules}/models/__init__.py +5 -5
  129. cognite/neat/{rules → _rules}/models/_base_input.py +15 -6
  130. cognite/neat/{rules → _rules}/models/_base_rules.py +14 -2
  131. cognite/neat/{rules → _rules}/models/_rdfpath.py +1 -1
  132. cognite/neat/_rules/models/_types.py +151 -0
  133. cognite/neat/{rules → _rules}/models/asset/_rules.py +4 -4
  134. cognite/neat/{rules → _rules}/models/asset/_rules_input.py +4 -4
  135. cognite/neat/{rules → _rules}/models/asset/_validation.py +7 -7
  136. cognite/neat/{rules → _rules}/models/data_types.py +15 -12
  137. cognite/neat/{rules → _rules}/models/dms/_exporter.py +60 -12
  138. cognite/neat/{rules → _rules}/models/dms/_rules.py +26 -23
  139. cognite/neat/{rules → _rules}/models/dms/_rules_input.py +4 -4
  140. cognite/neat/{rules → _rules}/models/dms/_schema.py +15 -14
  141. cognite/neat/{rules → _rules}/models/dms/_validation.py +8 -8
  142. cognite/neat/{rules → _rules}/models/domain.py +6 -6
  143. cognite/neat/{rules → _rules}/models/entities/__init__.py +1 -2
  144. cognite/neat/_rules/models/entities/_constants.py +15 -0
  145. cognite/neat/{rules → _rules}/models/entities/_loaders.py +2 -2
  146. cognite/neat/{rules → _rules}/models/entities/_multi_value.py +15 -2
  147. cognite/neat/{rules → _rules}/models/entities/_single_value.py +7 -4
  148. cognite/neat/{rules → _rules}/models/information/_rules.py +34 -22
  149. cognite/neat/{rules → _rules}/models/information/_rules_input.py +3 -3
  150. cognite/neat/{rules → _rules}/models/information/_validation.py +6 -5
  151. cognite/neat/_rules/models/mapping/__init__.py +4 -0
  152. cognite/neat/_rules/models/mapping/_base.py +131 -0
  153. cognite/neat/_rules/models/mapping/_classic2core.py +150 -0
  154. cognite/neat/{rules → _rules}/transformers/__init__.py +15 -2
  155. cognite/neat/{rules → _rules}/transformers/_base.py +3 -3
  156. cognite/neat/{rules → _rules}/transformers/_converters.py +289 -20
  157. cognite/neat/{rules/transformers/_map_onto.py → _rules/transformers/_mapping.py} +46 -4
  158. cognite/neat/{rules → _rules}/transformers/_pipelines.py +4 -4
  159. cognite/neat/{rules → _rules}/transformers/_verification.py +10 -4
  160. cognite/neat/_session/__init__.py +3 -0
  161. cognite/neat/_session/_base.py +86 -0
  162. cognite/neat/_session/_prepare.py +61 -0
  163. cognite/neat/_session/_read.py +118 -0
  164. cognite/neat/_session/_show.py +274 -0
  165. cognite/neat/_session/_state.py +69 -0
  166. cognite/neat/_session/_to.py +70 -0
  167. cognite/neat/_session/_wizard.py +39 -0
  168. cognite/neat/_session/exceptions.py +42 -0
  169. cognite/neat/{store → _store}/_base.py +62 -31
  170. cognite/neat/{store → _store}/_provenance.py +11 -1
  171. cognite/neat/{utils → _utils}/auth.py +14 -3
  172. cognite/neat/{utils → _utils}/auxiliary.py +1 -1
  173. cognite/neat/{utils → _utils}/cdf/loaders/_data_modeling.py +8 -2
  174. cognite/neat/{utils → _utils}/cdf/loaders/_ingestion.py +1 -1
  175. cognite/neat/{utils → _utils}/upload.py +1 -1
  176. cognite/neat/_version.py +1 -1
  177. cognite/neat/_workflows/__init__.py +17 -0
  178. cognite/neat/{workflows → _workflows}/base.py +10 -10
  179. cognite/neat/{workflows → _workflows}/cdf_store.py +3 -3
  180. cognite/neat/{workflows → _workflows}/examples/Export_DMS/workflow.yaml +89 -89
  181. cognite/neat/{workflows → _workflows}/manager.py +6 -6
  182. cognite/neat/{workflows → _workflows}/steps/data_contracts.py +3 -3
  183. cognite/neat/{workflows → _workflows}/steps/lib/current/graph_extractor.py +8 -31
  184. cognite/neat/{workflows → _workflows}/steps/lib/current/graph_loader.py +4 -4
  185. cognite/neat/{workflows → _workflows}/steps/lib/current/graph_store.py +4 -4
  186. cognite/neat/{workflows → _workflows}/steps/lib/current/rules_exporter.py +8 -8
  187. cognite/neat/{workflows → _workflows}/steps/lib/current/rules_importer.py +13 -13
  188. cognite/neat/{workflows → _workflows}/steps/lib/current/rules_validator.py +8 -8
  189. cognite/neat/{workflows → _workflows}/steps/lib/io/io_steps.py +3 -3
  190. cognite/neat/{workflows → _workflows}/steps/step_model.py +3 -3
  191. cognite/neat/{workflows → _workflows}/steps_registry.py +9 -9
  192. cognite/neat/{workflows → _workflows}/tasks.py +1 -1
  193. cognite/neat/{workflows → _workflows}/triggers.py +2 -2
  194. {cognite_neat-0.92.3.dist-info → cognite_neat-0.94.0.dist-info}/METADATA +6 -2
  195. cognite_neat-0.94.0.dist-info/RECORD +276 -0
  196. {cognite_neat-0.92.3.dist-info → cognite_neat-0.94.0.dist-info}/WHEEL +1 -1
  197. cognite_neat-0.94.0.dist-info/entry_points.txt +3 -0
  198. cognite/neat/app/api/context_manager/__init__.py +0 -3
  199. cognite/neat/graph/_shared.py +0 -5
  200. cognite/neat/graph/extractors/_iodd.py +0 -160
  201. cognite/neat/graph/extractors/_rdf_file.py +0 -26
  202. cognite/neat/rules/analysis/__init__.py +0 -6
  203. cognite/neat/rules/examples/__init__.py +0 -10
  204. cognite/neat/rules/examples/info-rules-imf.xlsx +0 -0
  205. cognite/neat/rules/examples/wind-energy.owl +0 -1511
  206. cognite/neat/rules/importers/_rdf/_owl2rules/_owl2rules.py +0 -65
  207. cognite/neat/rules/models/_types.py +0 -96
  208. cognite/neat/rules/models/entities/_constants.py +0 -73
  209. cognite/neat/utils/regex_patterns.py +0 -58
  210. cognite/neat/workflows/__init__.py +0 -12
  211. cognite_neat-0.92.3.dist-info/RECORD +0 -224
  212. cognite_neat-0.92.3.dist-info/entry_points.txt +0 -3
  213. /cognite/neat/{app → _app}/api/__init__.py +0 -0
  214. /cognite/neat/{app → _app}/api/asgi/metrics.py +0 -0
  215. /cognite/neat/{app → _app}/api/data_classes/__init__.py +0 -0
  216. /cognite/neat/{app → _app}/api/data_classes/rest.py +0 -0
  217. /cognite/neat/{app → _app}/api/routers/metrics.py +0 -0
  218. /cognite/neat/{app → _app}/api/utils/__init__.py +0 -0
  219. /cognite/neat/{app → _app}/api/utils/data_mapping.py +0 -0
  220. /cognite/neat/{app → _app}/api/utils/logging.py +0 -0
  221. /cognite/neat/{app → _app}/api/utils/query_templates.py +0 -0
  222. /cognite/neat/{app → _app}/monitoring/__init__.py +0 -0
  223. /cognite/neat/{app → _app}/monitoring/metrics.py +0 -0
  224. /cognite/neat/{app → _app}/ui/index.html +0 -0
  225. /cognite/neat/{app → _app}/ui/neat-app/.gitignore +0 -0
  226. /cognite/neat/{app → _app}/ui/neat-app/README.md +0 -0
  227. /cognite/neat/{app → _app}/ui/neat-app/build/asset-manifest.json +0 -0
  228. /cognite/neat/{app → _app}/ui/neat-app/build/favicon.ico +0 -0
  229. /cognite/neat/{app → _app}/ui/neat-app/build/img/architect-icon.svg +0 -0
  230. /cognite/neat/{app → _app}/ui/neat-app/build/img/developer-icon.svg +0 -0
  231. /cognite/neat/{app → _app}/ui/neat-app/build/img/sme-icon.svg +0 -0
  232. /cognite/neat/{app → _app}/ui/neat-app/build/index.html +0 -0
  233. /cognite/neat/{app → _app}/ui/neat-app/build/logo192.png +0 -0
  234. /cognite/neat/{app → _app}/ui/neat-app/build/manifest.json +0 -0
  235. /cognite/neat/{app → _app}/ui/neat-app/build/robots.txt +0 -0
  236. /cognite/neat/{app → _app}/ui/neat-app/build/static/css/main.72e3d92e.css +0 -0
  237. /cognite/neat/{app → _app}/ui/neat-app/build/static/css/main.72e3d92e.css.map +0 -0
  238. /cognite/neat/{app → _app}/ui/neat-app/build/static/js/main.5a52cf09.js +0 -0
  239. /cognite/neat/{app → _app}/ui/neat-app/build/static/js/main.5a52cf09.js.LICENSE.txt +0 -0
  240. /cognite/neat/{app → _app}/ui/neat-app/build/static/js/main.5a52cf09.js.map +0 -0
  241. /cognite/neat/{app → _app}/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -0
  242. /cognite/neat/{graph → _graph}/__init__.py +0 -0
  243. /cognite/neat/{graph → _graph}/_tracking/__init__.py +0 -0
  244. /cognite/neat/{graph → _graph}/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  245. /cognite/neat/{graph → _graph}/examples/Knowledge-Graph-Nordic44.xml +0 -0
  246. /cognite/neat/{graph → _graph}/examples/__init__.py +0 -0
  247. /cognite/neat/{graph → _graph}/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  248. /cognite/neat/{graph → _graph}/extractors/_classic_cdf/__init__.py +0 -0
  249. /cognite/neat/{graph → _graph}/loaders/__init__.py +0 -0
  250. /cognite/neat/{graph → _graph}/models.py +0 -0
  251. /cognite/neat/{graph → _graph}/queries/__init__.py +0 -0
  252. /cognite/neat/{graph → _graph}/transformers/_base.py +0 -0
  253. /cognite/neat/{issues → _issues}/__init__.py +0 -0
  254. /cognite/neat/{issues → _issues}/formatters.py +0 -0
  255. /cognite/neat/{rules → _rules}/__init__.py +0 -0
  256. /cognite/neat/{rules → _rules}/importers/__init__.py +0 -0
  257. /cognite/neat/{rules → _rules}/importers/_dtdl2rules/__init__.py +0 -0
  258. /cognite/neat/{rules → _rules}/importers/_dtdl2rules/_unit_lookup.py +0 -0
  259. /cognite/neat/{rules → _rules}/importers/_rdf/__init__.py +0 -0
  260. /cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/__init__.py +0 -0
  261. /cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/__init__.py +0 -0
  262. /cognite/neat/{rules → _rules}/models/asset/__init__.py +0 -0
  263. /cognite/neat/{rules → _rules}/models/dms/__init__.py +0 -0
  264. /cognite/neat/{rules → _rules}/models/entities/_types.py +0 -0
  265. /cognite/neat/{rules → _rules}/models/entities/_wrapped.py +0 -0
  266. /cognite/neat/{rules → _rules}/models/information/__init__.py +0 -0
  267. /cognite/neat/{store → _store}/__init__.py +0 -0
  268. /cognite/neat/{utils → _utils}/__init__.py +0 -0
  269. /cognite/neat/{utils → _utils}/cdf/__init__.py +0 -0
  270. /cognite/neat/{utils → _utils}/cdf/data_classes.py +0 -0
  271. /cognite/neat/{utils → _utils}/cdf/loaders/__init__.py +0 -0
  272. /cognite/neat/{utils → _utils}/cdf/loaders/_base.py +0 -0
  273. /cognite/neat/{utils → _utils}/collection_.py +0 -0
  274. /cognite/neat/{utils → _utils}/rdf_.py +0 -0
  275. /cognite/neat/{utils → _utils}/spreadsheet.py +0 -0
  276. /cognite/neat/{utils → _utils}/text.py +0 -0
  277. /cognite/neat/{utils → _utils}/time_.py +0 -0
  278. /cognite/neat/{utils → _utils}/xml_.py +0 -0
  279. /cognite/neat/{workflows → _workflows}/examples/Export_Semantic_Data_Model/workflow.yaml +0 -0
  280. /cognite/neat/{workflows → _workflows}/examples/Import_DMS/workflow.yaml +0 -0
  281. /cognite/neat/{workflows → _workflows}/examples/Validate_Rules/workflow.yaml +0 -0
  282. /cognite/neat/{workflows → _workflows}/examples/Validate_Solution_Model/workflow.yaml +0 -0
  283. /cognite/neat/{workflows → _workflows}/model.py +0 -0
  284. /cognite/neat/{workflows → _workflows}/steps/__init__.py +0 -0
  285. /cognite/neat/{workflows → _workflows}/steps/lib/__init__.py +0 -0
  286. /cognite/neat/{workflows → _workflows}/steps/lib/current/__init__.py +0 -0
  287. /cognite/neat/{workflows → _workflows}/steps/lib/io/__init__.py +0 -0
  288. /cognite/neat/{workflows → _workflows}/utils.py +0 -0
  289. {cognite_neat-0.92.3.dist-info → cognite_neat-0.94.0.dist-info}/LICENSE +0 -0
@@ -3,23 +3,21 @@ from datetime import datetime
3
3
  from pathlib import Path
4
4
  from typing import cast
5
5
 
6
- from rdflib import RDF, Graph, Namespace, URIRef
6
+ from rdflib import RDF
7
7
  from rdflib import Literal as RdfLiteral
8
8
 
9
- from cognite.neat.constants import DEFAULT_NAMESPACE, get_default_prefixes
10
- from cognite.neat.issues import IssueList
11
- from cognite.neat.issues.errors import FileReadError
12
- from cognite.neat.issues.warnings import PropertyValueTypeUndefinedWarning
13
- from cognite.neat.rules._shared import ReadRules
14
- from cognite.neat.rules.importers._base import BaseImporter
15
- from cognite.neat.rules.models._base_rules import MatchType
16
- from cognite.neat.rules.models.entities._single_value import UnknownEntity
17
- from cognite.neat.rules.models.information import (
18
- InformationInputRules,
9
+ from cognite.neat._constants import DEFAULT_NAMESPACE
10
+ from cognite.neat._issues.warnings import PropertyValueTypeUndefinedWarning
11
+ from cognite.neat._rules.models._base_rules import MatchType
12
+ from cognite.neat._rules.models.data_types import AnyURI
13
+ from cognite.neat._rules.models.entities._single_value import UnknownEntity
14
+ from cognite.neat._rules.models.information import (
19
15
  InformationMetadata,
20
16
  )
21
- from cognite.neat.store import NeatGraphStore
22
- from cognite.neat.utils.rdf_ import get_namespace, remove_namespace_from_uri, uri_to_short_form
17
+ from cognite.neat._store import NeatGraphStore
18
+ from cognite.neat._utils.rdf_ import remove_namespace_from_uri
19
+
20
+ from ._base import DEFAULT_NON_EXISTING_NODE_TYPE, BaseRDFImporter
23
21
 
24
22
  ORDERED_CLASSES_QUERY = """SELECT ?class (count(?s) as ?instances )
25
23
  WHERE { ?s a ?class . }
@@ -36,7 +34,7 @@ INSTANCE_PROPERTIES_DEFINITION = """SELECT ?property (count(?property) as ?occur
36
34
  GROUP BY ?property ?dataType ?objectType"""
37
35
 
38
36
 
39
- class InferenceImporter(BaseImporter[InformationInputRules]):
37
+ class InferenceImporter(BaseRDFImporter):
40
38
  """Infers rules from a triple store.
41
39
 
42
40
  Rules inference through analysis of knowledge graph provided in various formats.
@@ -50,62 +48,32 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
50
48
  prefix: Prefix to be used for the inferred model
51
49
  """
52
50
 
53
- def __init__(
54
- self,
55
- issue_list: IssueList,
56
- graph: Graph,
57
- max_number_of_instance: int = -1,
58
- prefix: str = "inferred",
59
- ) -> None:
60
- self.issue_list = issue_list
61
- self.graph = graph
62
- self.max_number_of_instance = max_number_of_instance
63
- self.prefix = prefix
64
-
65
51
  @classmethod
66
52
  def from_graph_store(
67
53
  cls,
68
54
  store: NeatGraphStore,
69
- max_number_of_instance: int = -1,
70
55
  prefix: str = "inferred",
56
+ max_number_of_instance: int = -1,
57
+ non_existing_node_type: UnknownEntity | AnyURI = DEFAULT_NON_EXISTING_NODE_TYPE,
71
58
  ) -> "InferenceImporter":
72
- issue_list = IssueList(title="Inferred from graph store")
73
-
74
- return cls(
75
- issue_list,
76
- store.graph,
77
- max_number_of_instance=max_number_of_instance,
78
- prefix=prefix,
79
- )
59
+ return super().from_graph_store(store, prefix, max_number_of_instance, non_existing_node_type)
80
60
 
81
61
  @classmethod
82
- def from_rdf_file(
62
+ def from_file(
83
63
  cls,
84
64
  filepath: Path,
85
- max_number_of_instance: int = -1,
86
65
  prefix: str = "inferred",
66
+ max_number_of_instance: int = -1,
67
+ non_existing_node_type: UnknownEntity | AnyURI = DEFAULT_NON_EXISTING_NODE_TYPE,
87
68
  ) -> "InferenceImporter":
88
- issue_list = IssueList(title=f"'{filepath.name}'")
89
-
90
- graph = Graph()
91
- try:
92
- graph.parse(filepath)
93
- except Exception as e:
94
- issue_list.append(FileReadError(filepath, str(e)))
95
-
96
- return cls(
97
- issue_list,
98
- graph,
99
- max_number_of_instance=max_number_of_instance,
100
- prefix=prefix,
101
- )
69
+ return super().from_file(filepath, prefix, max_number_of_instance, non_existing_node_type)
102
70
 
103
71
  @classmethod
104
72
  def from_json_file(
105
73
  cls,
106
74
  filepath: Path,
107
- max_number_of_instance: int = -1,
108
75
  prefix: str = "inferred",
76
+ max_number_of_instance: int = -1,
109
77
  ) -> "InferenceImporter":
110
78
  raise NotImplementedError("JSON file format is not supported yet.")
111
79
 
@@ -113,8 +81,8 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
113
81
  def from_yaml_file(
114
82
  cls,
115
83
  filepath: Path,
116
- max_number_of_instance: int = -1,
117
84
  prefix: str = "inferred",
85
+ max_number_of_instance: int = -1,
118
86
  ) -> "InferenceImporter":
119
87
  raise NotImplementedError("YAML file format is not supported yet.")
120
88
 
@@ -122,27 +90,11 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
122
90
  def from_xml_file(
123
91
  cls,
124
92
  filepath: Path,
125
- max_number_of_instance: int = -1,
126
93
  prefix: str = "inferred",
94
+ max_number_of_instance: int = -1,
127
95
  ) -> "InferenceImporter":
128
96
  raise NotImplementedError("JSON file format is not supported yet.")
129
97
 
130
- def to_rules(
131
- self,
132
- ) -> ReadRules[InformationInputRules]:
133
- """
134
- Creates `Rules` object from the data for target role.
135
- """
136
-
137
- if self.issue_list.has_errors:
138
- # In case there were errors during the import, the to_rules method will return None
139
- return ReadRules(None, self.issue_list, {})
140
-
141
- rules_dict = self._to_rules_components()
142
-
143
- rules = InformationInputRules.load(rules_dict)
144
- return ReadRules(rules, self.issue_list, {})
145
-
146
98
  def _to_rules_components(
147
99
  self,
148
100
  ) -> dict:
@@ -157,16 +109,10 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
157
109
  """
158
110
  classes: dict[str, dict] = {}
159
111
  properties: dict[str, dict] = {}
160
- prefixes: dict[str, Namespace] = get_default_prefixes()
161
112
  count_by_value_type_by_property: dict[str, dict[str, int]] = defaultdict(Counter)
162
113
 
163
- # Adds default namespace to prefixes
164
- prefixes[self._default_metadata().prefix] = self._default_metadata().namespace
165
-
166
114
  # Infers all the classes in the graph
167
115
  for class_uri, no_instances in self.graph.query(ORDERED_CLASSES_QUERY): # type: ignore[misc]
168
- self._add_uri_namespace_to_prefixes(cast(URIRef, class_uri), prefixes)
169
-
170
116
  if (class_id := remove_namespace_from_uri(class_uri)) in classes:
171
117
  # handles cases when class id is already present in classes
172
118
  class_id = f"{class_id}_{len(classes)+1}"
@@ -195,27 +141,24 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
195
141
 
196
142
  property_id = remove_namespace_from_uri(property_uri)
197
143
 
198
- self._add_uri_namespace_to_prefixes(cast(URIRef, property_uri), prefixes)
199
-
200
144
  if value_type_uri := (data_type_uri or object_type_uri):
201
- self._add_uri_namespace_to_prefixes(cast(URIRef, value_type_uri), prefixes)
202
-
203
145
  value_type_id = remove_namespace_from_uri(value_type_uri)
204
146
 
205
147
  # this handles situations when property points to node that is not present in graph
206
148
  else:
207
- value_type_id = str(UnknownEntity())
208
-
209
- self.issue_list.append(
210
- PropertyValueTypeUndefinedWarning(
211
- resource_type="Property",
212
- identifier=f"{class_id}{property_id}",
213
- property_name=property_id,
214
- default_action="Remove the property from the rules",
215
- recommended_action="Make sure that graph is complete",
216
- )
149
+ value_type_id = str(self.non_existing_node_type)
150
+
151
+ issue = PropertyValueTypeUndefinedWarning(
152
+ resource_type="Property",
153
+ identifier=f"{class_id}:{property_id}",
154
+ property_name=property_id,
155
+ default_action="Remove the property from the rules",
156
+ recommended_action="Make sure that graph is complete",
217
157
  )
218
158
 
159
+ if issue not in self.issue_list:
160
+ self.issue_list.append(issue)
161
+
219
162
  id_ = f"{class_id}:{property_id}"
220
163
 
221
164
  definition = {
@@ -224,10 +167,6 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
224
167
  "max_count": cast(RdfLiteral, occurrence).value,
225
168
  "value_type": value_type_id,
226
169
  "reference": property_uri,
227
- "transformation": (
228
- f"{uri_to_short_form(class_definition['reference'], prefixes)}"
229
- f"({uri_to_short_form(cast(URIRef, property_uri), prefixes)})"
230
- ),
231
170
  }
232
171
 
233
172
  count_by_value_type_by_property[id_][value_type_id] += 1
@@ -279,20 +218,8 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
279
218
  "metadata": self._default_metadata().model_dump(),
280
219
  "classes": list(classes.values()),
281
220
  "properties": list(properties.values()),
282
- "prefixes": prefixes,
283
221
  }
284
222
 
285
- @classmethod
286
- def _add_uri_namespace_to_prefixes(cls, URI: URIRef, prefixes: dict[str, Namespace]):
287
- """Add URI to prefixes dict if not already present
288
-
289
- Args:
290
- URI: URI from which namespace is being extracted
291
- prefixes: Dict of prefixes and namespaces
292
- """
293
- if Namespace(get_namespace(URI)) not in prefixes.values():
294
- prefixes[f"prefix-{len(prefixes)+1}"] = Namespace(get_namespace(URI))
295
-
296
223
  def _default_metadata(self):
297
224
  return InformationMetadata(
298
225
  name="Inferred Model",
@@ -2,7 +2,7 @@ from typing import cast
2
2
 
3
3
  from rdflib import Graph
4
4
 
5
- from cognite.neat.rules.importers._rdf._shared import (
5
+ from cognite.neat._rules.importers._rdf._shared import (
6
6
  clean_up_classes,
7
7
  make_classes_compliant,
8
8
  parse_raw_classes_dataframe,
@@ -1,10 +1,10 @@
1
1
  from rdflib import Graph, Namespace
2
2
 
3
- from cognite.neat.constants import DEFAULT_NAMESPACE
4
- from cognite.neat.rules.importers._rdf._shared import make_metadata_compliant
5
- from cognite.neat.rules.models import RoleTypes, SchemaCompleteness
6
- from cognite.neat.utils.collection_ import remove_none_elements_from_set
7
- from cognite.neat.utils.rdf_ import convert_rdflib_content
3
+ from cognite.neat._constants import DEFAULT_NAMESPACE
4
+ from cognite.neat._rules.importers._rdf._shared import make_metadata_compliant
5
+ from cognite.neat._rules.models import RoleTypes, SchemaCompleteness
6
+ from cognite.neat._utils.collection_ import remove_none_elements_from_set
7
+ from cognite.neat._utils.rdf_ import convert_rdflib_content
8
8
 
9
9
 
10
10
  def parse_owl_metadata(graph: Graph) -> dict:
@@ -2,7 +2,7 @@ from typing import cast
2
2
 
3
3
  from rdflib import Graph
4
4
 
5
- from cognite.neat.rules.importers._rdf._shared import (
5
+ from cognite.neat._rules.importers._rdf._shared import (
6
6
  clean_up_properties,
7
7
  make_properties_compliant,
8
8
  parse_raw_properties_dataframe,
@@ -0,0 +1,39 @@
1
+ """This module performs importing of various formats to one of serializations for which
2
+ there are loaders to TransformationRules pydantic class."""
3
+
4
+ from cognite.neat._rules.importers._rdf._base import BaseRDFImporter
5
+ from cognite.neat._rules.importers._rdf._shared import make_components_compliant
6
+
7
+ from ._owl2classes import parse_owl_classes
8
+ from ._owl2metadata import parse_owl_metadata
9
+ from ._owl2properties import parse_owl_properties
10
+
11
+
12
+ class OWLImporter(BaseRDFImporter):
13
+ """Convert OWL ontology to tables/ transformation rules / Excel file.
14
+
15
+ Args:
16
+ filepath: Path to OWL ontology
17
+
18
+ !!! Note
19
+ OWL Ontologies are information models which completeness varies. As such, constructing functional
20
+ data model directly will often be impossible, therefore the produced Rules object will be ill formed.
21
+ To avoid this, neat will automatically attempt to make the imported rules compliant by adding default
22
+ values for missing information, attaching dangling properties to default containers based on the
23
+ property type, etc.
24
+
25
+ One has to be aware that NEAT will be opinionated about how to make the ontology
26
+ compliant, and that the resulting rules may not be what you expect.
27
+
28
+ """
29
+
30
+ def _to_rules_components(
31
+ self,
32
+ ) -> dict:
33
+ components = {
34
+ "Metadata": parse_owl_metadata(self.graph),
35
+ "Classes": parse_owl_classes(self.graph),
36
+ "Properties": parse_owl_properties(self.graph),
37
+ }
38
+
39
+ return make_components_compliant(components)
@@ -4,10 +4,10 @@ import numpy as np
4
4
  import pandas as pd
5
5
  from rdflib import OWL, Literal, Namespace
6
6
 
7
- from cognite.neat.rules.models._base_rules import MatchType
8
- from cognite.neat.rules.models.data_types import _XSD_TYPES
9
- from cognite.neat.utils.rdf_ import remove_namespace_from_uri
10
- from cognite.neat.utils.regex_patterns import PATTERNS
7
+ from cognite.neat._rules._constants import PATTERNS
8
+ from cognite.neat._rules.models._base_rules import MatchType
9
+ from cognite.neat._rules.models.data_types import _XSD_TYPES
10
+ from cognite.neat._utils.rdf_ import remove_namespace_from_uri
11
11
 
12
12
 
13
13
  def parse_raw_classes_dataframe(query_results: list[tuple]) -> pd.DataFrame:
@@ -13,23 +13,23 @@ from cognite.client.utils._importing import local_import
13
13
  from pandas import ExcelFile
14
14
  from rdflib import Namespace
15
15
 
16
- from cognite.neat.issues import IssueList
17
- from cognite.neat.issues.errors import (
16
+ from cognite.neat._issues import IssueList
17
+ from cognite.neat._issues.errors import (
18
18
  FileMissingRequiredFieldError,
19
19
  FileNotFoundNeatError,
20
20
  FileReadError,
21
21
  PropertyDefinitionDuplicatedError,
22
22
  )
23
- from cognite.neat.issues.warnings import FileMissingRequiredFieldWarning
24
- from cognite.neat.rules._shared import ReadRules, T_InputRules
25
- from cognite.neat.rules.models import (
23
+ from cognite.neat._issues.warnings import FileMissingRequiredFieldWarning
24
+ from cognite.neat._rules._shared import ReadRules, T_InputRules
25
+ from cognite.neat._rules.models import (
26
26
  INPUT_RULES_BY_ROLE,
27
27
  VERIFIED_RULES_BY_ROLE,
28
28
  RoleTypes,
29
29
  SchemaCompleteness,
30
30
  )
31
- from cognite.neat.utils.spreadsheet import SpreadsheetRead, read_individual_sheet
32
- from cognite.neat.utils.text import humanize_collection
31
+ from cognite.neat._utils.spreadsheet import SpreadsheetRead, read_individual_sheet
32
+ from cognite.neat._utils.text import humanize_collection
33
33
 
34
34
  from ._base import BaseImporter
35
35
 
@@ -3,16 +3,16 @@ from typing import Any, cast
3
3
 
4
4
  import yaml
5
5
 
6
- from cognite.neat.issues import IssueList, NeatIssue
7
- from cognite.neat.issues.errors import (
6
+ from cognite.neat._issues import IssueList, NeatIssue
7
+ from cognite.neat._issues.errors import (
8
8
  FileMissingRequiredFieldError,
9
9
  FileNotAFileError,
10
10
  FileNotFoundNeatError,
11
11
  FileTypeUnexpectedError,
12
12
  )
13
- from cognite.neat.issues.warnings import NeatValueWarning
14
- from cognite.neat.rules._shared import ReadRules, T_InputRules
15
- from cognite.neat.rules.models import INPUT_RULES_BY_ROLE, RoleTypes
13
+ from cognite.neat._issues.warnings import NeatValueWarning
14
+ from cognite.neat._rules._shared import ReadRules, T_InputRules
15
+ from cognite.neat._rules.models import INPUT_RULES_BY_ROLE, RoleTypes
16
16
 
17
17
  from ._base import BaseImporter
18
18
 
@@ -1,8 +1,8 @@
1
- from cognite.neat.rules.models.asset._rules import AssetRules
2
- from cognite.neat.rules.models.asset._rules_input import AssetInputRules
3
- from cognite.neat.rules.models.domain import DomainInputRules, DomainRules
4
- from cognite.neat.rules.models.information._rules import InformationRules
5
- from cognite.neat.rules.models.information._rules_input import InformationInputRules
1
+ from cognite.neat._rules.models.asset._rules import AssetRules
2
+ from cognite.neat._rules.models.asset._rules_input import AssetInputRules
3
+ from cognite.neat._rules.models.domain import DomainInputRules, DomainRules
4
+ from cognite.neat._rules.models.information._rules import InformationRules
5
+ from cognite.neat._rules.models.information._rules_input import InformationInputRules
6
6
 
7
7
  from ._base_rules import DataModelType, ExtensionCategory, RoleTypes, SchemaCompleteness, SheetList, SheetRow
8
8
  from .dms._rules import DMSRules
@@ -18,6 +18,8 @@ from dataclasses import Field, dataclass, fields, is_dataclass
18
18
  from types import GenericAlias, UnionType
19
19
  from typing import Any, Generic, TypeVar, Union, cast, get_args, get_origin, overload
20
20
 
21
+ import pandas as pd
22
+
21
23
  from ._base_rules import BaseRules, SchemaModel
22
24
 
23
25
  if sys.version_info >= (3, 11):
@@ -40,14 +42,14 @@ class InputRules(Generic[T_BaseRules], ABC):
40
42
 
41
43
  @classmethod
42
44
  @overload
43
- def load(cls, data: dict[str, Any]) -> Self: ...
45
+ def load(cls: "type[T_InputRules]", data: dict[str, Any]) -> "T_InputRules": ...
44
46
 
45
47
  @classmethod
46
48
  @overload
47
- def load(cls, data: None) -> None: ...
49
+ def load(cls: "type[T_InputRules]", data: None) -> None: ...
48
50
 
49
51
  @classmethod
50
- def load(cls, data: dict | None) -> Self | None:
52
+ def load(cls: "type[T_InputRules]", data: dict | None) -> "T_InputRules | None":
51
53
  if data is None:
52
54
  return None
53
55
  return cls._load(data)
@@ -62,14 +64,15 @@ class InputRules(Generic[T_BaseRules], ABC):
62
64
  if isinstance(type_, str) and type_.startswith(cls.__name__):
63
65
  type_ = cls
64
66
 
67
+ candidate: type
65
68
  if is_dataclass(type_):
66
- candidate = type_
69
+ candidate = type_ # type: ignore[assignment]
67
70
  elif isinstance(type_, GenericAlias) and type_.__origin__ is list and is_dataclass(type_.__args__[0]):
68
- candidate = type_.__args__[0]
71
+ candidate = type_.__args__[0] # type: ignore[assignment]
69
72
 
70
73
  # this handles prefixes
71
74
  elif isinstance(type_, GenericAlias) and type_.__origin__ is dict:
72
- candidate = type_
75
+ candidate = type_ # type: ignore[assignment]
73
76
  else:
74
77
  continue
75
78
 
@@ -124,6 +127,9 @@ class InputRules(Generic[T_BaseRules], ABC):
124
127
  return output
125
128
 
126
129
 
130
+ T_InputRules = TypeVar("T_InputRules", bound=InputRules)
131
+
132
+
127
133
  @dataclass
128
134
  class InputComponent(ABC, Generic[T_RuleModel]):
129
135
  @classmethod
@@ -170,3 +176,6 @@ class InputComponent(ABC, Generic[T_RuleModel]):
170
176
  for name, field_ in self._get_verified_cls().model_fields.items()
171
177
  if not field_.exclude
172
178
  }
179
+
180
+ def _repr_html_(self) -> str:
181
+ return pd.DataFrame([self.dump()])._repr_html_() # type: ignore[operator]
@@ -24,6 +24,8 @@ from pydantic import (
24
24
  from pydantic.main import IncEx
25
25
  from pydantic_core import core_schema
26
26
 
27
+ from cognite.neat._rules.models._types import ClassEntityType, InformationPropertyType
28
+
27
29
  if sys.version_info >= (3, 11):
28
30
  from enum import StrEnum
29
31
  from typing import Self
@@ -208,7 +210,7 @@ class BaseRules(SchemaModel, ABC):
208
210
  as_reference: bool = False,
209
211
  mode: Literal["python", "json"] = "python",
210
212
  by_alias: bool = False,
211
- exclude: IncEx = None,
213
+ exclude: IncEx | None = None,
212
214
  exclude_none: bool = False,
213
215
  exclude_unset: bool = False,
214
216
  exclude_defaults: bool = False,
@@ -244,7 +246,7 @@ class BaseRules(SchemaModel, ABC):
244
246
  if entities_exclude_defaults:
245
247
  context["metadata"] = self.metadata
246
248
 
247
- exclude_input: IncEx
249
+ exclude_input: IncEx | None
248
250
  if self.reference is None:
249
251
  exclude_input = exclude
250
252
  else:
@@ -348,3 +350,13 @@ ExtensionCategoryType = Annotated[
348
350
  ),
349
351
  BeforeValidator(lambda v: ExtensionCategory(v) if isinstance(v, str) else v),
350
352
  ]
353
+
354
+
355
+ # Immutable such that this can be used as a key in a dictionary
356
+ class PropertyRef(BaseModel, frozen=True):
357
+ class_: ClassEntityType = Field(alias="Class")
358
+ property_: InformationPropertyType = Field(alias="Property")
359
+
360
+
361
+ class ClassRef(BaseModel, frozen=True):
362
+ class_: ClassEntityType = Field(alias="Class")
@@ -8,7 +8,7 @@ from typing import ClassVar, Literal
8
8
 
9
9
  from pydantic import BaseModel, field_validator, model_serializer
10
10
 
11
- from cognite.neat.issues.errors import NeatValueError
11
+ from cognite.neat._issues.errors import NeatValueError
12
12
 
13
13
  if sys.version_info >= (3, 11):
14
14
  from enum import StrEnum
@@ -0,0 +1,151 @@
1
+ import warnings
2
+ from collections.abc import Callable
3
+ from typing import Annotated, Any, TypeAlias, TypeVar
4
+
5
+ import rdflib
6
+ from pydantic import (
7
+ AfterValidator,
8
+ BeforeValidator,
9
+ HttpUrl,
10
+ StringConstraints,
11
+ TypeAdapter,
12
+ ValidationInfo,
13
+ WrapValidator,
14
+ )
15
+ from pydantic.functional_serializers import PlainSerializer
16
+
17
+ from cognite.neat._issues.errors import RegexViolationError
18
+ from cognite.neat._issues.warnings import RegexViolationWarning
19
+ from cognite.neat._rules._constants import (
20
+ DATA_MODEL_COMPLIANCE_REGEX,
21
+ PATTERNS,
22
+ PREFIX_COMPLIANCE_REGEX,
23
+ VERSION_COMPLIANCE_REGEX,
24
+ EntityTypes,
25
+ )
26
+ from cognite.neat._rules.models.entities._multi_value import MultiValueTypeInfo
27
+ from cognite.neat._rules.models.entities._single_value import (
28
+ ClassEntity,
29
+ ContainerEntity,
30
+ ViewEntity,
31
+ )
32
+
33
+ Entities: TypeAlias = ClassEntity | ViewEntity | ContainerEntity
34
+ T_Entities = TypeVar("T_Entities", bound=Entities)
35
+
36
+
37
+ def _custom_error(exc_factory: Callable[[str | None, Exception], Any]) -> Any:
38
+ def _validator(value: Any, next_: Any, ctx: ValidationInfo) -> Any:
39
+ try:
40
+ return next_(value, ctx)
41
+ except Exception:
42
+ raise exc_factory(ctx.field_name, value) from None
43
+
44
+ return WrapValidator(_validator)
45
+
46
+
47
+ StrOrListType = Annotated[
48
+ str | list[str],
49
+ BeforeValidator(lambda value: value.replace(", ", ",").split(",") if isinstance(value, str) and value else value),
50
+ PlainSerializer(
51
+ lambda value: ",".join([entry for entry in value if entry]) if isinstance(value, list) else value,
52
+ return_type=str,
53
+ when_used="unless-none",
54
+ ),
55
+ ]
56
+
57
+ StrListType = Annotated[
58
+ list[str],
59
+ BeforeValidator(lambda value: [entry.strip() for entry in value.split(",")] if isinstance(value, str) else value),
60
+ PlainSerializer(
61
+ lambda value: ",".join([entry for entry in value if entry]), return_type=str, when_used="unless-none"
62
+ ),
63
+ ]
64
+
65
+ NamespaceType = Annotated[
66
+ rdflib.Namespace,
67
+ BeforeValidator(
68
+ lambda value: (
69
+ rdflib.Namespace(TypeAdapter(HttpUrl).validate_python(value))
70
+ if value.endswith("#") or value.endswith("/")
71
+ else rdflib.Namespace(TypeAdapter(HttpUrl).validate_python(f"{value}/"))
72
+ )
73
+ ),
74
+ ]
75
+
76
+ PrefixType = Annotated[
77
+ str,
78
+ StringConstraints(pattern=PREFIX_COMPLIANCE_REGEX),
79
+ _custom_error(lambda _, value: RegexViolationError(value, PREFIX_COMPLIANCE_REGEX)),
80
+ ]
81
+
82
+ DataModelExternalIdType = Annotated[
83
+ str,
84
+ StringConstraints(pattern=DATA_MODEL_COMPLIANCE_REGEX),
85
+ _custom_error(lambda _, value: RegexViolationError(value, DATA_MODEL_COMPLIANCE_REGEX)),
86
+ ]
87
+
88
+
89
+ VersionType = Annotated[
90
+ str,
91
+ BeforeValidator(str),
92
+ StringConstraints(pattern=VERSION_COMPLIANCE_REGEX),
93
+ _custom_error(lambda _, value: RegexViolationError(value, VERSION_COMPLIANCE_REGEX)),
94
+ ]
95
+
96
+
97
+ def _external_id_validation_factory(entity_type: EntityTypes):
98
+ def _external_id_validation(value: str) -> str:
99
+ compiled_regex = PATTERNS.entity_pattern(entity_type)
100
+ if not compiled_regex.match(value):
101
+ raise RegexViolationError(value, compiled_regex.pattern)
102
+ if PATTERNS.more_than_one_alphanumeric.search(value):
103
+ warnings.warn(
104
+ RegexViolationWarning(
105
+ value,
106
+ compiled_regex.pattern,
107
+ "property",
108
+ "MoreThanOneNonAlphanumeric",
109
+ ),
110
+ stacklevel=2,
111
+ )
112
+ return value
113
+
114
+ return _external_id_validation
115
+
116
+
117
+ SpaceType = Annotated[
118
+ str,
119
+ AfterValidator(_external_id_validation_factory(EntityTypes.space)),
120
+ ]
121
+
122
+ InformationPropertyType = Annotated[
123
+ str,
124
+ AfterValidator(_external_id_validation_factory(EntityTypes.information_property)),
125
+ ]
126
+ DmsPropertyType = Annotated[
127
+ str,
128
+ AfterValidator(_external_id_validation_factory(EntityTypes.dms_property)),
129
+ ]
130
+
131
+
132
+ def _entity_validation(value: Entities) -> Entities:
133
+ suffix_regex = PATTERNS.entity_pattern(value.type_)
134
+ if not suffix_regex.match(value.suffix):
135
+ raise RegexViolationError(str(value), suffix_regex.pattern)
136
+ return value
137
+
138
+
139
+ ClassEntityType = Annotated[ClassEntity, AfterValidator(_entity_validation)]
140
+ ViewEntityType = Annotated[ViewEntity, AfterValidator(_entity_validation)]
141
+ ContainerEntityType = Annotated[ContainerEntity, AfterValidator(_entity_validation)]
142
+
143
+
144
+ def _multi_value_type_validation(value: MultiValueTypeInfo) -> MultiValueTypeInfo:
145
+ for type_ in value.types:
146
+ if isinstance(type_, ClassEntity):
147
+ _entity_validation(type_)
148
+ return value
149
+
150
+
151
+ MultiValueTypeType = Annotated[MultiValueTypeInfo, AfterValidator(_multi_value_type_validation)]