cognite-neat 0.123.2__py3-none-any.whl → 0.127.30__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.
Files changed (333) hide show
  1. cognite/neat/__init__.py +2 -2
  2. cognite/neat/_client/__init__.py +4 -0
  3. cognite/neat/_client/api.py +8 -0
  4. cognite/neat/_client/client.py +21 -0
  5. cognite/neat/_client/config.py +40 -0
  6. cognite/neat/_client/containers_api.py +125 -0
  7. cognite/neat/_client/data_classes.py +44 -0
  8. cognite/neat/_client/data_model_api.py +115 -0
  9. cognite/neat/_client/spaces_api.py +115 -0
  10. cognite/neat/_client/statistics_api.py +24 -0
  11. cognite/neat/_client/views_api.py +129 -0
  12. cognite/neat/_config.py +185 -0
  13. cognite/neat/_data_model/_analysis.py +196 -0
  14. cognite/neat/_data_model/_constants.py +67 -0
  15. cognite/neat/_data_model/_identifiers.py +61 -0
  16. cognite/neat/_data_model/_shared.py +41 -0
  17. cognite/neat/_data_model/deployer/_differ.py +140 -0
  18. cognite/neat/_data_model/deployer/_differ_container.py +360 -0
  19. cognite/neat/_data_model/deployer/_differ_data_model.py +54 -0
  20. cognite/neat/_data_model/deployer/_differ_space.py +9 -0
  21. cognite/neat/_data_model/deployer/_differ_view.py +299 -0
  22. cognite/neat/_data_model/deployer/data_classes.py +529 -0
  23. cognite/neat/_data_model/deployer/deployer.py +401 -0
  24. cognite/neat/_data_model/exporters/__init__.py +15 -0
  25. cognite/neat/_data_model/exporters/_api_exporter.py +37 -0
  26. cognite/neat/_data_model/exporters/_base.py +24 -0
  27. cognite/neat/_data_model/exporters/_table_exporter/exporter.py +128 -0
  28. cognite/neat/_data_model/exporters/_table_exporter/workbook.py +409 -0
  29. cognite/neat/_data_model/exporters/_table_exporter/writer.py +421 -0
  30. cognite/neat/_data_model/importers/__init__.py +5 -0
  31. cognite/neat/_data_model/importers/_api_importer.py +166 -0
  32. cognite/neat/_data_model/importers/_base.py +16 -0
  33. cognite/neat/_data_model/importers/_table_importer/data_classes.py +295 -0
  34. cognite/neat/_data_model/importers/_table_importer/importer.py +192 -0
  35. cognite/neat/_data_model/importers/_table_importer/reader.py +1063 -0
  36. cognite/neat/_data_model/importers/_table_importer/source.py +94 -0
  37. cognite/neat/_data_model/models/conceptual/_base.py +18 -0
  38. cognite/neat/_data_model/models/conceptual/_concept.py +67 -0
  39. cognite/neat/_data_model/models/conceptual/_data_model.py +51 -0
  40. cognite/neat/_data_model/models/conceptual/_properties.py +104 -0
  41. cognite/neat/_data_model/models/conceptual/_property.py +105 -0
  42. cognite/neat/_data_model/models/dms/__init__.py +206 -0
  43. cognite/neat/_data_model/models/dms/_base.py +31 -0
  44. cognite/neat/_data_model/models/dms/_constants.py +48 -0
  45. cognite/neat/_data_model/models/dms/_constraints.py +42 -0
  46. cognite/neat/_data_model/models/dms/_container.py +159 -0
  47. cognite/neat/_data_model/models/dms/_data_model.py +95 -0
  48. cognite/neat/_data_model/models/dms/_data_types.py +195 -0
  49. cognite/neat/_data_model/models/dms/_http.py +28 -0
  50. cognite/neat/_data_model/models/dms/_indexes.py +30 -0
  51. cognite/neat/_data_model/models/dms/_limits.py +96 -0
  52. cognite/neat/_data_model/models/dms/_references.py +135 -0
  53. cognite/neat/_data_model/models/dms/_schema.py +18 -0
  54. cognite/neat/_data_model/models/dms/_space.py +48 -0
  55. cognite/neat/_data_model/models/dms/_types.py +17 -0
  56. cognite/neat/_data_model/models/dms/_view_filter.py +282 -0
  57. cognite/neat/_data_model/models/dms/_view_property.py +235 -0
  58. cognite/neat/_data_model/models/dms/_views.py +210 -0
  59. cognite/neat/_data_model/models/entities/__init__.py +50 -0
  60. cognite/neat/_data_model/models/entities/_base.py +101 -0
  61. cognite/neat/_data_model/models/entities/_constants.py +22 -0
  62. cognite/neat/_data_model/models/entities/_data_types.py +144 -0
  63. cognite/neat/_data_model/models/entities/_identifiers.py +61 -0
  64. cognite/neat/_data_model/models/entities/_parser.py +226 -0
  65. cognite/neat/_data_model/validation/dms/__init__.py +75 -0
  66. cognite/neat/_data_model/validation/dms/_ai_readiness.py +364 -0
  67. cognite/neat/_data_model/validation/dms/_base.py +307 -0
  68. cognite/neat/_data_model/validation/dms/_connections.py +638 -0
  69. cognite/neat/_data_model/validation/dms/_consistency.py +57 -0
  70. cognite/neat/_data_model/validation/dms/_containers.py +174 -0
  71. cognite/neat/_data_model/validation/dms/_limits.py +420 -0
  72. cognite/neat/_data_model/validation/dms/_orchestrator.py +222 -0
  73. cognite/neat/_data_model/validation/dms/_views.py +103 -0
  74. cognite/neat/_exceptions.py +56 -0
  75. cognite/neat/_issues.py +68 -0
  76. cognite/neat/_session/__init__.py +3 -0
  77. cognite/neat/_session/_html/_render.py +30 -0
  78. cognite/neat/_session/_html/static/__init__.py +8 -0
  79. cognite/neat/_session/_html/static/deployment.css +303 -0
  80. cognite/neat/_session/_html/static/deployment.js +150 -0
  81. cognite/neat/_session/_html/static/issues.css +211 -0
  82. cognite/neat/_session/_html/static/issues.js +168 -0
  83. cognite/neat/_session/_html/static/shared.css +186 -0
  84. cognite/neat/_session/_html/templates/__init__.py +4 -0
  85. cognite/neat/_session/_html/templates/deployment.html +75 -0
  86. cognite/neat/_session/_html/templates/issues.html +45 -0
  87. cognite/neat/_session/_issues.py +81 -0
  88. cognite/neat/_session/_opt.py +35 -0
  89. cognite/neat/_session/_physical.py +261 -0
  90. cognite/neat/_session/_result.py +236 -0
  91. cognite/neat/_session/_session.py +88 -0
  92. cognite/neat/_session/_usage_analytics/__init__.py +0 -0
  93. cognite/neat/_session/_usage_analytics/_collector.py +131 -0
  94. cognite/neat/_session/_usage_analytics/_constants.py +23 -0
  95. cognite/neat/_session/_usage_analytics/_storage.py +240 -0
  96. cognite/neat/_session/_wrappers.py +82 -0
  97. cognite/neat/_state_machine/__init__.py +10 -0
  98. cognite/neat/_state_machine/_base.py +37 -0
  99. cognite/neat/_state_machine/_states.py +52 -0
  100. cognite/neat/_store/__init__.py +3 -0
  101. cognite/neat/_store/_provenance.py +81 -0
  102. cognite/neat/_store/_store.py +156 -0
  103. cognite/neat/_utils/__init__.py +0 -0
  104. cognite/neat/_utils/_reader.py +194 -0
  105. cognite/neat/_utils/auxiliary.py +39 -0
  106. cognite/neat/_utils/collection.py +11 -0
  107. cognite/neat/_utils/http_client/__init__.py +39 -0
  108. cognite/neat/_utils/http_client/_client.py +245 -0
  109. cognite/neat/_utils/http_client/_config.py +19 -0
  110. cognite/neat/_utils/http_client/_data_classes.py +294 -0
  111. cognite/neat/_utils/http_client/_tracker.py +31 -0
  112. cognite/neat/_utils/text.py +71 -0
  113. cognite/neat/_utils/useful_types.py +37 -0
  114. cognite/neat/_utils/validation.py +154 -0
  115. cognite/neat/_version.py +1 -1
  116. cognite/neat/v0/__init__.py +0 -0
  117. cognite/neat/v0/core/__init__.py +0 -0
  118. cognite/neat/v0/core/_client/_api/__init__.py +0 -0
  119. cognite/neat/{core → v0/core}/_client/_api/data_modeling_loaders.py +86 -7
  120. cognite/neat/{core → v0/core}/_client/_api/neat_instances.py +5 -5
  121. cognite/neat/{core → v0/core}/_client/_api/schema.py +5 -5
  122. cognite/neat/{core → v0/core}/_client/_api/statistics.py +3 -3
  123. cognite/neat/{core → v0/core}/_client/_api_client.py +1 -1
  124. cognite/neat/v0/core/_client/data_classes/__init__.py +0 -0
  125. cognite/neat/{core → v0/core}/_client/data_classes/schema.py +4 -4
  126. cognite/neat/{core → v0/core}/_client/testing.py +1 -1
  127. cognite/neat/{core → v0/core}/_constants.py +10 -3
  128. cognite/neat/v0/core/_data_model/__init__.py +0 -0
  129. cognite/neat/{core → v0/core}/_data_model/_constants.py +9 -6
  130. cognite/neat/{core → v0/core}/_data_model/_shared.py +5 -5
  131. cognite/neat/{core → v0/core}/_data_model/analysis/_base.py +12 -8
  132. cognite/neat/{core → v0/core}/_data_model/exporters/__init__.py +1 -2
  133. cognite/neat/{core → v0/core}/_data_model/exporters/_base.py +7 -7
  134. cognite/neat/{core → v0/core}/_data_model/exporters/_data_model2dms.py +9 -9
  135. cognite/neat/{core → v0/core}/_data_model/exporters/_data_model2excel.py +13 -13
  136. cognite/neat/{core → v0/core}/_data_model/exporters/_data_model2instance_template.py +4 -4
  137. cognite/neat/{core/_data_model/exporters/_data_model2ontology.py → v0/core/_data_model/exporters/_data_model2semantic_model.py} +126 -133
  138. cognite/neat/{core → v0/core}/_data_model/exporters/_data_model2yaml.py +1 -1
  139. cognite/neat/{core → v0/core}/_data_model/importers/__init__.py +4 -6
  140. cognite/neat/{core → v0/core}/_data_model/importers/_base.py +5 -5
  141. cognite/neat/{core → v0/core}/_data_model/importers/_base_file_reader.py +2 -2
  142. cognite/neat/{core → v0/core}/_data_model/importers/_dict2data_model.py +6 -6
  143. cognite/neat/{core → v0/core}/_data_model/importers/_dms2data_model.py +19 -16
  144. cognite/neat/v0/core/_data_model/importers/_graph2data_model.py +299 -0
  145. cognite/neat/v0/core/_data_model/importers/_rdf/__init__.py +4 -0
  146. cognite/neat/{core → v0/core}/_data_model/importers/_rdf/_base.py +13 -13
  147. cognite/neat/{core → v0/core}/_data_model/importers/_rdf/_inference2rdata_model.py +14 -14
  148. cognite/neat/v0/core/_data_model/importers/_rdf/_owl2data_model.py +144 -0
  149. cognite/neat/v0/core/_data_model/importers/_rdf/_shared.py +255 -0
  150. cognite/neat/{core → v0/core}/_data_model/importers/_spreadsheet2data_model.py +94 -13
  151. cognite/neat/{core → v0/core}/_data_model/models/__init__.py +3 -3
  152. cognite/neat/{core → v0/core}/_data_model/models/_base_verified.py +5 -5
  153. cognite/neat/v0/core/_data_model/models/_import_contexts.py +82 -0
  154. cognite/neat/{core → v0/core}/_data_model/models/_types.py +5 -5
  155. cognite/neat/{core → v0/core}/_data_model/models/conceptual/_unverified.py +18 -12
  156. cognite/neat/v0/core/_data_model/models/conceptual/_validation.py +308 -0
  157. cognite/neat/{core → v0/core}/_data_model/models/conceptual/_verified.py +13 -11
  158. cognite/neat/{core → v0/core}/_data_model/models/data_types.py +14 -4
  159. cognite/neat/{core → v0/core}/_data_model/models/entities/__init__.py +6 -0
  160. cognite/neat/v0/core/_data_model/models/entities/_loaders.py +155 -0
  161. cognite/neat/{core → v0/core}/_data_model/models/entities/_multi_value.py +2 -2
  162. cognite/neat/v0/core/_data_model/models/entities/_restrictions.py +230 -0
  163. cognite/neat/{core → v0/core}/_data_model/models/entities/_single_value.py +121 -16
  164. cognite/neat/{core → v0/core}/_data_model/models/entities/_types.py +10 -0
  165. cognite/neat/{core → v0/core}/_data_model/models/mapping/_classic2core.py +5 -5
  166. cognite/neat/{core → v0/core}/_data_model/models/physical/__init__.py +1 -1
  167. cognite/neat/{core → v0/core}/_data_model/models/physical/_exporter.py +28 -21
  168. cognite/neat/{core → v0/core}/_data_model/models/physical/_unverified.py +141 -38
  169. cognite/neat/{core → v0/core}/_data_model/models/physical/_validation.py +190 -24
  170. cognite/neat/{core → v0/core}/_data_model/models/physical/_verified.py +135 -15
  171. cognite/neat/{core → v0/core}/_data_model/transformers/__init__.py +2 -0
  172. cognite/neat/{core → v0/core}/_data_model/transformers/_base.py +4 -4
  173. cognite/neat/{core → v0/core}/_data_model/transformers/_converters.py +39 -32
  174. cognite/neat/{core → v0/core}/_data_model/transformers/_mapping.py +7 -7
  175. cognite/neat/v0/core/_data_model/transformers/_union_conceptual.py +208 -0
  176. cognite/neat/{core → v0/core}/_data_model/transformers/_verification.py +7 -7
  177. cognite/neat/v0/core/_instances/__init__.py +0 -0
  178. cognite/neat/{core → v0/core}/_instances/_tracking/base.py +1 -1
  179. cognite/neat/{core → v0/core}/_instances/_tracking/log.py +1 -1
  180. cognite/neat/{core → v0/core}/_instances/extractors/__init__.py +1 -1
  181. cognite/neat/{core → v0/core}/_instances/extractors/_base.py +6 -6
  182. cognite/neat/v0/core/_instances/extractors/_classic_cdf/__init__.py +0 -0
  183. cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_base.py +7 -7
  184. cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_classic.py +12 -12
  185. cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_relationships.py +3 -3
  186. cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_sequences.py +2 -2
  187. cognite/neat/{core → v0/core}/_instances/extractors/_dict.py +6 -3
  188. cognite/neat/{core → v0/core}/_instances/extractors/_dms.py +6 -6
  189. cognite/neat/{core → v0/core}/_instances/extractors/_dms_graph.py +11 -11
  190. cognite/neat/{core → v0/core}/_instances/extractors/_mock_graph_generator.py +10 -10
  191. cognite/neat/{core → v0/core}/_instances/extractors/_raw.py +3 -3
  192. cognite/neat/{core → v0/core}/_instances/extractors/_rdf_file.py +7 -7
  193. cognite/neat/{core → v0/core}/_instances/loaders/_base.py +5 -5
  194. cognite/neat/{core → v0/core}/_instances/loaders/_rdf2dms.py +17 -17
  195. cognite/neat/{core → v0/core}/_instances/loaders/_rdf_to_instance_space.py +11 -11
  196. cognite/neat/{core → v0/core}/_instances/queries/_select.py +29 -3
  197. cognite/neat/{core → v0/core}/_instances/queries/_update.py +1 -1
  198. cognite/neat/{core → v0/core}/_instances/transformers/_base.py +4 -4
  199. cognite/neat/{core → v0/core}/_instances/transformers/_classic_cdf.py +6 -6
  200. cognite/neat/{core → v0/core}/_instances/transformers/_prune_graph.py +4 -4
  201. cognite/neat/{core → v0/core}/_instances/transformers/_rdfpath.py +1 -1
  202. cognite/neat/{core → v0/core}/_instances/transformers/_value_type.py +4 -4
  203. cognite/neat/{core → v0/core}/_issues/_base.py +11 -6
  204. cognite/neat/{core → v0/core}/_issues/_contextmanagers.py +8 -6
  205. cognite/neat/{core → v0/core}/_issues/_factory.py +11 -8
  206. cognite/neat/{core → v0/core}/_issues/errors/__init__.py +3 -1
  207. cognite/neat/{core → v0/core}/_issues/errors/_external.py +1 -1
  208. cognite/neat/{core → v0/core}/_issues/errors/_general.py +1 -1
  209. cognite/neat/{core → v0/core}/_issues/errors/_properties.py +12 -1
  210. cognite/neat/{core → v0/core}/_issues/errors/_resources.py +2 -2
  211. cognite/neat/{core → v0/core}/_issues/errors/_wrapper.py +7 -3
  212. cognite/neat/{core → v0/core}/_issues/warnings/__init__.py +5 -1
  213. cognite/neat/{core → v0/core}/_issues/warnings/_external.py +1 -1
  214. cognite/neat/{core → v0/core}/_issues/warnings/_general.py +1 -1
  215. cognite/neat/{core → v0/core}/_issues/warnings/_models.py +39 -4
  216. cognite/neat/{core → v0/core}/_issues/warnings/_properties.py +13 -2
  217. cognite/neat/{core → v0/core}/_issues/warnings/_resources.py +1 -1
  218. cognite/neat/{core → v0/core}/_issues/warnings/user_modeling.py +1 -1
  219. cognite/neat/{core → v0/core}/_store/_data_model.py +13 -12
  220. cognite/neat/{core → v0/core}/_store/_instance.py +45 -12
  221. cognite/neat/{core → v0/core}/_store/_provenance.py +3 -3
  222. cognite/neat/{core → v0/core}/_store/exceptions.py +4 -4
  223. cognite/neat/v0/core/_utils/__init__.py +0 -0
  224. cognite/neat/{core → v0/core}/_utils/auth.py +1 -1
  225. cognite/neat/{core → v0/core}/_utils/auxiliary.py +7 -1
  226. cognite/neat/{core → v0/core}/_utils/collection_.py +2 -2
  227. cognite/neat/{core → v0/core}/_utils/graph_transformations_report.py +1 -1
  228. cognite/neat/{core → v0/core}/_utils/rdf_.py +38 -14
  229. cognite/neat/{core → v0/core}/_utils/reader/_base.py +1 -1
  230. cognite/neat/{core → v0/core}/_utils/spreadsheet.py +22 -4
  231. cognite/neat/v0/core/_utils/tarjan.py +44 -0
  232. cognite/neat/{core → v0/core}/_utils/text.py +1 -1
  233. cognite/neat/{core → v0/core}/_utils/upload.py +3 -3
  234. cognite/neat/v0/plugins/__init__.py +4 -0
  235. cognite/neat/v0/plugins/_base.py +9 -0
  236. cognite/neat/v0/plugins/_data_model.py +48 -0
  237. cognite/neat/{plugins → v0/plugins}/_issues.py +1 -1
  238. cognite/neat/{plugins → v0/plugins}/_manager.py +7 -16
  239. cognite/neat/{session → v0/session}/_base.py +13 -10
  240. cognite/neat/{session → v0/session}/_collector.py +1 -1
  241. cognite/neat/v0/session/_diff.py +51 -0
  242. cognite/neat/{session → v0/session}/_drop.py +3 -3
  243. cognite/neat/{session → v0/session}/_explore.py +2 -2
  244. cognite/neat/{session → v0/session}/_fix.py +2 -2
  245. cognite/neat/{session → v0/session}/_inspect.py +3 -3
  246. cognite/neat/{session → v0/session}/_mapping.py +3 -3
  247. cognite/neat/{session → v0/session}/_plugin.py +4 -5
  248. cognite/neat/{session → v0/session}/_prepare.py +8 -8
  249. cognite/neat/{session → v0/session}/_read.py +33 -43
  250. cognite/neat/{session → v0/session}/_set.py +8 -8
  251. cognite/neat/{session → v0/session}/_show.py +5 -5
  252. cognite/neat/{session → v0/session}/_state.py +22 -8
  253. cognite/neat/{session → v0/session}/_subset.py +4 -4
  254. cognite/neat/{session → v0/session}/_template.py +11 -11
  255. cognite/neat/{session → v0/session}/_to.py +12 -12
  256. cognite/neat/{session → v0/session}/_wizard.py +1 -1
  257. cognite/neat/{session → v0/session}/engine/_load.py +1 -1
  258. cognite/neat/{session → v0/session}/exceptions.py +5 -5
  259. cognite/neat/v1.py +3 -0
  260. {cognite_neat-0.123.2.dist-info → cognite_neat-0.127.30.dist-info}/METADATA +9 -8
  261. cognite_neat-0.127.30.dist-info/RECORD +319 -0
  262. {cognite_neat-0.123.2.dist-info → cognite_neat-0.127.30.dist-info}/WHEEL +1 -1
  263. cognite/neat/core/_data_model/importers/_dtdl2data_model/__init__.py +0 -3
  264. cognite/neat/core/_data_model/importers/_dtdl2data_model/_unit_lookup.py +0 -224
  265. cognite/neat/core/_data_model/importers/_dtdl2data_model/dtdl_converter.py +0 -320
  266. cognite/neat/core/_data_model/importers/_dtdl2data_model/dtdl_importer.py +0 -155
  267. cognite/neat/core/_data_model/importers/_dtdl2data_model/spec.py +0 -363
  268. cognite/neat/core/_data_model/importers/_rdf/__init__.py +0 -5
  269. cognite/neat/core/_data_model/importers/_rdf/_imf2data_model.py +0 -98
  270. cognite/neat/core/_data_model/importers/_rdf/_owl2data_model.py +0 -87
  271. cognite/neat/core/_data_model/importers/_rdf/_shared.py +0 -168
  272. cognite/neat/core/_data_model/models/conceptual/_validation.py +0 -294
  273. cognite/neat/core/_data_model/models/entities/_loaders.py +0 -75
  274. cognite/neat/plugins/__init__.py +0 -3
  275. cognite/neat/plugins/data_model/importers/__init__.py +0 -5
  276. cognite/neat/plugins/data_model/importers/_base.py +0 -28
  277. cognite_neat-0.123.2.dist-info/RECORD +0 -197
  278. /cognite/neat/{core → _data_model}/__init__.py +0 -0
  279. /cognite/neat/{core/_client/_api → _data_model/deployer}/__init__.py +0 -0
  280. /cognite/neat/{core/_client/data_classes → _data_model/exporters/_table_exporter}/__init__.py +0 -0
  281. /cognite/neat/{core/_data_model → _data_model/importers/_table_importer}/__init__.py +0 -0
  282. /cognite/neat/{core/_instances → _data_model/models}/__init__.py +0 -0
  283. /cognite/neat/{core/_instances/extractors/_classic_cdf → _data_model/models/conceptual}/__init__.py +0 -0
  284. /cognite/neat/{core/_utils → _data_model/validation}/__init__.py +0 -0
  285. /cognite/neat/{plugins/data_model → _session/_html}/__init__.py +0 -0
  286. /cognite/neat/{core → v0/core}/_client/__init__.py +0 -0
  287. /cognite/neat/{core → v0/core}/_client/data_classes/data_modeling.py +0 -0
  288. /cognite/neat/{core → v0/core}/_client/data_classes/neat_sequence.py +0 -0
  289. /cognite/neat/{core → v0/core}/_client/data_classes/statistics.py +0 -0
  290. /cognite/neat/{core → v0/core}/_config.py +0 -0
  291. /cognite/neat/{core → v0/core}/_data_model/analysis/__init__.py +0 -0
  292. /cognite/neat/{core → v0/core}/_data_model/catalog/__init__.py +0 -0
  293. /cognite/neat/{core → v0/core}/_data_model/catalog/classic_model.xlsx +0 -0
  294. /cognite/neat/{core → v0/core}/_data_model/catalog/conceptual-imf-data-model.xlsx +0 -0
  295. /cognite/neat/{core → v0/core}/_data_model/catalog/hello_world_pump.xlsx +0 -0
  296. /cognite/neat/{core → v0/core}/_data_model/models/_base_unverified.py +0 -0
  297. /cognite/neat/{core → v0/core}/_data_model/models/conceptual/__init__.py +0 -0
  298. /cognite/neat/{core → v0/core}/_data_model/models/entities/_constants.py +0 -0
  299. /cognite/neat/{core → v0/core}/_data_model/models/entities/_wrapped.py +0 -0
  300. /cognite/neat/{core → v0/core}/_data_model/models/mapping/__init__.py +0 -0
  301. /cognite/neat/{core → v0/core}/_data_model/models/mapping/_classic2core.yaml +0 -0
  302. /cognite/neat/{core → v0/core}/_instances/_shared.py +0 -0
  303. /cognite/neat/{core → v0/core}/_instances/_tracking/__init__.py +0 -0
  304. /cognite/neat/{core → v0/core}/_instances/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
  305. /cognite/neat/{core → v0/core}/_instances/examples/Knowledge-Graph-Nordic44.xml +0 -0
  306. /cognite/neat/{core → v0/core}/_instances/examples/__init__.py +0 -0
  307. /cognite/neat/{core → v0/core}/_instances/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
  308. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_assets.py +0 -0
  309. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_data_sets.py +0 -0
  310. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_events.py +0 -0
  311. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_files.py +0 -0
  312. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_labels.py +0 -0
  313. /cognite/neat/{core → v0/core}/_instances/extractors/_classic_cdf/_timeseries.py +0 -0
  314. /cognite/neat/{core → v0/core}/_instances/loaders/__init__.py +0 -0
  315. /cognite/neat/{core → v0/core}/_instances/queries/__init__.py +0 -0
  316. /cognite/neat/{core → v0/core}/_instances/queries/_base.py +0 -0
  317. /cognite/neat/{core → v0/core}/_instances/queries/_queries.py +0 -0
  318. /cognite/neat/{core → v0/core}/_instances/transformers/__init__.py +0 -0
  319. /cognite/neat/{core → v0/core}/_issues/__init__.py +0 -0
  320. /cognite/neat/{core → v0/core}/_issues/formatters.py +0 -0
  321. /cognite/neat/{core → v0/core}/_shared.py +0 -0
  322. /cognite/neat/{core → v0/core}/_store/__init__.py +0 -0
  323. /cognite/neat/{core → v0/core}/_utils/io_.py +0 -0
  324. /cognite/neat/{core → v0/core}/_utils/reader/__init__.py +0 -0
  325. /cognite/neat/{core → v0/core}/_utils/time_.py +0 -0
  326. /cognite/neat/{core → v0/core}/_utils/xml_.py +0 -0
  327. /cognite/neat/{session → v0/session}/__init__.py +0 -0
  328. /cognite/neat/{session → v0/session}/_experimental.py +0 -0
  329. /cognite/neat/{session → v0/session}/_state/README.md +0 -0
  330. /cognite/neat/{session → v0/session}/engine/__init__.py +0 -0
  331. /cognite/neat/{session → v0/session}/engine/_import.py +0 -0
  332. /cognite/neat/{session → v0/session}/engine/_interface.py +0 -0
  333. {cognite_neat-0.123.2.dist-info → cognite_neat-0.127.30.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,222 @@
1
+ from collections.abc import Callable
2
+ from itertools import chain
3
+
4
+ from cognite.neat._client import NeatClient
5
+ from cognite.neat._data_model._analysis import DataModelAnalysis
6
+ from cognite.neat._data_model._shared import OnSuccessIssuesChecker
7
+ from cognite.neat._data_model.models.dms._container import ContainerRequest
8
+ from cognite.neat._data_model.models.dms._limits import SchemaLimits
9
+ from cognite.neat._data_model.models.dms._references import ContainerReference, DataModelReference, ViewReference
10
+ from cognite.neat._data_model.models.dms._schema import RequestSchema
11
+ from cognite.neat._data_model.models.dms._view_property import ViewCorePropertyRequest
12
+ from cognite.neat._data_model.models.dms._views import ViewRequest
13
+ from cognite.neat._data_model.validation.dms._limits import (
14
+ ContainerPropertyCountIsOutOfLimits,
15
+ ContainerPropertyListSizeIsOutOfLimits,
16
+ DataModelViewCountIsOutOfLimits,
17
+ ViewContainerCountIsOutOfLimits,
18
+ ViewImplementsCountIsOutOfLimits,
19
+ ViewPropertyCountIsOutOfLimits,
20
+ )
21
+ from cognite.neat._utils.useful_types import ModusOperandi
22
+
23
+ from ._ai_readiness import (
24
+ DataModelMissingDescription,
25
+ DataModelMissingName,
26
+ EnumerationMissingDescription,
27
+ EnumerationMissingName,
28
+ ViewMissingDescription,
29
+ ViewMissingName,
30
+ ViewPropertyMissingDescription,
31
+ ViewPropertyMissingName,
32
+ )
33
+ from ._base import CDFResources, DataModelValidator, LocalResources
34
+ from ._connections import (
35
+ ConnectionValueTypeUndefined,
36
+ ConnectionValueTypeUnexisting,
37
+ ReverseConnectionContainerMissing,
38
+ ReverseConnectionContainerPropertyMissing,
39
+ ReverseConnectionContainerPropertyWrongType,
40
+ ReverseConnectionPointsToAncestor,
41
+ ReverseConnectionSourcePropertyMissing,
42
+ ReverseConnectionSourcePropertyWrongType,
43
+ ReverseConnectionSourceViewMissing,
44
+ ReverseConnectionTargetMismatch,
45
+ ReverseConnectionTargetMissing,
46
+ )
47
+ from ._consistency import ViewSpaceVersionInconsistentWithDataModel
48
+ from ._containers import (
49
+ ExternalContainerDoesNotExist,
50
+ ExternalContainerPropertyDoesNotExist,
51
+ RequiredContainerDoesNotExist,
52
+ )
53
+ from ._views import ImplementedViewNotExisting, ViewToContainerMappingNotPossible
54
+
55
+
56
+ class DmsDataModelValidation(OnSuccessIssuesChecker):
57
+ """Placeholder for DMS Quality Assessment functionality."""
58
+
59
+ def __init__(
60
+ self,
61
+ client: NeatClient | None = None,
62
+ modus_operandi: ModusOperandi = "additive",
63
+ can_run_validator: Callable[[str, type], bool] | None = None,
64
+ ) -> None:
65
+ super().__init__()
66
+ self._client = client
67
+ self._can_run_validator = can_run_validator or (lambda code, issue_type: True) # type: ignore
68
+ self._modus_operandi = modus_operandi
69
+ self._has_run = False
70
+
71
+ def _gather_resources(self, data_model: RequestSchema) -> tuple[LocalResources, CDFResources, SchemaLimits]:
72
+ """Gather local and CDF resources needed for validation."""
73
+
74
+ analysis = DataModelAnalysis(data_model)
75
+
76
+ local_views_by_reference = analysis.view_by_reference(include_inherited_properties=True)
77
+ local_ancestors_by_view_reference = analysis.ancestors_by_view(list(local_views_by_reference.values()))
78
+ local_reverse_to_direct_mapping = analysis.reverse_to_direct_mapping
79
+ local_containers_by_reference = analysis.container_by_reference
80
+ local_data_model_views = set(data_model.data_model.views) if data_model.data_model.views else set()
81
+
82
+ local_resources = LocalResources(
83
+ data_model_description=data_model.data_model.description,
84
+ data_model_name=data_model.data_model.name,
85
+ data_model_reference=data_model.data_model.as_reference(),
86
+ views_by_reference=local_views_by_reference,
87
+ properties_by_view=analysis.properties_by_view,
88
+ ancestors_by_view_reference=local_ancestors_by_view_reference,
89
+ reverse_to_direct_mapping=local_reverse_to_direct_mapping,
90
+ containers_by_reference=local_containers_by_reference,
91
+ connection_end_node_types=analysis.connection_end_node_types,
92
+ data_model_views=local_data_model_views,
93
+ )
94
+
95
+ cdf_views_by_reference = self._cdf_view_by_reference(
96
+ list(analysis.referenced_views(include_connection_end_node_types=True)),
97
+ include_inherited_properties=True,
98
+ )
99
+ cdf_ancestors_by_view_reference = analysis.ancestors_by_view(list(cdf_views_by_reference.values()))
100
+ cdf_containers_by_reference = self._cdf_container_by_reference(
101
+ list(self._referenced_containers(local_views_by_reference, cdf_views_by_reference))
102
+ )
103
+ cdf_data_model_views = self._cdf_data_model_views(data_model.data_model.as_reference())
104
+
105
+ cdf_resources = CDFResources(
106
+ views_by_reference=cdf_views_by_reference,
107
+ ancestors_by_view_reference=cdf_ancestors_by_view_reference,
108
+ containers_by_reference=cdf_containers_by_reference,
109
+ data_model_views=cdf_data_model_views,
110
+ )
111
+
112
+ return local_resources, cdf_resources, self._cdf_limits()
113
+
114
+ def run(self, data_model: RequestSchema) -> None:
115
+ """Run quality assessment on the DMS data model."""
116
+
117
+ # Helper wrangled data model components
118
+ local_resources, cdf_resources, cdf_limits = self._gather_resources(data_model)
119
+
120
+ # Initialize all validators
121
+ validators: list[DataModelValidator] = [
122
+ # Limits
123
+ DataModelViewCountIsOutOfLimits(local_resources, cdf_resources, cdf_limits, self._modus_operandi),
124
+ ViewPropertyCountIsOutOfLimits(local_resources, cdf_resources, cdf_limits, self._modus_operandi),
125
+ ViewImplementsCountIsOutOfLimits(local_resources, cdf_resources, cdf_limits, self._modus_operandi),
126
+ ViewContainerCountIsOutOfLimits(local_resources, cdf_resources, cdf_limits, self._modus_operandi),
127
+ ContainerPropertyCountIsOutOfLimits(local_resources, cdf_resources, cdf_limits, self._modus_operandi),
128
+ ContainerPropertyListSizeIsOutOfLimits(local_resources, cdf_resources, cdf_limits, self._modus_operandi),
129
+ # Views
130
+ ViewToContainerMappingNotPossible(local_resources, cdf_resources, self._modus_operandi),
131
+ ImplementedViewNotExisting(local_resources, cdf_resources, self._modus_operandi),
132
+ # Containers
133
+ ExternalContainerDoesNotExist(local_resources, cdf_resources, self._modus_operandi),
134
+ ExternalContainerPropertyDoesNotExist(local_resources, cdf_resources, self._modus_operandi),
135
+ RequiredContainerDoesNotExist(local_resources, cdf_resources, self._modus_operandi),
136
+ # Consistency
137
+ ViewSpaceVersionInconsistentWithDataModel(local_resources, cdf_resources, self._modus_operandi),
138
+ # Connections
139
+ ConnectionValueTypeUnexisting(local_resources, cdf_resources, self._modus_operandi),
140
+ ConnectionValueTypeUndefined(local_resources, cdf_resources, self._modus_operandi),
141
+ ReverseConnectionContainerMissing(local_resources, cdf_resources, self._modus_operandi),
142
+ ReverseConnectionContainerPropertyMissing(local_resources, cdf_resources, self._modus_operandi),
143
+ ReverseConnectionContainerPropertyWrongType(local_resources, cdf_resources, self._modus_operandi),
144
+ ReverseConnectionSourceViewMissing(local_resources, cdf_resources, self._modus_operandi),
145
+ ReverseConnectionSourcePropertyMissing(local_resources, cdf_resources, self._modus_operandi),
146
+ ReverseConnectionSourcePropertyWrongType(local_resources, cdf_resources, self._modus_operandi),
147
+ ReverseConnectionPointsToAncestor(local_resources, cdf_resources, self._modus_operandi),
148
+ ReverseConnectionTargetMismatch(local_resources, cdf_resources, self._modus_operandi),
149
+ ReverseConnectionTargetMissing(local_resources, cdf_resources, self._modus_operandi),
150
+ # AI Readiness
151
+ DataModelMissingName(local_resources, cdf_resources, self._modus_operandi),
152
+ DataModelMissingDescription(local_resources, cdf_resources, self._modus_operandi),
153
+ ViewMissingName(local_resources, cdf_resources, self._modus_operandi),
154
+ ViewMissingDescription(local_resources, cdf_resources, self._modus_operandi),
155
+ ViewPropertyMissingName(local_resources, cdf_resources, self._modus_operandi),
156
+ ViewPropertyMissingDescription(local_resources, cdf_resources, self._modus_operandi),
157
+ EnumerationMissingName(local_resources, cdf_resources, self._modus_operandi),
158
+ EnumerationMissingDescription(local_resources, cdf_resources, self._modus_operandi),
159
+ ]
160
+
161
+ # Run validators
162
+ for validator in validators:
163
+ if self._can_run_validator(validator.code, validator.issue_type):
164
+ self._issues.extend(validator.run())
165
+
166
+ self._has_run = True
167
+
168
+ def _cdf_data_model_views(self, data_model_ref: DataModelReference) -> set[ViewReference]:
169
+ """Get all data model views in CDF."""
170
+
171
+ if not self._client:
172
+ return set()
173
+
174
+ data_model = self._client.data_models.retrieve([data_model_ref])
175
+
176
+ return set(data_model[0].views) if data_model and data_model[0].views else set()
177
+
178
+ def _cdf_view_by_reference(
179
+ self, views: list[ViewReference], include_inherited_properties: bool = True
180
+ ) -> dict[ViewReference, ViewRequest]:
181
+ """Fetch view definition from CDF."""
182
+
183
+ if not self._client:
184
+ return {}
185
+ return {
186
+ response.as_reference(): response.as_request()
187
+ for response in self._client.views.retrieve(
188
+ views, include_inherited_properties=include_inherited_properties
189
+ )
190
+ }
191
+
192
+ def _cdf_container_by_reference(
193
+ self, containers: list[ContainerReference]
194
+ ) -> dict[ContainerReference, ContainerRequest]:
195
+ """Fetch container definition from CDF."""
196
+
197
+ if not self._client:
198
+ return {}
199
+ return {
200
+ response.as_reference(): response.as_request() for response in self._client.containers.retrieve(containers)
201
+ }
202
+
203
+ def _cdf_limits(self) -> SchemaLimits:
204
+ """Fetch DMS statistics from CDF."""
205
+
206
+ if not self._client:
207
+ return SchemaLimits()
208
+ return SchemaLimits.from_api_response(self._client.statistics.project())
209
+
210
+ def _referenced_containers(
211
+ self,
212
+ local_views_by_reference: dict[ViewReference, ViewRequest],
213
+ cdf_views_by_reference: dict[ViewReference, ViewRequest],
214
+ ) -> set[ContainerReference]:
215
+ """Get all referenced containers in the physical data model both local and in CDF."""
216
+ return {
217
+ property_.container
218
+ for view in chain(local_views_by_reference.values(), cdf_views_by_reference.values())
219
+ if view.properties
220
+ for property_ in view.properties.values()
221
+ if isinstance(property_, ViewCorePropertyRequest)
222
+ }
@@ -0,0 +1,103 @@
1
+ """Validators for checking containers in the data model."""
2
+
3
+ from cognite.neat._data_model.models.dms._view_property import ViewCorePropertyRequest
4
+ from cognite.neat._data_model.validation.dms._base import DataModelValidator
5
+ from cognite.neat._issues import ConsistencyError
6
+
7
+ BASE_CODE = "NEAT-DMS-VIEW"
8
+
9
+
10
+ class ViewToContainerMappingNotPossible(DataModelValidator):
11
+ """Validates that container and container property referenced by view property exist.
12
+
13
+ ## What it does
14
+ Validates that for each view property that maps to a container and container property,
15
+ the referenced container and container property exist.
16
+
17
+ ## Why is this bad?
18
+ If a view property references a container or container property that does not exist,
19
+ the data model cannot be deployed to CDF. This means that view property will not be able to function.
20
+
21
+ ## Example
22
+ View WindTurbine has property location that maps to container WindTurbineContainer and property gpsCoordinates.
23
+ If WindTurbineContainer and/or property gpsCoordinates does not exist, the data model cannot be deployed to CDF.
24
+ """
25
+
26
+ code = f"{BASE_CODE}-001"
27
+ issue_type = ConsistencyError
28
+
29
+ def run(self) -> list[ConsistencyError]:
30
+ errors: list[ConsistencyError] = []
31
+
32
+ for view_ref, view in self.local_resources.views_by_reference.items():
33
+ for property_ref, property_ in view.properties.items():
34
+ if not isinstance(property_, ViewCorePropertyRequest):
35
+ continue
36
+
37
+ container_ref = property_.container
38
+ container_property = property_.container_property_identifier
39
+
40
+ container = self._select_container_with_property(container_ref, container_property)
41
+
42
+ if not container:
43
+ errors.append(
44
+ ConsistencyError(
45
+ message=(
46
+ f"View {view_ref!s} property {property_ref!s} maps to "
47
+ f"container {container_ref!s} which does not exist."
48
+ ),
49
+ fix="Define necessary container",
50
+ code=self.code,
51
+ )
52
+ )
53
+ elif container_property not in container.properties:
54
+ errors.append(
55
+ ConsistencyError(
56
+ message=(
57
+ f"View {view_ref!s} property {property_ref!s} maps to "
58
+ f"container {container_ref!s} which does not have "
59
+ f"property '{container_property}'."
60
+ ),
61
+ fix="Define necessary container property",
62
+ code=self.code,
63
+ )
64
+ )
65
+
66
+ return errors
67
+
68
+
69
+ class ImplementedViewNotExisting(DataModelValidator):
70
+ """Validates that implemented (inherited) view exists.
71
+
72
+ ## What it does
73
+ Validates that all views which are implemented (inherited) in the data model actually exist either locally
74
+ or in CDF.
75
+
76
+ ## Why is this bad?
77
+ If a view being implemented (inherited) does not exist, the data model cannot be deployed to CDF.
78
+
79
+ ## Example
80
+ If view WindTurbine implements (inherits) view Asset, but Asset view does not exist in the data model
81
+ or in CDF, the data model cannot be deployed to CDF.
82
+ """
83
+
84
+ code = f"{BASE_CODE}-002"
85
+ issue_type = ConsistencyError
86
+
87
+ def run(self) -> list[ConsistencyError]:
88
+ errors: list[ConsistencyError] = []
89
+
90
+ for view_ref, view in self.local_resources.views_by_reference.items():
91
+ if view.implements is None:
92
+ continue
93
+ for implement in view.implements:
94
+ if implement not in self.merged_views:
95
+ errors.append(
96
+ ConsistencyError(
97
+ message=f"View {view_ref!s} implements {implement!s} which is not defined.",
98
+ fix="Define the missing view or remove it from the implemented views list",
99
+ code=self.code,
100
+ )
101
+ )
102
+
103
+ return errors
@@ -0,0 +1,56 @@
1
+ from abc import ABC
2
+ from typing import TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING:
5
+ from cognite.neat._issues import ModelSyntaxError
6
+ from cognite.neat._utils.http_client import HTTPMessage
7
+
8
+
9
+ class NeatException(Exception, ABC):
10
+ """Base class for all exceptions raised by Neat."""
11
+
12
+ pass
13
+
14
+
15
+ class DataModelImportException(NeatException):
16
+ """Raised when there is an error importing a model."""
17
+
18
+ def __init__(self, errors: "list[ModelSyntaxError]") -> None:
19
+ super().__init__(errors)
20
+ self.errors = errors
21
+
22
+ def __str__(self) -> str:
23
+ return f"Model import failed with {len(self.errors)} errors: " + "; ".join(map(str, self.errors))
24
+
25
+
26
+ class CDFAPIException(NeatException):
27
+ """Raised when there is an error in an API call."""
28
+
29
+ def __init__(self, messages: "list[HTTPMessage]") -> None:
30
+ self.messages = messages
31
+
32
+ def __str__(self) -> str:
33
+ return f"{type(self).__name__}: " + "; ".join(map(str, self.messages))
34
+
35
+
36
+ class FileReadException(NeatException):
37
+ """Raised when there is an error reading a file."""
38
+
39
+ def __init__(self, filepath: str, message: str) -> None:
40
+ super().__init__(f"Error reading file {filepath}: {message}")
41
+ self.filepath = filepath
42
+ self.message = message
43
+
44
+ def __str__(self) -> str:
45
+ return f"Error reading file {self.filepath}: {self.message}"
46
+
47
+
48
+ class UserInputError(NeatException):
49
+ """Raised when there is an error in user input."""
50
+
51
+ def __init__(self, message: str) -> None:
52
+ super().__init__(message)
53
+ self.message = message
54
+
55
+ def __str__(self) -> str:
56
+ return f"User input error: {self.message}"
@@ -0,0 +1,68 @@
1
+ from collections import UserList, defaultdict
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class Issue(BaseModel):
7
+ """Base class for all issues"""
8
+
9
+ message: str
10
+ code: str | None = None
11
+ fix: str | None = None
12
+
13
+ @classmethod
14
+ def issue_type(cls) -> str:
15
+ return cls.__name__
16
+
17
+
18
+ class ModelSyntaxError(Issue):
19
+ """If any syntax error is found. Stop validation
20
+ and ask user to fix the syntax error first."""
21
+
22
+ ...
23
+
24
+
25
+ class ImplementationWarning(Issue):
26
+ """This is only for conceptual data model. It means that conversion to DMS
27
+ will fail unless user implements the missing part."""
28
+
29
+ ...
30
+
31
+
32
+ class ConsistencyError(Issue):
33
+ """If any consistency error is found, the deployment of the data model will fail. For example,
34
+ if a reverse direct relations points to a non-existing direct relation. This is only relevant for
35
+ DMS model.
36
+ """
37
+
38
+ ...
39
+
40
+
41
+ class Recommendation(Issue):
42
+ """Best practice recommendation."""
43
+
44
+ ...
45
+
46
+
47
+ class IssueList(UserList[Issue]):
48
+ """A list of issues that can be sorted by type and message."""
49
+
50
+ def by_type(self) -> dict[type[Issue], list[Issue]]:
51
+ """Returns a dictionary of issues sorted by their type."""
52
+ result: dict[type[Issue], list[Issue]] = defaultdict(list)
53
+ for issue in self.data:
54
+ issue_type = type(issue)
55
+ if issue_type not in result:
56
+ result[issue_type] = []
57
+ result[issue_type].append(issue)
58
+ return result
59
+
60
+ def by_code(self) -> dict[str, list[Issue]]:
61
+ """Returns a dictionary of issues sorted by their code."""
62
+ result: dict[str, list[Issue]] = defaultdict(list)
63
+ for issue in self.data:
64
+ if issue.code is not None:
65
+ result[issue.code].append(issue)
66
+ else:
67
+ result["UNDEFINED"].append(issue)
68
+ return dict(result)
@@ -0,0 +1,3 @@
1
+ from ._session import NeatSession
2
+
3
+ __all__ = ["NeatSession"]
@@ -0,0 +1,30 @@
1
+ from typing import Any, Literal, TypeAlias
2
+
3
+ from . import static, templates
4
+
5
+ ENCODING = "utf-8"
6
+
7
+ Template: TypeAlias = Literal["issues", "deployment"]
8
+
9
+
10
+ def render(template_name: Literal["issues", "deployment"], variables: dict[str, Any]) -> str:
11
+ """Generate HTML content from a template and variables."""
12
+
13
+ if template_name not in ["issues", "deployment"]:
14
+ raise ValueError(f"Unknown template name: {template_name}")
15
+
16
+ variables["SHARED_CSS"] = static.shared_style.read_text(encoding=ENCODING)
17
+
18
+ if template_name == "issues":
19
+ template = templates.issues.read_text(encoding=ENCODING)
20
+ variables["SCRIPTS"] = static.issues_scripts.read_text(encoding=ENCODING)
21
+ variables["SPECIFIC_CSS"] = static.issues_style.read_text(encoding=ENCODING)
22
+
23
+ elif template_name == "deployment":
24
+ template = templates.deployment.read_text(encoding=ENCODING)
25
+ variables["SCRIPTS"] = static.deployment_scripts.read_text(encoding=ENCODING)
26
+ variables["SPECIFIC_CSS"] = static.deployment_style.read_text(encoding=ENCODING)
27
+
28
+ for key, value in variables.items():
29
+ template = template.replace(f"{{{{{key}}}}}", str(value))
30
+ return template
@@ -0,0 +1,8 @@
1
+ from pathlib import Path
2
+
3
+ shared_style = Path(__file__).parent / "shared.css"
4
+ issues_style = Path(__file__).parent / "issues.css"
5
+ issues_scripts = Path(__file__).parent / "issues.js"
6
+
7
+ deployment_style = Path(__file__).parent / "deployment.css"
8
+ deployment_scripts = Path(__file__).parent / "deployment.js"