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
@@ -0,0 +1,13 @@
1
+ from typing import List, Optional
2
+
3
+ from odmantic import Model, Field, ObjectId
4
+
5
+
6
+ class Project(Model):
7
+ field_name: str = Field(unique=True)
8
+ description: Optional[str] = None
9
+ tag_ids: List[ObjectId] = Field(default_factory=list)
10
+
11
+ model_config = {
12
+ "collection": "projects",
13
+ }
@@ -0,0 +1,170 @@
1
+ import re
2
+ from typing import Optional, ClassVar, Dict, Any
3
+
4
+ from odmantic import Field, Model, EmbeddedModel
5
+ from pydantic import field_validator, model_validator
6
+
7
+
8
+ class SlurmParametersPatch(EmbeddedModel):
9
+ nodes: Optional[int] = Field(default=None, ge=1)
10
+ tasks: Optional[int] = Field(default=None, ge=1)
11
+ tasks_per_node: Optional[int] = Field(default=None, ge=1)
12
+ cpus_per_task: Optional[int] = Field(default=None, ge=1)
13
+ mem: Optional[str] = None
14
+ mem_per_cpu: Optional[str] = None
15
+ time: Optional[str] = None
16
+ begin: Optional[str] = None
17
+ partition: Optional[str] = None
18
+ qos: Optional[str] = None
19
+ job_name: Optional[str] = None
20
+ output: Optional[str] = None
21
+ error: Optional[str] = None
22
+ mail_type: Optional[str] = None
23
+ mail_user: Optional[str] = None
24
+ gres: Optional[str] = None
25
+ account: Optional[str] = None
26
+ priority: Optional[int] = None
27
+ reservation: Optional[str] = None
28
+ constraint: Optional[str] = None
29
+ exclusive: Optional[bool] = None
30
+ nice: Optional[int] = None
31
+ dependency: Optional[str] = None
32
+ array: Optional[str] = None
33
+ startup_commands: Optional[list[str]] = None
34
+ chdir: Optional[str] = None
35
+ export: Optional[str] = None
36
+ signal: Optional[str] = None
37
+ requeue: Optional[bool] = None
38
+ no_requeue: Optional[bool] = None
39
+
40
+ model_config: ClassVar[Dict[str, Any]] = {
41
+ "extra": "forbid",
42
+ }
43
+
44
+
45
+ class ResourceAssignmentRule(Model):
46
+ name: str = Field(unique=True)
47
+ regex_pattern: str
48
+ priority: int = Field(default=0)
49
+ enabled: bool = Field(default=True)
50
+ resource_str: Optional[str] = None
51
+ queue: Optional[str] = None
52
+ slurm_parameters_patch: Dict[str, Any] = Field(default_factory=dict)
53
+ description: Optional[str] = ""
54
+
55
+ model_config = {"collection": "resource_assignment_rule"}
56
+
57
+ @field_validator("name", "regex_pattern", mode="before")
58
+ @classmethod
59
+ def _strip_required_strings(cls, value):
60
+ if value is None:
61
+ return value
62
+ return str(value).strip()
63
+
64
+ @field_validator("resource_str", "queue", "description", mode="before")
65
+ @classmethod
66
+ def _strip_optional_strings(cls, value):
67
+ if value is None:
68
+ return None
69
+ normalized = str(value).strip()
70
+ return normalized or None
71
+
72
+ @field_validator("regex_pattern", mode="after")
73
+ @classmethod
74
+ def _validate_regex_pattern(cls, value: str) -> str:
75
+ if not value:
76
+ raise ValueError("Path pattern must not be empty")
77
+ try:
78
+ re.compile(cls.pattern_to_regex(value))
79
+ except ValueError:
80
+ raise
81
+ except re.error as exc:
82
+ raise ValueError(f"Invalid path pattern: {exc}") from exc
83
+ return value
84
+
85
+ @model_validator(mode="after")
86
+ def _validate_has_effect(self):
87
+ has_slurm_patch = bool(self.slurm_parameters_patch)
88
+ if not any([self.resource_str, self.queue, has_slurm_patch]):
89
+ raise ValueError(
90
+ "ResourceAssignmentRule must set at least one of resource_str, queue, or slurm_parameters_patch"
91
+ )
92
+ return self
93
+
94
+ @staticmethod
95
+ def normalize_pattern(pattern: str) -> str:
96
+ normalized = (pattern or "").strip()
97
+ if normalized.startswith("."):
98
+ without_leading_dots = normalized.lstrip(".")
99
+ if without_leading_dots and "." not in without_leading_dots:
100
+ return f"*.{without_leading_dots}"
101
+ return without_leading_dots
102
+ return normalized
103
+
104
+ @classmethod
105
+ def _pattern_segments(cls, pattern: str) -> list[str]:
106
+ return [
107
+ segment for segment in cls.normalize_pattern(pattern).split(".") if segment
108
+ ]
109
+
110
+ @staticmethod
111
+ def _segment_to_regex(segment: str) -> str:
112
+ return "".join("[^.]*" if char == "*" else re.escape(char) for char in segment)
113
+
114
+ @classmethod
115
+ def pattern_to_regex(cls, pattern: str) -> str:
116
+ segments = cls._pattern_segments(pattern)
117
+ if not segments:
118
+ raise ValueError("Path pattern must not be empty")
119
+ if segments == ["*"]:
120
+ return r"[^.]+(?:\.[^.]+)*"
121
+
122
+ regex_parts: list[str] = []
123
+ for index, segment in enumerate(segments):
124
+ if segment == "*":
125
+ regex_parts.append(r"(?:[^.]+\.)*" if index == 0 else r"(?:\.[^.]+)*")
126
+ continue
127
+
128
+ segment_regex = cls._segment_to_regex(segment)
129
+ previous_is_leading_wildcard = index == 1 and segments[0] == "*"
130
+ if index == 0 or previous_is_leading_wildcard:
131
+ regex_parts.append(segment_regex)
132
+ else:
133
+ regex_parts.append(r"\." + segment_regex)
134
+
135
+ return "".join(regex_parts)
136
+
137
+ @classmethod
138
+ def pattern_specificity_score(cls, pattern: str) -> int:
139
+ segments = cls._pattern_segments(pattern)
140
+ literal_segment_count = sum(1 for segment in segments if segment != "*")
141
+ literal_char_count = sum(len(segment.replace("*", "")) for segment in segments)
142
+ wildcard_count = sum(segment.count("*") for segment in segments)
143
+ return (
144
+ literal_segment_count * 10000
145
+ + literal_char_count * 100
146
+ + len(segments)
147
+ - wildcard_count
148
+ )
149
+
150
+ @classmethod
151
+ def matches_call_path(cls, pattern: str, normalized_call_path: str) -> bool:
152
+ return (
153
+ re.fullmatch(cls.pattern_to_regex(pattern), normalized_call_path)
154
+ is not None
155
+ )
156
+
157
+ @field_validator("slurm_parameters_patch", mode="before")
158
+ @classmethod
159
+ def _normalize_slurm_patch(cls, value):
160
+ if value is None:
161
+ return {}
162
+ if isinstance(value, SlurmParametersPatch):
163
+ return value.model_dump(exclude_none=True)
164
+ if isinstance(value, dict):
165
+ return SlurmParametersPatch.model_validate(value).model_dump(
166
+ exclude_none=True
167
+ )
168
+ raise ValueError(
169
+ "slurm_parameters_patch must be a dictionary or SlurmParametersPatch"
170
+ )
@@ -0,0 +1,125 @@
1
+ from typing import Optional, List
2
+ import urllib.parse
3
+ import socket
4
+ import re
5
+ from pathlib import Path
6
+ from odmantic import EmbeddedModel, Field, Model
7
+ from pydantic import field_validator, model_serializer
8
+
9
+ from simstack.util.transform_file_name import transform_file_name
10
+ class GitRepo(Model):
11
+ """
12
+ Represents a Git repository with relevant attributes such as its URL, branch,
13
+ and whether it is a submodule. Ensures that the URL provided is valid.
14
+
15
+ This class is used to model information about a Git repository, including
16
+ its URL, the branch being used, and whether it is included as a submodule
17
+ within another repository. It provides validation for the URL to ensure that
18
+ it is in the correct format.
19
+
20
+ In the user database there is a list of Git repositories for the user
21
+
22
+ :ivar url: The URL of the Git repository.
23
+ :type url: str
24
+ :ivar branch: The branch of the Git repository. Optional.
25
+ :type branch: Optional[str]
26
+ :ivar is_submodule: Indicates whether the repository is a submodule. Defaults to False.
27
+ :type is_submodule: bool
28
+ """
29
+ url: str
30
+ branch: Optional[str]
31
+ is_submodule: bool = Field(default=False)
32
+
33
+ @field_validator("url", mode="after")
34
+ @classmethod
35
+ def validate_url(cls, v):
36
+ try:
37
+ result = urllib.parse.urlparse(v)
38
+ if not all([result.scheme, result.netloc]):
39
+ raise ValueError("Invalid URL format")
40
+ except Exception:
41
+ raise ValueError("Invalid URL format")
42
+ return v
43
+
44
+ class ResourceDefinition(Model):
45
+ resource_str: str = Field(unique=True)
46
+ workdir: str # Change Path to str
47
+ hostname: str
48
+ python_paths: List[str] = Field(default_factory=list) # Change List[Path] to List[str]
49
+ environment_start: Optional[str] = None
50
+ ssh_key: Optional[str] = None # Change Optional[Path] to Optional[str]
51
+ routes: Optional[List[str]] = []
52
+ queue: str = "default"
53
+ is_default: bool = False
54
+ git_branch: str = "main"
55
+
56
+ @staticmethod
57
+ def _convert_backslashes(path_str: str) -> str:
58
+ return re.sub(r'\\+', '/', path_str)
59
+
60
+ @field_validator("workdir", mode="before")
61
+ @classmethod
62
+ def convert_workdir(cls, v):
63
+ if isinstance(v, (Path, str)):
64
+ return str(cls._convert_backslashes(str(v)))
65
+ return v
66
+
67
+ @field_validator("python_paths", mode="before")
68
+ @classmethod
69
+ def convert_python_paths(cls, v):
70
+ if isinstance(v, list):
71
+ return [str(cls._convert_backslashes(str(p))) for p in v]
72
+ return v
73
+
74
+ @field_validator("ssh_key", mode="before")
75
+ @classmethod
76
+ def convert_ssh_key(cls, v):
77
+ if v is None:
78
+ return None
79
+ return str(cls._convert_backslashes(str(v)))
80
+
81
+ @field_validator("queue", mode="before")
82
+ @classmethod
83
+ def normalize_queue(cls, v):
84
+ if v is None:
85
+ return "default"
86
+ normalized = str(v).strip()
87
+ return normalized or "default"
88
+
89
+
90
+ def validate_hostname(self):
91
+ current_hostname = socket.gethostname()
92
+ if self.hostname != current_hostname:
93
+ raise ValueError(f"Hostname must match current host. Expected: {current_hostname}, got: {self.hostname}")
94
+
95
+ def validate_ssh_key(self):
96
+ if self.ssh_key is not None:
97
+ file_path = transform_file_name(Path(self.ssh_key)) # Convert to Path for utility
98
+ if not file_path:
99
+ raise ValueError(f"SSH key path does not exist: {self.ssh_key}")
100
+
101
+ def get_ssh_key_path(self):
102
+ if self.ssh_key is not None:
103
+ return transform_file_name(Path(self.ssh_key))
104
+ return None
105
+
106
+ def validate_python_path(self):
107
+ for path_str in self.python_paths:
108
+ path = Path(path_str)
109
+ real_path = transform_file_name(path)
110
+ if not path.exists():
111
+ raise ValueError(f"Python path does not exist: {path}")
112
+ if not path.is_dir():
113
+ raise ValueError(f"Python path is not a directory: {path}")
114
+
115
+ def get_python_path(self):
116
+ if self.python_paths:
117
+ return [transform_file_name(Path(p)) for p in self.python_paths]
118
+ return None
119
+
120
+ def __repr__(self):
121
+ return f"ResourceDefinition(name={self.resource_str})"
122
+
123
+ @classmethod
124
+ def from_resource_definition(cls, resource_definition: dict):
125
+ return cls(**resource_definition)
@@ -0,0 +1,39 @@
1
+ from datetime import datetime
2
+ from enum import Enum
3
+ from typing import Optional, List
4
+
5
+ from odmantic import Model, ObjectId, Field
6
+ from pydantic import ConfigDict
7
+
8
+ from simstack.models.parameters import Resource
9
+
10
+
11
+ class RunnerEventEnum(str, Enum):
12
+ SHUTDOWN = "shutdown"
13
+ RUNNER_STARTED = "runner_started"
14
+ NODE_STARTED = "node_started"
15
+ NODE_SUBMIT = "node_submit"
16
+ ALIVE = "alive"
17
+ RESTART = "restart"
18
+ CRONTAB_OK = "crontab_ok"
19
+ CRONTAB_GONE = "crontab_gone"
20
+
21
+
22
+ class RunnerType(str, Enum):
23
+ NODE_RUNNER = "node_runner"
24
+ RESOURCE_RUNNER = "resource_runner"
25
+
26
+
27
+ class RunnerEvent(Model):
28
+ model_config = ConfigDict(arbitrary_types_allowed=True)
29
+
30
+ timestamp: datetime = Field(default_factory=datetime.now)
31
+ event: RunnerEventEnum
32
+ resource: Resource
33
+ runner_type: RunnerType
34
+ hostname: Optional[str] = None
35
+ user: Optional[str] = None
36
+ pid: Optional[int] = None
37
+ node_id: Optional[ObjectId] = None
38
+ message: Optional[str] = None
39
+ git_status: List[str] = Field(default_factory=list)
@@ -0,0 +1,79 @@
1
+ from enum import Enum
2
+ from typing import Any, Dict, List
3
+
4
+ from odmantic import Model, Field
5
+ from pydantic import field_validator
6
+
7
+ from simstack.models import simstack_model
8
+
9
+
10
+ class SimpleTableColumnType(str, Enum):
11
+ STRING = "string"
12
+ NUMBER = "number"
13
+
14
+ @classmethod
15
+ def from_value(
16
+ cls, value: "SimpleTableColumnType | str"
17
+ ) -> "SimpleTableColumnType":
18
+ if isinstance(value, cls):
19
+ return value
20
+ if not isinstance(value, str):
21
+ raise ValueError(f"Invalid SimpleTable column type: {value!r}")
22
+
23
+ normalized = value.strip()
24
+ try:
25
+ return cls(normalized)
26
+ except ValueError:
27
+ pass
28
+
29
+ try:
30
+ return SIMPLE_TABLE_COLUMN_TYPE_LEGACY_ALIASES[normalized.lower()]
31
+ except KeyError as exc:
32
+ raise ValueError(f"Invalid SimpleTable column type: {value!r}") from exc
33
+
34
+
35
+ SIMPLE_TABLE_COLUMN_TYPE_LEGACY_ALIASES = {
36
+ # Existing producers and stored DB documents used these variants before
37
+ # SimpleTable column types were narrowed to logical data types.
38
+ "str": SimpleTableColumnType.STRING,
39
+ "int": SimpleTableColumnType.NUMBER,
40
+ "float": SimpleTableColumnType.NUMBER,
41
+ }
42
+
43
+
44
+ @simstack_model
45
+ class SimpleTable(Model):
46
+ """
47
+ A simple table model to display tabular data using ag-grid
48
+ """
49
+
50
+ name: str = Field(default="SimpleTable")
51
+ heading: List[str] = Field(default_factory=list)
52
+ row: List[Dict[str, Any]] = Field(default_factory=list)
53
+ type: List[SimpleTableColumnType] = Field(default_factory=list)
54
+
55
+ @field_validator("type", mode="before")
56
+ @classmethod
57
+ def normalize_column_types(cls, value: Any) -> Any:
58
+ if value is None:
59
+ return value
60
+ if isinstance(value, list):
61
+ return [SimpleTableColumnType.from_value(item) for item in value]
62
+ return value
63
+
64
+ def add_column(
65
+ self, column_name: str, column_type: SimpleTableColumnType | str
66
+ ) -> None:
67
+ if column_name not in self.heading:
68
+ self.heading.append(column_name)
69
+ self.type.append(SimpleTableColumnType.from_value(column_type))
70
+
71
+ def add_row(self, row: Dict[str, Any]) -> None:
72
+ self.row.append(row)
73
+
74
+ @classmethod
75
+ def ui_schema(cls) -> Dict[str, str]:
76
+ ui_schema = {
77
+ "ui:field": "SimpleTableField",
78
+ }
79
+ return ui_schema
@@ -0,0 +1,97 @@
1
+ from functools import wraps
2
+ from typing import TypeVar, Type, Any, get_type_hints, overload
3
+
4
+ from simstack.util.cleaned_json_schema import cleaned_json_schema
5
+ from simstack.util.custom_model_dump import custom_model_dump
6
+ from simstack.util.default_from_dict import default_from_dict, default_from_model
7
+ from simstack.util.generate_ui_schema import generate_ui_schema
8
+ from simstack.util.ui_tools import ui_make_title
9
+
10
+ T = TypeVar("T")
11
+
12
+
13
+ @overload
14
+ def simstack_model(cls: Type[T]) -> Type[T]:
15
+ ...
16
+
17
+
18
+ def simstack_model(cls: T) -> T:
19
+ """
20
+ Decorates a given class to equip it with default implementations of utility
21
+ methods for handling operations such as dictionary conversion, schema
22
+ generation, and UI schema generation.
23
+ """
24
+
25
+ # Function to create a properly typed wrapper that preserves docstrings
26
+ def create_typed_wrapper(func, first_param_name="this_class"):
27
+ # Get original type hints
28
+ original_hints = get_type_hints(func)
29
+
30
+ # Create a wrapper with the correct parameters
31
+ @wraps(func) # This preserves metadata like docstrings
32
+ def wrapper(*args, **kwargs):
33
+ return func(*args, **kwargs)
34
+
35
+ # Add explicit docstring if not preserved by wraps
36
+ if not wrapper.__doc__ and func.__doc__:
37
+ wrapper.__doc__ = func.__doc__
38
+
39
+ # Copy the original function's annotations
40
+ wrapper.__annotations__ = {
41
+ first_param_name: Type[Any], # the first param is now the class
42
+ **{
43
+ k: v
44
+ for k, v in original_hints.items()
45
+ if k != "return" and k != first_param_name
46
+ },
47
+ }
48
+
49
+ # Preserve the return annotation if it exists
50
+ if "return" in original_hints:
51
+ wrapper.__annotations__["return"] = original_hints["return"]
52
+
53
+ return wrapper
54
+
55
+ # Create typed wrappers for all functions with explicit docstrings
56
+ default_class_methods = {
57
+ "json_schema": create_typed_wrapper(cleaned_json_schema),
58
+ "ui_schema": create_typed_wrapper(generate_ui_schema),
59
+ "ui_make_title": create_typed_wrapper(ui_make_title),
60
+ "from_dict": create_typed_wrapper(default_from_dict),
61
+ "from_model": create_typed_wrapper(default_from_model),
62
+ #'make_column_defs': create_typed_wrapper(make_column_defs_helper),
63
+ }
64
+
65
+ # Add methods only if they don't exist
66
+ for method_name, default_implementation in default_class_methods.items():
67
+ if not hasattr(cls, method_name):
68
+ setattr(cls, method_name, classmethod(default_implementation))
69
+
70
+ default_methods = {
71
+ "custom_model_dump": custom_model_dump,
72
+ #'make_table_entries': make_table_entries_helper
73
+ }
74
+
75
+ # Add methods only if they don't exist
76
+ for method_name, default_implementation in default_methods.items():
77
+ if not hasattr(cls, method_name):
78
+ setattr(cls, method_name, default_implementation)
79
+
80
+ # Add a marker attribute to identify decorated classes
81
+ setattr(cls, "_is_simstack_model", True)
82
+
83
+ # Return the original class without casting - the overload handles the typing
84
+ return cls
85
+
86
+
87
+ def is_simstack_model(cls: Type) -> bool:
88
+ """
89
+ Check if a class has been decorated with @simstack_model.
90
+
91
+ Args:
92
+ cls: The class to check
93
+
94
+ Returns:
95
+ bool: True if the class was decorated with @simstack_model, False otherwise
96
+ """
97
+ return getattr(cls, "_is_simstack_model", False)
@@ -0,0 +1,17 @@
1
+ import datetime
2
+
3
+ from odmantic import Model, ObjectId
4
+
5
+ from simstack.models.parameters import Resource
6
+
7
+
8
+ class SlurmInfo(Model):
9
+ node_registry: ObjectId
10
+ updated: datetime.datetime
11
+ resource: Resource
12
+ job_id: str
13
+ name: str
14
+ user: str
15
+ code: str
16
+ time: str
17
+ nodes: list[str]
@@ -0,0 +1,87 @@
1
+ from typing import List, Optional, Dict, Any
2
+
3
+ from odmantic import EmbeddedModel, Field, Model, ObjectId
4
+
5
+
6
+ class AGGridColumnDef(EmbeddedModel):
7
+ """AG-Grid column definition with support for nested tables."""
8
+
9
+ # Core properties
10
+ field: str = Field(..., description="The field name in the row data to bind to")
11
+ headerName: str = Field(..., description="Display name for the column header")
12
+
13
+ # Sizing properties
14
+ width: Optional[int] = Field(default=None, description="Column width in pixels")
15
+ minWidth: Optional[int] = Field(
16
+ default=None, description="Minimum column width in pixels"
17
+ )
18
+ maxWidth: Optional[int] = Field(
19
+ default=None, description="Maximum column width in pixels"
20
+ )
21
+ flex: Optional[int] = Field(
22
+ default=None, description="Flex sizing for responsive columns"
23
+ )
24
+
25
+ # Display and interaction properties
26
+ hide: Optional[bool] = Field(default=None, description="Whether to hide the column")
27
+ # pinned: Optional[Literal["left", "right"]] = Field(default=None, description="Pin column to left or right")
28
+ sortable: Optional[bool] = Field(
29
+ default=None, description="Whether the column can be sorted"
30
+ )
31
+ resizable: Optional[bool] = Field(
32
+ default=None, description="Whether the column can be resized"
33
+ )
34
+ editable: Optional[bool] = Field(
35
+ default=None, description="Whether cells in this column are editable"
36
+ )
37
+
38
+ # # Filtering and rendering
39
+ # filter: Optional[Union[bool, str]] = Field(default=None, description="Filter type")
40
+ # cellRenderer: Optional[str] = Field(default=None, description="Custom cell renderer component")
41
+ # cellRendererParams: Optional[Dict[str, Any]] = Field(default=None, description="Parameters for cell renderer")
42
+
43
+ # # Master-Detail specific properties for nested tables
44
+ # cellRendererSelector: Optional[Dict[str, Any]] = Field(default=None, description="Function to select cell renderer based on data")
45
+ #
46
+ # # Nested table configuration
47
+ # is_nested_table: Optional[bool] = Field(default=False, description="Whether this column contains nested table data")
48
+ # nested_table_config: Optional[Dict[str, Any]] = Field(default=None, description="Configuration for nested table rendering")
49
+ #
50
+ # # Row grouping and detail rows
51
+ # rowGroup: Optional[bool] = Field(default=None, description="Whether this column is used for row grouping")
52
+ # showRowGroup: Optional[Union[bool, str]] = Field(default=None, description="Show row group column")
53
+ #
54
+ # # Additional properties
55
+ # custom_properties: Optional[Dict[str, Any]] = Field(default_factory=dict, description="Additional custom properties")
56
+
57
+
58
+ class TableArtifactModel(Model):
59
+ parent_id: ObjectId = Field(default=None, description="ID of the node registry")
60
+ columns_defs: List[AGGridColumnDef] = Field(
61
+ default_factory=list, description="AG-Grid column definitions"
62
+ )
63
+ row_data: List[Dict[str, Any]] = Field(
64
+ default_factory=list, description="List of row objects"
65
+ )
66
+
67
+ # Master-Detail configuration
68
+ master_detail: Optional[bool] = Field(
69
+ default=False, description="Enable master-detail rows"
70
+ )
71
+ detail_cell_renderer: Optional[str] = Field(
72
+ default=None, description="Detail panel cell renderer"
73
+ )
74
+ detail_cell_renderer_params: Optional[Dict[str, Any]] = Field(
75
+ default=None, description="Parameters for detail renderer"
76
+ )
77
+ # TODO implement nested tables and rendering
78
+ # # Nested tables storage - simplified to avoid recursion
79
+ # nested_tables: Optional[Dict[str, str]] = Field(default_factory=dict, description="Nested table IDs by reference key")
80
+ #
81
+ # # Tree data configuration
82
+ # tree_data: Optional[bool] = Field(default=False, description="Enable tree data structure")
83
+ # get_data_path: Optional[str] = Field(default=None, description="Function to get data path for tree structure")
84
+ #
85
+ # # Row grouping
86
+ # auto_group_column_def: Optional[AGGridColumnDef] = Field(default=None, description="Auto group column definition")
87
+ # group_default_expanded: Optional[int] = Field(default=None, description="Default expansion level for groups")
simstack/models/tag.py ADDED
@@ -0,0 +1,12 @@
1
+ from typing import Optional
2
+
3
+ from odmantic import Field, Model
4
+
5
+
6
+ class Tag(Model):
7
+ name: str = Field(unique=True)
8
+ description: Optional[str] = None
9
+
10
+ model_config = {
11
+ "collection": "tags",
12
+ }
@@ -0,0 +1,5 @@
1
+
2
+
3
+ if __name__ == "__main__":
4
+ print("hi")
5
+
@@ -0,0 +1 @@
1
+ # this file makes sure that find_root keeps searching
@@ -0,0 +1,4 @@
1
+ # Sphinx build info version 1
2
+ # This file records the configuration used when building these files. When it is not found, a full rebuild will be done.
3
+ config: a5fbdea24be32225dfc70ca293aee737
4
+ tags: 645f666f9bcd5a90fca523b33c5a78b7