simstack 2.0.1__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 (354) hide show
  1. simstack/__init__.py +0 -0
  2. simstack/_version.py +24 -0
  3. simstack/core/__init__.py +0 -0
  4. simstack/core/artifacts.py +406 -0
  5. simstack/core/asnyc_helper.py +14 -0
  6. simstack/core/config_file.py +60 -0
  7. simstack/core/context.py +283 -0
  8. simstack/core/definitions.py +22 -0
  9. simstack/core/engine.py +115 -0
  10. simstack/core/find_simstack_modules.py +41 -0
  11. simstack/core/hash.py +179 -0
  12. simstack/core/node.py +1137 -0
  13. simstack/core/node_claim.py +31 -0
  14. simstack/core/node_runner.py +362 -0
  15. simstack/core/process_results.py +102 -0
  16. simstack/core/recompute_artifacts.py +117 -0
  17. simstack/core/reset_db.py +12 -0
  18. simstack/core/resource_assignment.py +222 -0
  19. simstack/core/resources.py +90 -0
  20. simstack/core/route_table.py +24 -0
  21. simstack/core/run_docker.py +109 -0
  22. simstack/core/run_node.py +71 -0
  23. simstack/core/runner.py +169 -0
  24. simstack/core/services/__init__.py +11 -0
  25. simstack/core/services/base_service.py +191 -0
  26. simstack/core/services/file_transfer_service.py +117 -0
  27. simstack/core/services/git_restart_service.py +12 -0
  28. simstack/core/services/git_uv_update_service.py +105 -0
  29. simstack/core/services/node_execution_service.py +182 -0
  30. simstack/core/services/resource_branch_monitor_service.py +71 -0
  31. simstack/core/services/runner_cleanup_service.py +149 -0
  32. simstack/core/services/runner_manager.py +163 -0
  33. simstack/core/services/runner_status_service.py +10 -0
  34. simstack/core/services/slurm_status_service.py +67 -0
  35. simstack/core/services/stop_check_service.py +27 -0
  36. simstack/core/services/timeout_restart_service.py +26 -0
  37. simstack/core/simstack_result.py +39 -0
  38. simstack/core/submit_node.py +217 -0
  39. simstack/core/task_id.py +22 -0
  40. simstack/methods/__init__.py +0 -0
  41. simstack/methods/archive_files.py +292 -0
  42. simstack/methods/fire_and_forget_runner.py +113 -0
  43. simstack/methods/generate_test.py +125 -0
  44. simstack/methods/get_file.py +26 -0
  45. simstack/methods/mass_runner.py +154 -0
  46. simstack/methods/multiple_executor.py +307 -0
  47. simstack/methods/switch_git.py +16 -0
  48. simstack/methods/upload_helpers.py +81 -0
  49. simstack/models/__init__.py +74 -0
  50. simstack/models/array_list.py +21 -0
  51. simstack/models/array_storage.py +83 -0
  52. simstack/models/artifact_models.py +127 -0
  53. simstack/models/base_lists.py +51 -0
  54. simstack/models/base_types.py +209 -0
  55. simstack/models/charts_artifact.py +690 -0
  56. simstack/models/dataset.py +451 -0
  57. simstack/models/dataset_metadata.py +390 -0
  58. simstack/models/datasettuple.py +587 -0
  59. simstack/models/file_instance.py +150 -0
  60. simstack/models/file_list.py +45 -0
  61. simstack/models/files.py +424 -0
  62. simstack/models/fire_and_forget_result.py +19 -0
  63. simstack/models/images2d.py +113 -0
  64. simstack/models/log_entry_model.py +37 -0
  65. simstack/models/models.py +52 -0
  66. simstack/models/named_data_reference.py +36 -0
  67. simstack/models/node_registry.py +96 -0
  68. simstack/models/pandas_model.py +239 -0
  69. simstack/models/parameters.py +402 -0
  70. simstack/models/pickle_models.py +300 -0
  71. simstack/models/project.py +13 -0
  72. simstack/models/resource_assignment.py +170 -0
  73. simstack/models/resource_definition.py +125 -0
  74. simstack/models/runner_model.py +39 -0
  75. simstack/models/simple_table.py +79 -0
  76. simstack/models/simstack_model.py +97 -0
  77. simstack/models/slurm_info.py +17 -0
  78. simstack/models/table_artifact.py +87 -0
  79. simstack/models/tag.py +12 -0
  80. simstack/models/unused_test_file.py +5 -0
  81. simstack/simstack_marker.com +1 -0
  82. simstack/static/docs/.buildinfo +4 -0
  83. simstack/static/docs/_images/GUI Concept.webp +0 -0
  84. simstack/static/docs/_modules/index.html +434 -0
  85. simstack/static/docs/_modules/simstack/core/artifacts.html +743 -0
  86. simstack/static/docs/_modules/simstack/core/asnyc_helper.html +330 -0
  87. simstack/static/docs/_modules/simstack/core/config_file.html +379 -0
  88. simstack/static/docs/_modules/simstack/core/definitions.html +341 -0
  89. simstack/static/docs/_modules/simstack/core/engine.html +437 -0
  90. simstack/static/docs/_modules/simstack/core/find_simstack_modules.html +360 -0
  91. simstack/static/docs/_modules/simstack/core/hash.html +528 -0
  92. simstack/static/docs/_modules/simstack/core/node.html +1392 -0
  93. simstack/static/docs/_modules/simstack/core/node_claim.html +347 -0
  94. simstack/static/docs/_modules/simstack/core/node_runner.html +711 -0
  95. simstack/static/docs/_modules/simstack/core/process_results.html +418 -0
  96. simstack/static/docs/_modules/simstack/core/recompute_artifacts.html +433 -0
  97. simstack/static/docs/_modules/simstack/core/reset_db.html +328 -0
  98. simstack/static/docs/_modules/simstack/core/resource_assignment.html +553 -0
  99. simstack/static/docs/_modules/simstack/core/resources.html +424 -0
  100. simstack/static/docs/_modules/simstack/core/route_table.html +349 -0
  101. simstack/static/docs/_modules/simstack/core/run_docker.html +425 -0
  102. simstack/static/docs/_modules/simstack/core/run_node.html +390 -0
  103. simstack/static/docs/_modules/simstack/core/runner.html +491 -0
  104. simstack/static/docs/_modules/simstack/core/services/base_service.html +522 -0
  105. simstack/static/docs/_modules/simstack/core/services/file_transfer_service.html +436 -0
  106. simstack/static/docs/_modules/simstack/core/services/git_restart_service.html +331 -0
  107. simstack/static/docs/_modules/simstack/core/services/git_uv_update_service.html +427 -0
  108. simstack/static/docs/_modules/simstack/core/services/node_execution_service.html +507 -0
  109. simstack/static/docs/_modules/simstack/core/services/resource_branch_monitor_service.html +390 -0
  110. simstack/static/docs/_modules/simstack/core/services/runner_cleanup_service.html +468 -0
  111. simstack/static/docs/_modules/simstack/core/services/runner_manager.html +485 -0
  112. simstack/static/docs/_modules/simstack/core/services/runner_status_service.html +329 -0
  113. simstack/static/docs/_modules/simstack/core/services/slurm_status_service.html +386 -0
  114. simstack/static/docs/_modules/simstack/core/services/stop_check_service.html +346 -0
  115. simstack/static/docs/_modules/simstack/core/services/timeout_restart_service.html +345 -0
  116. simstack/static/docs/_modules/simstack/core/simstack_result.html +355 -0
  117. simstack/static/docs/_modules/simstack/core/submit_node.html +536 -0
  118. simstack/static/docs/_modules/simstack/core/task_id.html +344 -0
  119. simstack/static/docs/_modules/simstack/methods/archive_files.html +598 -0
  120. simstack/static/docs/_modules/simstack/methods/fire_and_forget_runner.html +432 -0
  121. simstack/static/docs/_modules/simstack/methods/generate_test.html +443 -0
  122. simstack/static/docs/_modules/simstack/methods/get_file.html +342 -0
  123. simstack/static/docs/_modules/simstack/methods/mass_runner.html +476 -0
  124. simstack/static/docs/_modules/simstack/methods/multiple_executor.html +674 -0
  125. simstack/static/docs/_modules/simstack/methods/switch_git.html +332 -0
  126. simstack/static/docs/_modules/simstack/methods/upload_helpers.html +403 -0
  127. simstack/static/docs/_modules/simstack/models/array_list.html +337 -0
  128. simstack/static/docs/_modules/simstack/models/array_storage.html +417 -0
  129. simstack/static/docs/_modules/simstack/models/base_lists.html +374 -0
  130. simstack/static/docs/_modules/simstack/models/base_types.html +588 -0
  131. simstack/static/docs/_modules/simstack/models/charts_artifact.html +1035 -0
  132. simstack/static/docs/_modules/simstack/models/dataset.html +866 -0
  133. simstack/static/docs/_modules/simstack/models/dataset_metadata.html +711 -0
  134. simstack/static/docs/_modules/simstack/models/datasettuple.html +1005 -0
  135. simstack/static/docs/_modules/simstack/models/file_instance.html +472 -0
  136. simstack/static/docs/_modules/simstack/models/file_list.html +367 -0
  137. simstack/static/docs/_modules/simstack/models/files.html +773 -0
  138. simstack/static/docs/_modules/simstack/models/fire_and_forget_result.html +335 -0
  139. simstack/static/docs/_modules/simstack/models/images2d.html +447 -0
  140. simstack/static/docs/_modules/simstack/models/log_entry_model.html +356 -0
  141. simstack/static/docs/_modules/simstack/models/models.html +374 -0
  142. simstack/static/docs/_modules/simstack/models/named_data_reference.html +355 -0
  143. simstack/static/docs/_modules/simstack/models/node_registry.html +415 -0
  144. simstack/static/docs/_modules/simstack/models/pandas_model.html +570 -0
  145. simstack/static/docs/_modules/simstack/models/parameters.html +739 -0
  146. simstack/static/docs/_modules/simstack/models/pickle_models.html +631 -0
  147. simstack/static/docs/_modules/simstack/models/project.html +329 -0
  148. simstack/static/docs/_modules/simstack/models/resource_assignment.html +501 -0
  149. simstack/static/docs/_modules/simstack/models/resource_definition.html +477 -0
  150. simstack/static/docs/_modules/simstack/models/runner_model.html +361 -0
  151. simstack/static/docs/_modules/simstack/models/simple_table.html +413 -0
  152. simstack/static/docs/_modules/simstack/models/simstack_model.html +416 -0
  153. simstack/static/docs/_modules/simstack/models/slurm_info.html +333 -0
  154. simstack/static/docs/_modules/simstack/models/table_artifact.html +406 -0
  155. simstack/static/docs/_modules/simstack/models/tag.html +328 -0
  156. simstack/static/docs/_modules/simstack/tables/model_table.html +519 -0
  157. simstack/static/docs/_modules/simstack/tables/node_children.html +538 -0
  158. simstack/static/docs/_modules/simstack/tables/node_table.html +854 -0
  159. simstack/static/docs/_modules/simstack/tables/table_builder.html +642 -0
  160. simstack/static/docs/_modules/simstack/util/async_zip_utils.html +337 -0
  161. simstack/static/docs/_modules/simstack/util/b64mixin.html +339 -0
  162. simstack/static/docs/_modules/simstack/util/cleaned_json_schema.html +336 -0
  163. simstack/static/docs/_modules/simstack/util/config_reader.html +498 -0
  164. simstack/static/docs/_modules/simstack/util/custom_model_dump.html +391 -0
  165. simstack/static/docs/_modules/simstack/util/database_information.html +488 -0
  166. simstack/static/docs/_modules/simstack/util/db.html +1392 -0
  167. simstack/static/docs/_modules/simstack/util/db_logger.html +448 -0
  168. simstack/static/docs/_modules/simstack/util/default_from_dict.html +376 -0
  169. simstack/static/docs/_modules/simstack/util/directory_iterator.html +553 -0
  170. simstack/static/docs/_modules/simstack/util/docstring_parser.html +526 -0
  171. simstack/static/docs/_modules/simstack/util/file_hashing.html +394 -0
  172. simstack/static/docs/_modules/simstack/util/file_transfer_client.html +791 -0
  173. simstack/static/docs/_modules/simstack/util/files.html +733 -0
  174. simstack/static/docs/_modules/simstack/util/find_python_files.html +349 -0
  175. simstack/static/docs/_modules/simstack/util/generate_ui_schema.html +396 -0
  176. simstack/static/docs/_modules/simstack/util/generic_list_mixin.html +487 -0
  177. simstack/static/docs/_modules/simstack/util/get_module_path.html +336 -0
  178. simstack/static/docs/_modules/simstack/util/git_pull.html +381 -0
  179. simstack/static/docs/_modules/simstack/util/git_repository_status.html +411 -0
  180. simstack/static/docs/_modules/simstack/util/import_module.html +377 -0
  181. simstack/static/docs/_modules/simstack/util/importer.html +637 -0
  182. simstack/static/docs/_modules/simstack/util/init_data_source.html +357 -0
  183. simstack/static/docs/_modules/simstack/util/make_graph.html +423 -0
  184. simstack/static/docs/_modules/simstack/util/make_table.html +1171 -0
  185. simstack/static/docs/_modules/simstack/util/mappings.html +378 -0
  186. simstack/static/docs/_modules/simstack/util/minimal_route_finder.html +388 -0
  187. simstack/static/docs/_modules/simstack/util/mock_db.html +472 -0
  188. simstack/static/docs/_modules/simstack/util/module_path_checker.html +354 -0
  189. simstack/static/docs/_modules/simstack/util/object_list_mixin.html +649 -0
  190. simstack/static/docs/_modules/simstack/util/path_manager.html +566 -0
  191. simstack/static/docs/_modules/simstack/util/project_root_finder.html +357 -0
  192. simstack/static/docs/_modules/simstack/util/queue_watcher.html +593 -0
  193. simstack/static/docs/_modules/simstack/util/resource_config.html +532 -0
  194. simstack/static/docs/_modules/simstack/util/route_finder.html +390 -0
  195. simstack/static/docs/_modules/simstack/util/runner_util.html +487 -0
  196. simstack/static/docs/_modules/simstack/util/runner_utils.html +468 -0
  197. simstack/static/docs/_modules/simstack/util/safe_code_executor.html +510 -0
  198. simstack/static/docs/_modules/simstack/util/sample_config.html +414 -0
  199. simstack/static/docs/_modules/simstack/util/sensitive_content_filter.html +364 -0
  200. simstack/static/docs/_modules/simstack/util/setup_logging.html +365 -0
  201. simstack/static/docs/_modules/simstack/util/submit_to_watchdog.html +425 -0
  202. simstack/static/docs/_modules/simstack/util/toml_reader.html +482 -0
  203. simstack/static/docs/_modules/simstack/util/transform_file_name.html +357 -0
  204. simstack/static/docs/_modules/simstack/util/ui_tools.html +541 -0
  205. simstack/static/docs/_sources/architecture.rst.txt +25 -0
  206. simstack/static/docs/_sources/array_lists.rst.txt +60 -0
  207. simstack/static/docs/_sources/ci_pipeline.rst.txt +34 -0
  208. simstack/static/docs/_sources/data.rst.txt +175 -0
  209. simstack/static/docs/_sources/database_migrations.rst.txt +310 -0
  210. simstack/static/docs/_sources/datasets.rst.txt +93 -0
  211. simstack/static/docs/_sources/developer_guide.rst.txt +25 -0
  212. simstack/static/docs/_sources/docker_nodes.rst.txt +149 -0
  213. simstack/static/docs/_sources/files.rst.txt +159 -0
  214. simstack/static/docs/_sources/fire_and_forget_runner.rst.txt +67 -0
  215. simstack/static/docs/_sources/index.rst.txt +25 -0
  216. simstack/static/docs/_sources/installation.rst.txt +213 -0
  217. simstack/static/docs/_sources/lists.rst.txt +111 -0
  218. simstack/static/docs/_sources/mass_runner.rst.txt +91 -0
  219. simstack/static/docs/_sources/misc.rst.txt +106 -0
  220. simstack/static/docs/_sources/overview.rst.txt +91 -0
  221. simstack/static/docs/_sources/recovery.rst.txt +38 -0
  222. simstack/static/docs/_sources/resource_config.rst.txt +141 -0
  223. simstack/static/docs/_sources/simstack/modules/modules.rst.txt +7 -0
  224. simstack/static/docs/_sources/simstack/modules/simstack.core.rst.txt +205 -0
  225. simstack/static/docs/_sources/simstack/modules/simstack.core.services.rst.txt +109 -0
  226. simstack/static/docs/_sources/simstack/modules/simstack.methods.rst.txt +77 -0
  227. simstack/static/docs/_sources/simstack/modules/simstack.models.rst.txt +261 -0
  228. simstack/static/docs/_sources/simstack/modules/simstack.rst.txt +22 -0
  229. simstack/static/docs/_sources/simstack/modules/simstack.tables.rst.txt +45 -0
  230. simstack/static/docs/_sources/simstack/modules/simstack.util.rst.txt +381 -0
  231. simstack/static/docs/_sources/submit.rst.txt +141 -0
  232. simstack/static/docs/_sources/tables.rst.txt +50 -0
  233. simstack/static/docs/_sources/testing_complex_nodes.rst.txt +92 -0
  234. simstack/static/docs/_sources/ui_documentation.rst.txt +272 -0
  235. simstack/static/docs/_sources/workflows.rst.txt +446 -0
  236. simstack/static/docs/_static/base-stemmer.js +476 -0
  237. simstack/static/docs/_static/basic.css +906 -0
  238. simstack/static/docs/_static/cobalt2-theme.css +1 -0
  239. simstack/static/docs/_static/debug.css +69 -0
  240. simstack/static/docs/_static/docs-build-badge.css +51 -0
  241. simstack/static/docs/_static/docs-build-badge.js +51 -0
  242. simstack/static/docs/_static/doctools.js +150 -0
  243. simstack/static/docs/_static/documentation_options.js +13 -0
  244. simstack/static/docs/_static/english-stemmer.js +1066 -0
  245. simstack/static/docs/_static/file.png +0 -0
  246. simstack/static/docs/_static/language_data.js +13 -0
  247. simstack/static/docs/_static/minus.png +0 -0
  248. simstack/static/docs/_static/plus.png +0 -0
  249. simstack/static/docs/_static/pygments.css +250 -0
  250. simstack/static/docs/_static/scripts/furo-extensions.js +0 -0
  251. simstack/static/docs/_static/scripts/furo.js +3 -0
  252. simstack/static/docs/_static/scripts/furo.js.LICENSE.txt +7 -0
  253. simstack/static/docs/_static/scripts/furo.js.map +1 -0
  254. simstack/static/docs/_static/searchtools.js +693 -0
  255. simstack/static/docs/_static/skeleton.css +296 -0
  256. simstack/static/docs/_static/sphinx_highlight.js +159 -0
  257. simstack/static/docs/_static/styles/furo-extensions.css +2 -0
  258. simstack/static/docs/_static/styles/furo-extensions.css.map +1 -0
  259. simstack/static/docs/_static/styles/furo.css +2 -0
  260. simstack/static/docs/_static/styles/furo.css.map +1 -0
  261. simstack/static/docs/architecture.html +340 -0
  262. simstack/static/docs/array_lists.html +678 -0
  263. simstack/static/docs/ci_pipeline.html +385 -0
  264. simstack/static/docs/data.html +545 -0
  265. simstack/static/docs/database_migrations.html +652 -0
  266. simstack/static/docs/datasets.html +1268 -0
  267. simstack/static/docs/developer_guide.html +359 -0
  268. simstack/static/docs/docker_nodes.html +503 -0
  269. simstack/static/docs/files.html +718 -0
  270. simstack/static/docs/fire_and_forget_runner.html +641 -0
  271. simstack/static/docs/genindex.html +6390 -0
  272. simstack/static/docs/index.html +516 -0
  273. simstack/static/docs/installation.html +553 -0
  274. simstack/static/docs/lists.html +478 -0
  275. simstack/static/docs/mass_runner.html +481 -0
  276. simstack/static/docs/misc.html +454 -0
  277. simstack/static/docs/objects.inv +0 -0
  278. simstack/static/docs/overview.html +469 -0
  279. simstack/static/docs/py-modindex.html +1111 -0
  280. simstack/static/docs/recovery.html +371 -0
  281. simstack/static/docs/resource_config.html +590 -0
  282. simstack/static/docs/search.html +327 -0
  283. simstack/static/docs/searchindex.js +1 -0
  284. simstack/static/docs/simstack/modules/modules.html +489 -0
  285. simstack/static/docs/simstack/modules/simstack.core.html +1883 -0
  286. simstack/static/docs/simstack/modules/simstack.core.services.html +698 -0
  287. simstack/static/docs/simstack/modules/simstack.html +3060 -0
  288. simstack/static/docs/simstack/modules/simstack.methods.html +1150 -0
  289. simstack/static/docs/simstack/modules/simstack.models.html +13113 -0
  290. simstack/static/docs/simstack/modules/simstack.tables.html +635 -0
  291. simstack/static/docs/simstack/modules/simstack.util.html +3320 -0
  292. simstack/static/docs/submit.html +487 -0
  293. simstack/static/docs/tables.html +539 -0
  294. simstack/static/docs/testing_complex_nodes.html +458 -0
  295. simstack/static/docs/ui_documentation.html +788 -0
  296. simstack/static/docs/workflows.html +766 -0
  297. simstack/tables/__init__.py +0 -0
  298. simstack/tables/model_table.py +191 -0
  299. simstack/tables/node_children.py +219 -0
  300. simstack/tables/node_table.py +517 -0
  301. simstack/tables/table_builder.py +314 -0
  302. simstack/util/__init__.py +0 -0
  303. simstack/util/async_zip_utils.py +18 -0
  304. simstack/util/b64mixin.py +23 -0
  305. simstack/util/cleaned_json_schema.py +20 -0
  306. simstack/util/config_reader.py +179 -0
  307. simstack/util/custom_model_dump.py +75 -0
  308. simstack/util/database_information.py +160 -0
  309. simstack/util/db.py +1013 -0
  310. simstack/util/db_logger.py +117 -0
  311. simstack/util/default_from_dict.py +57 -0
  312. simstack/util/directory_iterator.py +216 -0
  313. simstack/util/docstring_parser.py +186 -0
  314. simstack/util/file_hashing.py +72 -0
  315. simstack/util/file_transfer_client.py +427 -0
  316. simstack/util/files.py +396 -0
  317. simstack/util/find_python_files.py +33 -0
  318. simstack/util/generate_ui_schema.py +80 -0
  319. simstack/util/generic_list_mixin.py +120 -0
  320. simstack/util/geometry_utils.py +118 -0
  321. simstack/util/get_module_path.py +20 -0
  322. simstack/util/git_pull.py +65 -0
  323. simstack/util/git_repository_status.py +95 -0
  324. simstack/util/import_module.py +63 -0
  325. simstack/util/importer.py +312 -0
  326. simstack/util/init_data_source.py +41 -0
  327. simstack/util/make_graph.py +107 -0
  328. simstack/util/make_table.py +837 -0
  329. simstack/util/mappings.py +41 -0
  330. simstack/util/minimal_route_finder.py +72 -0
  331. simstack/util/mock_db.py +144 -0
  332. simstack/util/module_path_checker.py +38 -0
  333. simstack/util/object_list_mixin.py +282 -0
  334. simstack/util/path_manager.py +223 -0
  335. simstack/util/project_root_finder.py +41 -0
  336. simstack/util/queue_watcher.py +262 -0
  337. simstack/util/resource_config.py +198 -0
  338. simstack/util/route_finder.py +74 -0
  339. simstack/util/runner_util.py +166 -0
  340. simstack/util/runner_utils.py +143 -0
  341. simstack/util/safe_code_executor.py +194 -0
  342. simstack/util/sample_config.py +98 -0
  343. simstack/util/sensitive_content_filter.py +48 -0
  344. simstack/util/setup_logging.py +49 -0
  345. simstack/util/submit_to_watchdog.py +106 -0
  346. simstack/util/toml_reader.py +142 -0
  347. simstack/util/transform_file_name.py +41 -0
  348. simstack/util/ui_tools.py +213 -0
  349. simstack-2.0.1.dist-info/METADATA +454 -0
  350. simstack-2.0.1.dist-info/RECORD +354 -0
  351. simstack-2.0.1.dist-info/WHEEL +5 -0
  352. simstack-2.0.1.dist-info/entry_points.txt +12 -0
  353. simstack-2.0.1.dist-info/licenses/LICENSE +21 -0
  354. simstack-2.0.1.dist-info/top_level.txt +1 -0
simstack/__init__.py ADDED
File without changes
simstack/_version.py ADDED
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '2.0.1'
22
+ __version_tuple__ = version_tuple = (2, 0, 1)
23
+
24
+ __commit_id__ = commit_id = None
File without changes
@@ -0,0 +1,406 @@
1
+ import inspect
2
+ import logging
3
+ import re
4
+ from typing import Any, Callable, Optional, List
5
+
6
+ from odmantic import ObjectId
7
+
8
+ from simstack.core.context import context
9
+ from simstack.models.artifact_models import ArtifactMapping, ArtifactModel
10
+ from simstack.models.charts_artifact import ChartArtifactModel
11
+ from simstack.models.node_registry import find_child_nodes, NodeRegistry
12
+ from simstack.models.table_artifact import TableArtifactModel
13
+ from simstack.util.db import Database
14
+ from simstack.util.importer import import_function
15
+
16
+ logger = logging.getLogger("artifacts")
17
+
18
+
19
+ class ArtifactArguments:
20
+ def __init__(self, result: Any, task_id: ObjectId | None = None) -> None:
21
+ self.task_id = task_id
22
+ self.result = result
23
+ self.child_artifacts: list[ArtifactModel] = []
24
+ self.call_path: str | None = None
25
+
26
+ def add_attributes(
27
+ self, func: Callable[..., Any], *args: Any, **kwargs: Any
28
+ ) -> None:
29
+ if not callable(func):
30
+ raise ValueError("func must be callable")
31
+ # Get function parameter names
32
+ sig = inspect.signature(func)
33
+ parameters = list(sig.parameters.keys())
34
+ # Map positional args to parameter names
35
+ for param_name, arg_value in zip(parameters, args):
36
+ setattr(self, param_name, arg_value)
37
+ # Map keyword args directly
38
+ for param_name, arg_value in kwargs.items():
39
+ setattr(self, param_name, arg_value)
40
+
41
+
42
+ async def find_artifact_mappings(
43
+ node_registry_path: str, db: Database, task_id: Optional[str] = None
44
+ ) -> List[ArtifactMapping]:
45
+ logger.debug(
46
+ f"task_id: {task_id} Loading artifacts with regex pattern: {node_registry_path} "
47
+ )
48
+ all_mappings = await db.find(ArtifactMapping)
49
+
50
+ # Filter them manually to find those whose patterns match your path
51
+ matching_mappings = [
52
+ mapping
53
+ for mapping in all_mappings
54
+ if re.match(mapping.regex_pattern, node_registry_path)
55
+ ]
56
+
57
+ for mapping in matching_mappings:
58
+ logger.debug(
59
+ f"task_id: {task_id} Artifact found: {mapping.name} with path: {mapping.regex_pattern}"
60
+ )
61
+ return matching_mappings
62
+
63
+
64
+ async def register_artifact_mapping(
65
+ artifact_mapping: ArtifactMapping,
66
+ ) -> ArtifactMapping:
67
+ # Check if an artifact with the same name already exists
68
+ existing = await context.db.find_one(
69
+ ArtifactMapping, ArtifactMapping.name == artifact_mapping.name
70
+ )
71
+ if existing:
72
+ logger.warning(
73
+ f"Replacing existing artifact mapping '{artifact_mapping.name}' already exists with path: {existing.regex_pattern}"
74
+ )
75
+ existing.set_values(artifact_mapping)
76
+ artifact_mapping = await context.db.save(existing)
77
+
78
+ # Check if the function_mapping is specified and not CODE
79
+ if (
80
+ artifact_mapping.function_mapping
81
+ and artifact_mapping.function_mapping != "CODE"
82
+ ):
83
+ try:
84
+ # Import the function to verify it exists
85
+ func = await import_function(
86
+ artifact_mapping.function_mapping, context.db, task_id=None
87
+ )
88
+ if not func:
89
+ logger.warning(
90
+ "Could not import function {artifact_mapping.function_mapping}"
91
+ )
92
+ except Exception as e:
93
+ logger.error(
94
+ f"Error processing function {artifact_mapping.function_mapping}: {e}"
95
+ )
96
+ return await context.db.save(artifact_mapping)
97
+
98
+
99
+ async def find_all_artifacts(
100
+ node_registry: NodeRegistry, db: Database
101
+ ) -> List[ArtifactModel]:
102
+ return [
103
+ await db.find_one(ArtifactModel, ArtifactModel.id == artifact_id)
104
+ for artifact_id in node_registry.artifact_ids
105
+ ]
106
+
107
+
108
+ async def create_artifacts(
109
+ artifact_arguments: ArtifactArguments, node_registry: NodeRegistry
110
+ ) -> List[ObjectId]:
111
+ try:
112
+ call_path = node_registry.call_path
113
+ task_id = node_registry.id
114
+ log_string = f"create artifacts for task_id: {task_id} for {call_path}"
115
+
116
+ artifact_mappings_list = await find_artifact_mappings(
117
+ call_path, context.db, task_id=task_id
118
+ )
119
+
120
+ child_nodes = await find_child_nodes(task_id)
121
+ logger.info(
122
+ f"{log_string} Found {len(artifact_mappings_list)} artifact mappings for path: {call_path} and {len(child_nodes)} child nodes."
123
+ )
124
+ # Concatenate artifacts from all child nodes
125
+ child_artifacts: list[ArtifactModel] = []
126
+ for child_node in child_nodes:
127
+ loaded_artifacts = await find_all_artifacts(child_node, context.db)
128
+ if len(loaded_artifacts) == 1:
129
+ child_artifacts.extend(loaded_artifacts)
130
+ elif len(loaded_artifacts) > 1:
131
+ # If multiple artifacts, consolidate them into a list
132
+ consolidated_artifact = ArtifactModel(
133
+ name=child_node.name,
134
+ path=call_path,
135
+ data={
136
+ node_registry.name: loaded_artifacts
137
+ }, # Store all artifacts in a single field
138
+ )
139
+ await context.db.save(consolidated_artifact)
140
+ child_artifacts.append(consolidated_artifact)
141
+
142
+ # child_artifacts = consolidate_artifacts(child_artifacts, call_path, task_id)
143
+ artifact_arguments.child_artifacts = child_artifacts
144
+ artifact_arguments.call_path = call_path
145
+
146
+ artifact_list: list[ArtifactModel] = []
147
+
148
+ if len(artifact_mappings_list) > 0:
149
+ for artifact_mapping in artifact_mappings_list:
150
+ # Count existing artifacts with the same mapping
151
+ existing_count = len(
152
+ [a for a in artifact_list if a.path.endswith(artifact_mapping.name)]
153
+ )
154
+ log_string_mapping = (
155
+ f"{log_string} Artifact: {artifact_mapping.name} #:{existing_count}"
156
+ )
157
+ logging.info(log_string_mapping)
158
+ if artifact_mapping.function_mapping != "CODE":
159
+ func = await import_function(
160
+ artifact_mapping.function_mapping,
161
+ context.db,
162
+ artifact_arguments.task_id,
163
+ )
164
+ if not func:
165
+ logger.error(
166
+ f"{log_string_mapping} Function {artifact_mapping.function_mapping} not found for artifact mapping."
167
+ )
168
+ continue
169
+ logger.info(
170
+ f"{log_string_mapping} Executing function {artifact_mapping.function_mapping} for artifact mapping."
171
+ )
172
+ artifact_result = func(artifact_arguments)
173
+ else:
174
+ from simstack.util.safe_code_executor import safe_code_executor
175
+
176
+ result = safe_code_executor(
177
+ artifact_mapping.function_code, artifact_arguments
178
+ )
179
+ logger.info(
180
+ f"{log_string_mapping} Executing code for artifact mapping."
181
+ )
182
+ if result["success"]:
183
+ artifact_result = result["result"]
184
+ else:
185
+ logger.error(
186
+ f"{log_string_mapping} Code execution failed with error: {result['error']}"
187
+ )
188
+ continue
189
+
190
+ # An artifact result can be either an Artifact or a list of elements which can be Artifacts or ArtifactModels (from children)
191
+ if not isinstance(artifact_result, List):
192
+ artifact_result = [artifact_result]
193
+
194
+ for artifact in artifact_result:
195
+ if artifact is None:
196
+ logger.warning(
197
+ f"{log_string_mapping} Artifact is None, skipping."
198
+ )
199
+ continue
200
+ if isinstance(artifact, TableArtifactModel):
201
+ artifact.parent_id = node_registry.id
202
+ saved_artifact = await context.db.save(artifact)
203
+ logger.debug(
204
+ f"{log_string_mapping} new table: {saved_artifact}"
205
+ )
206
+ elif isinstance(artifact, ChartArtifactModel):
207
+ artifact.parent_id = node_registry.id
208
+ saved_artifact = await context.db.save(artifact)
209
+ logger.debug(
210
+ f"{log_string_mapping} new table: {saved_artifact}"
211
+ )
212
+ elif isinstance(artifact, ArtifactModel):
213
+ artifact.path = call_path
214
+ saved_artifact = await context.db.save(artifact)
215
+ logger.debug(f"{log_string_mapping} new: {saved_artifact}")
216
+ artifact_list.append(saved_artifact)
217
+ else:
218
+ raise ValueError(
219
+ f"{log_string_mapping} not an ArtifactModel object. Got {artifact} instead."
220
+ )
221
+ else:
222
+ artifact_list = child_artifacts
223
+ logger.debug(f"{log_string} passing child artifacts")
224
+ return [artifact.id for artifact in artifact_list]
225
+ except Exception as e:
226
+ logger.exception(f"Error creating artifacts for node {node_registry.name}: {e}")
227
+ return []
228
+
229
+
230
+ async def save_artifact_model(artifact: ArtifactModel) -> ArtifactModel:
231
+ """
232
+ Custom save function for polymorphic models
233
+
234
+ If the item is a List type, it will also save any unsaved nested items.
235
+ """
236
+ # Special handling for List type
237
+ if artifact.type == "list":
238
+ # Save all nested items first
239
+ saved_items = []
240
+ for nested_item in artifact.items:
241
+ # Save the nested item
242
+ saved_item = await save_artifact_model(nested_item)
243
+ saved_items.append(saved_item)
244
+
245
+ # Update the items list with all saved items
246
+ artifact.items = saved_items
247
+
248
+ # Get the model's collection
249
+ collection = context.db.collection(ArtifactModel)
250
+
251
+ # Convert model to dict
252
+ item_dict = artifact.model_dump(by_alias=True)
253
+
254
+ # For List types, we need to convert ArtifactModel objects to their IDs for storage
255
+ if artifact.type == "list":
256
+ # Replace ArtifactModel objects with their IDs in the dict for storage
257
+ item_dict["items"] = [nested_item.id for nested_item in artifact.items]
258
+
259
+ # Check if this artifact already exists in the database
260
+ if artifact.id is not None:
261
+ existing = await collection.find_one({"_id": artifact.id})
262
+ if existing:
263
+ # ArtifactModel exists, update it
264
+ await collection.replace_one({"_id": artifact.id}, item_dict)
265
+ return artifact
266
+
267
+ # ArtifactModel doesn't exist or has no ID, insert it
268
+ # Remove id field if it exists to let MongoDB generate it
269
+ if "_id" in item_dict:
270
+ del item_dict["_id"]
271
+
272
+ result = await collection.insert_one(item_dict)
273
+ artifact.id = result.inserted_id
274
+
275
+ return artifact
276
+
277
+
278
+ async def find_artifacts(
279
+ model_class: type[ArtifactModel], **kwargs: Any
280
+ ) -> List[ArtifactModel]:
281
+ """
282
+ Custom find function for polymorphic models
283
+ """
284
+ # Get the collection
285
+ collection = context.db.collection(ArtifactModel)
286
+
287
+ # Add item_type filter for subclasses
288
+ if model_class != ArtifactModel:
289
+ discriminator_value = model_class.model_fields["artifact_type"].default
290
+ kwargs["artifact_type"] = discriminator_value
291
+
292
+ # Execute find
293
+ cursor = collection.find(kwargs)
294
+ results = await cursor.to_list(length=None)
295
+
296
+ # Convert results to model instances
297
+ items = []
298
+ for doc in results:
299
+ artifact_type = doc.get("artifact_type")
300
+
301
+ # For List types, we need special handling
302
+ if artifact_type == "list":
303
+ # Store item_ids temporarily
304
+ item_ids = doc.get("items", [])
305
+ # Remove items field for validation
306
+ doc_copy = doc.copy()
307
+ doc_copy["items"] = []
308
+
309
+ # Create the List instance without items first
310
+ item = model_class.model_validate(doc_copy)
311
+
312
+ # Load all referenced items
313
+ loaded_items = []
314
+ for item_id in item_ids:
315
+ nested_item = await context.db.find_one(
316
+ ArtifactModel, ArtifactModel.id == item_id
317
+ )
318
+ if nested_item:
319
+ loaded_items.append(nested_item)
320
+
321
+ # Now assign the loaded items
322
+ item.items = loaded_items
323
+ else:
324
+ # For non-List types, normal validation is fine
325
+ item = model_class.model_validate(doc)
326
+
327
+ items.append(item)
328
+
329
+ return items
330
+
331
+
332
+ # async def find_one_artifact(artifact_id: ObjectId) -> Optional[ArtifactModel]:
333
+ # """
334
+ # Find an artifact by ID and return it as the appropriate subclass instance
335
+ # based on its artifact_type field.
336
+ #
337
+ # Args:
338
+ # artifact_id: The ObjectId of the item to find
339
+ #
340
+ # Returns:
341
+ # An instance of the appropriate ArtifactModel subclass, or None if not found
342
+ # """
343
+ # # Find the document by ID
344
+ # doc = await collection.find_one({"_id": artifact_id})
345
+ #
346
+ # if doc is None:
347
+ # return None
348
+ #
349
+ # # Determine the appropriate class based on artifact_type
350
+ # artifact_type = doc.get("artifact_type")
351
+ #
352
+ # # Map artifact_type values to their respective classes
353
+ # type_to_class = {
354
+ # "int": IntArtifactModel,
355
+ # "float": FloatArtifactModel,
356
+ # "str": StringArtifactModel,
357
+ # "list": List,
358
+ # # Add more mappings as you add more subclasses
359
+ # }
360
+ #
361
+ # # Get the appropriate class, defaulting to base ArtifactModel if the type is unknown
362
+ # model_class = type_to_class.get(artifact_type, ArtifactModel)
363
+ #
364
+ # # For List type, we need special handling to load items
365
+ # if artifact_type == "list":
366
+ # # Store item_ids temporarily
367
+ # item_ids = doc.get("items", [])
368
+ # # Remove items field for now to allow validation
369
+ # doc["items"] = []
370
+ #
371
+ # # Create the List instance without items first
372
+ # item = model_class.model_validate(doc)
373
+ #
374
+ # # load all referenced items
375
+ # loaded_items = []
376
+ # for artifact_id in item_ids:
377
+ # nested_item = await context.db.find_one(ArtifactModel, ArtifactModel.id == artifact_id)
378
+ # if nested_item:
379
+ # loaded_items.append(nested_item)
380
+ #
381
+ # # Now assign the loaded items
382
+ # item.items = loaded_items
383
+ # else:
384
+ # # For non-List types, normal validation is fine
385
+ # item = model_class.model_validate(doc)
386
+ #
387
+ #
388
+ # return item
389
+
390
+ #
391
+ # async def load_list_items(list_item: List) -> List[ArtifactModel]:
392
+ # """
393
+ # Load all items in a List type and return them as a Python list.
394
+ # This is now a simple accessor since items are already ArtifactModel objects.
395
+ #
396
+ # Args:
397
+ # list_item: A List instance
398
+ #
399
+ # Returns:
400
+ # A list of ArtifactModel instances
401
+ # """
402
+ # if not isinstance(list_item, List):
403
+ # raise TypeError("Expected a List instance")
404
+ #
405
+ # return list_item.items
406
+ #
@@ -0,0 +1,14 @@
1
+ import asyncio
2
+ import functools
3
+
4
+ import nest_asyncio
5
+
6
+ nest_asyncio.apply()
7
+
8
+
9
+ def async_helper(func):
10
+ @functools.wraps(func)
11
+ def wrapper(*args, **kwargs):
12
+ return asyncio.run(func(*args, **kwargs))
13
+
14
+ return wrapper
@@ -0,0 +1,60 @@
1
+ from pathlib import Path
2
+ from typing import Optional
3
+
4
+
5
+ class SimstackConfig:
6
+ """
7
+ Singleton class that manages the path to a configuration file.
8
+
9
+ This class ensures only one instance exists throughout the application
10
+ and provides a centralized way to access the configuration file path.
11
+ """
12
+
13
+ _instance: Optional["SimstackConfig"] = None
14
+ _config_file_path: Optional[str] = "simstack.toml" # Default config file name
15
+
16
+ def __new__(cls) -> "SimstackConfig":
17
+ """Create or return the singleton instance."""
18
+ if cls._instance is None:
19
+ cls._instance = super(SimstackConfig, cls).__new__(cls)
20
+ return cls._instance
21
+
22
+ def __init__(self):
23
+ """Initialize the ConfigManager (only runs once due to singleton pattern)."""
24
+ # Only initialize once
25
+ if not hasattr(self, "_initialized"):
26
+ self._initialized = True
27
+
28
+ @property
29
+ def config_file_path(self) -> Optional[str]:
30
+ """Get the current configuration file path."""
31
+ return self._config_file_path
32
+
33
+ @config_file_path.setter
34
+ def config_file_path(self, path: str) -> None:
35
+ """
36
+ Set the configuration file path.
37
+
38
+ Args:
39
+ path: Path to the configuration file
40
+
41
+ Raises:
42
+ ValueError: If the path is empty or None
43
+ FileNotFoundError: If the file doesn't exist (optional validation)
44
+ """
45
+ if not path:
46
+ raise ValueError("Configuration file path cannot be empty or None")
47
+
48
+ # Convert to absolute path for consistency
49
+ self._config_file_path = str(Path(path).resolve())
50
+
51
+
52
+ # Convenience function to get the singleton instance
53
+ def get_config_file() -> SimstackConfig:
54
+ """
55
+ Get the singleton ConfigManager instance.
56
+
57
+ Returns:
58
+ The ConfigManager singleton instance
59
+ """
60
+ return SimstackConfig()