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,690 @@
1
+ from typing import List, Union, Literal, Optional, Dict, Any
2
+
3
+ from odmantic import EmbeddedModel, Field, Model, ObjectId
4
+
5
+ from simstack.models import simstack_model
6
+
7
+
8
+ # Chart Series Definitions
9
+ class AGChartSeriesBase(EmbeddedModel):
10
+ """Base class for AG-Charts series configuration."""
11
+
12
+ type: str = Field(..., description="Chart series type")
13
+ xKey: str = Field(..., description="Key for x-axis data")
14
+ yKey: str = Field(..., description="Key for y-axis data")
15
+ visible: Optional[bool] = Field(
16
+ default=True, description="Whether series is visible"
17
+ )
18
+ showInLegend: Optional[bool] = Field(default=True, description="Show in legend")
19
+ title: Optional[str] = Field(default=None, description="Series title")
20
+ # Chart data
21
+ data: List[Dict[str, Any]] = Field(default_factory=list, description="Chart data")
22
+
23
+
24
+ class AGLineSeriesConfig(AGChartSeriesBase):
25
+ """AG-Charts line series configuration."""
26
+
27
+ type: Literal["line"] = "line"
28
+ stroke: Optional[str] = Field(default=None, description="Line stroke color")
29
+ strokeWidth: Optional[float] = Field(default=2, description="Line stroke width")
30
+ strokeOpacity: Optional[float] = Field(default=1, description="Line stroke opacity")
31
+ lineDash: Optional[List[float]] = Field(
32
+ default=None, description="Line dash pattern"
33
+ )
34
+ marker: Optional[Dict[str, Any]] = Field(
35
+ default=None, description="Marker configuration"
36
+ )
37
+ tooltip: Optional[Dict[str, Any]] = Field(
38
+ default=None, description="Tooltip configuration"
39
+ )
40
+
41
+
42
+ class AGBarSeriesConfig(AGChartSeriesBase):
43
+ """AG-Charts bar series configuration."""
44
+
45
+ type: Literal["bar"] = "bar"
46
+ fill: Optional[str] = Field(default=None, description="Bar fill color")
47
+ fillOpacity: Optional[float] = Field(default=1, description="Bar fill opacity")
48
+ stroke: Optional[str] = Field(default=None, description="Bar stroke color")
49
+ strokeWidth: Optional[float] = Field(default=0, description="Bar stroke width")
50
+ cornerRadius: Optional[float] = Field(default=0, description="Bar corner radius")
51
+ tooltip: Optional[Dict[str, Any]] = Field(
52
+ default=None, description="Tooltip configuration"
53
+ )
54
+
55
+
56
+ class AGRangeBarSeriesConfig(EmbeddedModel):
57
+ """AG-Charts range-bar series configuration."""
58
+
59
+ type: Literal["range-bar"] = "range-bar"
60
+ xKey: str = Field(..., description="Key for x-axis data")
61
+ yLowKey: str = Field(..., description="Key for low range value")
62
+ yHighKey: str = Field(..., description="Key for high range value")
63
+ xName: Optional[str] = Field(default=None, description="X axis display name")
64
+ yName: Optional[str] = Field(default=None, description="Y axis display name")
65
+ yLowName: Optional[str] = Field(default=None, description="Low value display name")
66
+ yHighName: Optional[str] = Field(default=None, description="High value display name")
67
+ direction: Optional[Literal["horizontal", "vertical"]] = Field(
68
+ default=None, description="Bar rendering direction"
69
+ )
70
+ visible: Optional[bool] = Field(
71
+ default=True, description="Whether series is visible"
72
+ )
73
+ showInLegend: Optional[bool] = Field(default=True, description="Show in legend")
74
+ title: Optional[str] = Field(default=None, description="Series title")
75
+ data: List[Dict[str, Any]] = Field(default_factory=list, description="Chart data")
76
+ fill: Optional[str] = Field(default=None, description="Bar fill color")
77
+ fillOpacity: Optional[float] = Field(default=1, description="Bar fill opacity")
78
+ stroke: Optional[str] = Field(default=None, description="Bar stroke color")
79
+ strokeWidth: Optional[float] = Field(default=0, description="Bar stroke width")
80
+ cornerRadius: Optional[float] = Field(default=0, description="Bar corner radius")
81
+ tooltip: Optional[Dict[str, Any]] = Field(
82
+ default=None, description="Tooltip configuration"
83
+ )
84
+
85
+
86
+ class AGColumnSeriesConfig(AGChartSeriesBase):
87
+ """AG-Charts column series configuration."""
88
+
89
+ type: Literal["column"] = "column"
90
+ fill: Optional[str] = Field(default=None, description="Column fill color")
91
+ fillOpacity: Optional[float] = Field(default=1, description="Column fill opacity")
92
+ stroke: Optional[str] = Field(default=None, description="Column stroke color")
93
+ strokeWidth: Optional[float] = Field(default=0, description="Column stroke width")
94
+ cornerRadius: Optional[float] = Field(default=0, description="Column corner radius")
95
+ tooltip: Optional[Dict[str, Any]] = Field(
96
+ default=None, description="Tooltip configuration"
97
+ )
98
+
99
+
100
+ class AGAreaSeriesConfig(AGChartSeriesBase):
101
+ """AG-Charts area series configuration."""
102
+
103
+ type: Literal["area"] = "area"
104
+ fill: Optional[str] = Field(default=None, description="Area fill color")
105
+ fillOpacity: Optional[float] = Field(default=0.8, description="Area fill opacity")
106
+ stroke: Optional[str] = Field(default=None, description="Area stroke color")
107
+ strokeWidth: Optional[float] = Field(default=2, description="Area stroke width")
108
+ marker: Optional[Dict[str, Any]] = Field(
109
+ default=None, description="Marker configuration"
110
+ )
111
+ tooltip: Optional[Dict[str, Any]] = Field(
112
+ default=None, description="Tooltip configuration"
113
+ )
114
+
115
+
116
+ class AGScatterSeriesConfig(AGChartSeriesBase):
117
+ """AG-Charts scatter series configuration."""
118
+
119
+ type: Literal["scatter"] = "scatter"
120
+ fill: Optional[str] = Field(default=None, description="Marker fill color")
121
+ stroke: Optional[str] = Field(default=None, description="Marker stroke color")
122
+ marker: Optional[Dict[str, Any]] = Field(
123
+ default=None, description="Marker configuration"
124
+ )
125
+ tooltip: Optional[Dict[str, Any]] = Field(
126
+ default=None, description="Tooltip configuration"
127
+ )
128
+
129
+
130
+ class AGHeatmapSeriesConfig(AGChartSeriesBase):
131
+ """AG-Charts heatmap series configuration."""
132
+
133
+ type: Literal["heatmap"] = "heatmap"
134
+ colorKey: str = Field(..., description="Key for heatmap color values")
135
+ xName: Optional[str] = Field(default=None, description="X axis display name")
136
+ yName: Optional[str] = Field(default=None, description="Y axis display name")
137
+ colorName: Optional[str] = Field(default=None, description="Color value display name")
138
+ colorRange: Optional[List[str]] = Field(
139
+ default=None, description="Color interpolation range"
140
+ )
141
+ colorDomain: Optional[List[float]] = Field(
142
+ default=None, description="Color domain [min, max]"
143
+ )
144
+ stroke: Optional[str] = Field(default=None, description="Cell border color")
145
+ strokeWidth: Optional[float] = Field(default=None, description="Cell border width")
146
+ tooltip: Optional[Dict[str, Any]] = Field(
147
+ default=None, description="Tooltip configuration"
148
+ )
149
+
150
+
151
+ class AGPieSeriesConfig(EmbeddedModel):
152
+ """AG-Charts pie series configuration."""
153
+
154
+ type: Literal["pie"] = "pie"
155
+ angleKey: str = Field(..., description="Key for pie slice angles")
156
+ radiusKey: Optional[str] = Field(
157
+ default=None, description="Key for pie slice radius"
158
+ )
159
+ labelKey: Optional[str] = Field(
160
+ default=None, description="Key for pie slice labels"
161
+ )
162
+ legendItemKey: Optional[str] = Field(
163
+ default=None, description="Key for legend item labels"
164
+ )
165
+ calloutLabelKey: Optional[str] = Field(
166
+ default=None, description="Key for callout labels"
167
+ )
168
+ sectorLabelKey: Optional[str] = Field(
169
+ default=None, description="Key for sector labels"
170
+ )
171
+ visible: Optional[bool] = Field(
172
+ default=True, description="Whether series is visible"
173
+ )
174
+ showInLegend: Optional[bool] = Field(default=True, description="Show in legend")
175
+ title: Optional[str] = Field(default=None, description="Series title")
176
+ fills: Optional[List[str]] = Field(default=None, description="Slice fill colors")
177
+ strokes: Optional[List[str]] = Field(default=None, description="Slice stroke colors")
178
+ tooltip: Optional[Dict[str, Any]] = Field(
179
+ default=None, description="Tooltip configuration"
180
+ )
181
+ data: List[Dict[str, Any]] = Field(default_factory=list, description="Chart data")
182
+
183
+
184
+ class AGDonutSeriesConfig(EmbeddedModel):
185
+ """AG-Charts donut series configuration."""
186
+
187
+ type: Literal["donut"] = "donut"
188
+ angleKey: str = Field(..., description="Key for donut slice angles")
189
+ radiusKey: Optional[str] = Field(
190
+ default=None, description="Key for donut slice radius"
191
+ )
192
+ labelKey: Optional[str] = Field(
193
+ default=None, description="Key for donut slice labels"
194
+ )
195
+ legendItemKey: Optional[str] = Field(
196
+ default=None, description="Key for legend item labels"
197
+ )
198
+ calloutLabelKey: Optional[str] = Field(
199
+ default=None, description="Key for callout labels"
200
+ )
201
+ sectorLabelKey: Optional[str] = Field(
202
+ default=None, description="Key for sector labels"
203
+ )
204
+ innerRadiusRatio: Optional[float] = Field(
205
+ default=0.6, description="Inner radius ratio"
206
+ )
207
+ visible: Optional[bool] = Field(
208
+ default=True, description="Whether series is visible"
209
+ )
210
+ showInLegend: Optional[bool] = Field(default=True, description="Show in legend")
211
+ title: Optional[str] = Field(default=None, description="Series title")
212
+ fills: Optional[List[str]] = Field(default=None, description="Slice fill colors")
213
+ strokes: Optional[List[str]] = Field(default=None, description="Slice stroke colors")
214
+ tooltip: Optional[Dict[str, Any]] = Field(
215
+ default=None, description="Tooltip configuration"
216
+ )
217
+ data: List[Dict[str, Any]] = Field(default_factory=list, description="Chart data")
218
+
219
+
220
+ # Union type for all series configurations
221
+ AGChartSeries = Union[
222
+ AGLineSeriesConfig,
223
+ AGBarSeriesConfig,
224
+ AGRangeBarSeriesConfig,
225
+ AGColumnSeriesConfig,
226
+ AGAreaSeriesConfig,
227
+ AGScatterSeriesConfig,
228
+ AGHeatmapSeriesConfig,
229
+ AGPieSeriesConfig,
230
+ AGDonutSeriesConfig,
231
+ ]
232
+
233
+
234
+ # Axis Configurations
235
+ class AGChartAxisConfig(EmbeddedModel):
236
+ """AG-Charts axis configuration."""
237
+
238
+ type: Literal["category", "number", "time", "log"] = Field(
239
+ ..., description="Axis type"
240
+ )
241
+ position: Literal["top", "right", "bottom", "left"] = Field(
242
+ ..., description="Axis position"
243
+ )
244
+ title: Optional[str] = Field(default=None, description="Axis title")
245
+ min: Optional[float] = Field(default=None, description="Minimum axis value")
246
+ max: Optional[float] = Field(default=None, description="Maximum axis value")
247
+ tick: Optional[Dict[str, Any]] = Field(
248
+ default=None, description="Tick configuration"
249
+ )
250
+ label: Optional[Dict[str, Any]] = Field(
251
+ default=None, description="Label configuration"
252
+ )
253
+ gridStyle: Optional[List[Dict[str, Any]]] = Field(
254
+ default=None, description="Grid line style"
255
+ )
256
+
257
+
258
+ # Legend Configuration
259
+ class AGChartLegendConfig(EmbeddedModel):
260
+ """AG-Charts legend configuration."""
261
+
262
+ enabled: bool = Field(default=True, description="Enable legend")
263
+ position: Literal["top", "right", "bottom", "left"] = Field(
264
+ default="right", description="Legend position"
265
+ )
266
+ spacing: float = Field(default=20, description="Legend spacing")
267
+ item: Dict[str, Any] = Field(
268
+ default_factory=dict, description="Legend item configuration"
269
+ )
270
+
271
+
272
+ # Title Configuration
273
+ class AGChartTitleConfig(EmbeddedModel):
274
+ """AG-Charts title configuration."""
275
+
276
+ text: str = Field("Chart Title", description="Title text")
277
+ # fontSize: Optional[int] = Field(default=16, description="Title font size")
278
+ # fontWeight: Optional[str] = Field(default="bold", description="Title font weight")
279
+ # color: Optional[str] = Field(default=None, description="Title color")
280
+
281
+
282
+ # Subtitle Configuration
283
+ class AGChartSubtitleConfig(EmbeddedModel):
284
+ """AG-Charts subtitle configuration."""
285
+
286
+ text: str = Field(..., description="Subtitle text")
287
+ fontSize: Optional[int] = Field(default=12, description="Subtitle font size")
288
+ color: Optional[str] = Field(default=None, description="Subtitle color")
289
+
290
+
291
+ # Frame Configuration
292
+ class AGChartFrameConfig(EmbeddedModel):
293
+ """AG-Charts frame (border) configuration."""
294
+
295
+ enabled: bool = Field(default=True, description="Enable chart frame/border")
296
+ stroke: str = Field(default="black", description="Frame stroke color")
297
+ strokeWidth: float = Field(default=1, description="Frame stroke width")
298
+ cornerRadius: float = Field(default=0, description="Frame corner radius")
299
+ opacity: float = Field(default=1, description="Frame opacity")
300
+
301
+
302
+ # Main Chart Model
303
+ @simstack_model
304
+ class ChartArtifactModel(Model):
305
+ """AG-Charts configuration model."""
306
+
307
+ parent_id: Optional[ObjectId] = None
308
+
309
+ # Chart data
310
+ data: List[Dict[str, Any]] = Field(default_factory=list, description="Chart data")
311
+
312
+ # Chart configuration
313
+ title: AGChartTitleConfig = Field(..., description="Chart title configuration")
314
+ # subtitle: AGChartSubtitleConfig = Field(..., description="Chart subtitle configuration")
315
+
316
+ # Series configuration
317
+ series: List[AGChartSeries] = Field(
318
+ default_factory=list, description="Chart series configurations"
319
+ )
320
+
321
+ # Axes configuration
322
+ axes: List[AGChartAxisConfig] = Field(
323
+ default_factory=list, description="Chart axes configurations"
324
+ )
325
+
326
+ # # Legend configuration
327
+ legend: AGChartLegendConfig = Field(
328
+ default=AGChartLegendConfig(), description="Legend configuration"
329
+ )
330
+ #
331
+ # Chart styling and behavior
332
+ width: int = Field(default=800, description="Chart width in pixels")
333
+ height: int = Field(default=400, description="Chart height in pixels")
334
+ padding: Optional[Dict[str, int]] = Field(default=None, description="Chart padding")
335
+ background: Optional[Dict[str, Any]] = Field(
336
+ default=None, description="Background configuration"
337
+ )
338
+ frame: AGChartFrameConfig = Field(
339
+ default=AGChartFrameConfig(enabled=False), description="Frame/border configuration"
340
+ )
341
+
342
+ # Animation
343
+ animation: Optional[Dict[str, Any]] = Field(
344
+ default=None, description="Animation configuration"
345
+ )
346
+
347
+ # Tooltip
348
+ tooltip: Optional[Dict[str, Any]] = Field(
349
+ default=None, description="Global tooltip configuration"
350
+ )
351
+
352
+ # Theme
353
+ theme: Optional[str] = Field(default="ag-default", description="Chart theme")
354
+
355
+ # Additional options
356
+ options: Optional[Dict[str, Any]] = Field(
357
+ default_factory=dict, description="Additional chart options"
358
+ )
359
+
360
+ def make_table_entries(
361
+ self,
362
+ max_recursion_level=1,
363
+ drop_id=True,
364
+ current_level=0,
365
+ visited=None,
366
+ field_prefix="",
367
+ ):
368
+ return {"title": self.title.text[:10]}
369
+
370
+ def make_column_defs_instance(
371
+ self,
372
+ table_name=None,
373
+ max_recursion_level=1,
374
+ drop_id=True,
375
+ current_level=0,
376
+ visited=None,
377
+ field_prefix="",
378
+ ):
379
+ return [{"field": "title", "headerName": "Chart"}]
380
+
381
+
382
+ # Helper functions for creating specific chart types
383
+ def create_simple_line_chart(
384
+ data: List[Dict[str, Any]],
385
+ x_key: str,
386
+ y_key: str,
387
+ title: Optional[str] = None,
388
+ parent_id: ObjectId = None,
389
+ ) -> ChartArtifactModel:
390
+ """Create a simple line chart."""
391
+ chart_title = (
392
+ AGChartTitleConfig(text=title) if title else AGChartTitleConfig(text="Chart")
393
+ )
394
+ # subtitle = AGChartSubtitleConfig(text="Subtitle")
395
+
396
+ series = [
397
+ AGLineSeriesConfig(
398
+ type="line", xKey=x_key, yKey=y_key, title=y_key.title(), data=data
399
+ )
400
+ ]
401
+
402
+ axes = [
403
+ AGChartAxisConfig(type="number", position="bottom", title=x_key.title()),
404
+ AGChartAxisConfig(type="number", position="left", title=y_key.title()),
405
+ ]
406
+
407
+ return ChartArtifactModel(
408
+ parent_id=parent_id,
409
+ data=data,
410
+ title=chart_title,
411
+ # subtitle=subtitle,
412
+ series=series,
413
+ axes=axes,
414
+ )
415
+
416
+
417
+ def create_simple_bar_chart(
418
+ data: List[Dict[str, Any]],
419
+ x_key: str,
420
+ y_key: str,
421
+ title: Optional[str] = None,
422
+ parent_id: Optional[ObjectId] = None,
423
+ ) -> ChartArtifactModel:
424
+ """Create a simple bar chart."""
425
+ chart_title = (
426
+ AGChartTitleConfig(text=title) if title else AGChartTitleConfig(text="Chart")
427
+ )
428
+
429
+ series = [
430
+ AGColumnSeriesConfig(
431
+ type="column", xKey=x_key, yKey=y_key, title=y_key.title(), data=data
432
+ )
433
+ ]
434
+
435
+ axes = [
436
+ AGChartAxisConfig(type="category", position="bottom", title=x_key.title()),
437
+ AGChartAxisConfig(type="number", position="left", title=y_key.title()),
438
+ ]
439
+
440
+ return ChartArtifactModel(
441
+ parent_id=parent_id, data=data, title=chart_title, series=series, axes=axes
442
+ )
443
+
444
+
445
+ def create_simple_pie_chart(
446
+ data: List[Dict[str, Any]],
447
+ angle_key: str,
448
+ label_key: str,
449
+ title: Optional[str] = None,
450
+ legend_item_key: Optional[str] = None,
451
+ callout_label_key: Optional[str] = None,
452
+ sector_label_key: Optional[str] = None,
453
+ parent_id: Optional[ObjectId] = None,
454
+ ) -> ChartArtifactModel:
455
+ """Create a simple pie chart."""
456
+ chart_title = (
457
+ AGChartTitleConfig(text=title) if title else AGChartTitleConfig(text="Chart")
458
+ )
459
+
460
+ series = [
461
+ AGPieSeriesConfig(
462
+ type="pie",
463
+ angleKey=angle_key,
464
+ labelKey=label_key,
465
+ legendItemKey=legend_item_key,
466
+ calloutLabelKey=callout_label_key,
467
+ sectorLabelKey=sector_label_key,
468
+ title="Distribution",
469
+ data=data,
470
+ )
471
+ ]
472
+
473
+ return ChartArtifactModel(
474
+ parent_id=parent_id, data=data, title=chart_title, series=series
475
+ )
476
+
477
+
478
+ def create_simple_range_bar_chart(
479
+ data: List[Dict[str, Any]],
480
+ x_key: str,
481
+ y_low_key: str,
482
+ y_high_key: str,
483
+ title: Optional[str] = None,
484
+ parent_id: Optional[ObjectId] = None,
485
+ direction: Optional[Literal["horizontal", "vertical"]] = None,
486
+ ) -> ChartArtifactModel:
487
+ """Create a simple range-bar chart."""
488
+ chart_title = (
489
+ AGChartTitleConfig(text=title) if title else AGChartTitleConfig(text="Chart")
490
+ )
491
+
492
+ series = [
493
+ AGRangeBarSeriesConfig(
494
+ type="range-bar",
495
+ xKey=x_key,
496
+ yLowKey=y_low_key,
497
+ yHighKey=y_high_key,
498
+ title=f"{y_low_key.title()} - {y_high_key.title()}",
499
+ direction=direction,
500
+ data=data,
501
+ )
502
+ ]
503
+
504
+ axes = [
505
+ AGChartAxisConfig(type="category", position="bottom", title=x_key.title()),
506
+ AGChartAxisConfig(
507
+ type="number",
508
+ position="left",
509
+ title=f"{y_low_key.title()} / {y_high_key.title()}",
510
+ ),
511
+ ]
512
+
513
+ return ChartArtifactModel(
514
+ parent_id=parent_id, data=data, title=chart_title, series=series, axes=axes
515
+ )
516
+
517
+
518
+ def create_simple_area_chart(
519
+ data: List[Dict[str, Any]],
520
+ x_key: str,
521
+ y_key: str,
522
+ title: Optional[str] = None,
523
+ parent_id: Optional[ObjectId] = None,
524
+ ) -> ChartArtifactModel:
525
+ """Create a simple area chart."""
526
+ chart_title = (
527
+ AGChartTitleConfig(text=title) if title else AGChartTitleConfig(text="Chart")
528
+ )
529
+
530
+ series = [
531
+ AGAreaSeriesConfig(
532
+ type="area", xKey=x_key, yKey=y_key, title=y_key.title(), data=data
533
+ )
534
+ ]
535
+
536
+ axes = [
537
+ AGChartAxisConfig(type="category", position="bottom", title=x_key.title()),
538
+ AGChartAxisConfig(type="number", position="left", title=y_key.title()),
539
+ ]
540
+
541
+ return ChartArtifactModel(
542
+ parent_id=parent_id, data=data, title=chart_title, series=series, axes=axes
543
+ )
544
+
545
+
546
+ def create_simple_scatter_chart(
547
+ data: List[Dict[str, Any]],
548
+ x_key: str,
549
+ y_key: str,
550
+ title: Optional[str] = None,
551
+ parent_id: Optional[ObjectId] = None,
552
+ ) -> ChartArtifactModel:
553
+ """Create a simple scatter chart."""
554
+ chart_title = (
555
+ AGChartTitleConfig(text=title) if title else AGChartTitleConfig(text="Chart")
556
+ )
557
+
558
+ series = [
559
+ AGScatterSeriesConfig(
560
+ type="scatter", xKey=x_key, yKey=y_key, title=y_key.title(), data=data
561
+ )
562
+ ]
563
+
564
+ axes = [
565
+ AGChartAxisConfig(type="number", position="bottom", title=x_key.title()),
566
+ AGChartAxisConfig(type="number", position="left", title=y_key.title()),
567
+ ]
568
+
569
+ return ChartArtifactModel(
570
+ parent_id=parent_id, data=data, title=chart_title, series=series, axes=axes
571
+ )
572
+
573
+
574
+ def create_simple_heatmap_chart(
575
+ data: List[Dict[str, Any]],
576
+ x_key: str,
577
+ y_key: str,
578
+ color_key: str,
579
+ title: Optional[str] = None,
580
+ parent_id: Optional[ObjectId] = None,
581
+ x_axis_type: Literal["category", "number", "time", "log"] = "category",
582
+ y_axis_type: Literal["category", "number", "time", "log"] = "category",
583
+ ) -> ChartArtifactModel:
584
+ """Create a simple heatmap chart."""
585
+ chart_title = (
586
+ AGChartTitleConfig(text=title) if title else AGChartTitleConfig(text="Chart")
587
+ )
588
+
589
+ series = [
590
+ AGHeatmapSeriesConfig(
591
+ type="heatmap",
592
+ xKey=x_key,
593
+ yKey=y_key,
594
+ colorKey=color_key,
595
+ title=color_key.title(),
596
+ data=data,
597
+ )
598
+ ]
599
+
600
+ axes = [
601
+ AGChartAxisConfig(type=x_axis_type, position="bottom", title=x_key.title()),
602
+ AGChartAxisConfig(type=y_axis_type, position="left", title=y_key.title()),
603
+ ]
604
+
605
+ return ChartArtifactModel(
606
+ parent_id=parent_id, data=data, title=chart_title, series=series, axes=axes
607
+ )
608
+
609
+
610
+ def create_simple_donut_chart(
611
+ data: List[Dict[str, Any]],
612
+ angle_key: str,
613
+ label_key: str,
614
+ title: Optional[str] = None,
615
+ legend_item_key: Optional[str] = None,
616
+ callout_label_key: Optional[str] = None,
617
+ sector_label_key: Optional[str] = None,
618
+ inner_radius_ratio: float = 0.6,
619
+ parent_id: Optional[ObjectId] = None,
620
+ ) -> ChartArtifactModel:
621
+ """Create a simple donut chart."""
622
+ chart_title = (
623
+ AGChartTitleConfig(text=title) if title else AGChartTitleConfig(text="Chart")
624
+ )
625
+
626
+ series = [
627
+ AGDonutSeriesConfig(
628
+ type="donut",
629
+ angleKey=angle_key,
630
+ labelKey=label_key,
631
+ legendItemKey=legend_item_key,
632
+ calloutLabelKey=callout_label_key,
633
+ sectorLabelKey=sector_label_key,
634
+ innerRadiusRatio=inner_radius_ratio,
635
+ title="Distribution",
636
+ data=data,
637
+ )
638
+ ]
639
+
640
+ return ChartArtifactModel(
641
+ parent_id=parent_id, data=data, title=chart_title, series=series
642
+ )
643
+
644
+
645
+ def create_multi_series_line_chart(
646
+ data: List[Dict[str, Any]],
647
+ x_key: str,
648
+ y_keys: List[str],
649
+ title: Optional[str] = None,
650
+ parent_id: Optional[ObjectId] = None,
651
+ ) -> ChartArtifactModel:
652
+ """Create a line chart with multiple y-axis series."""
653
+ chart_title = AGChartTitleConfig(text=title) if title else AGChartTitleConfig(text="Chart")
654
+ colors = [
655
+ "#FF6B6B", # red
656
+ "#4ECDC4", # teal
657
+ "#45B7D1", # light blue
658
+ "#96CEB4", # sage green
659
+ "#FECA57", # yellow
660
+ "#A29BFE", # light purple
661
+ "#FF8C94", # pink
662
+ "#55EFC4", # mint
663
+ "#81ECEC", # cyan
664
+ ]
665
+
666
+ series = []
667
+ for i, y_key in enumerate(y_keys):
668
+ series.append(
669
+ AGLineSeriesConfig(
670
+ type="line",
671
+ xKey=x_key,
672
+ yKey=y_key,
673
+ title=y_key.title(),
674
+ data=data,
675
+ stroke=colors[i % len(colors)]
676
+ )
677
+ )
678
+
679
+ axes = [
680
+ AGChartAxisConfig(type="number", position="bottom", title=x_key.title()),
681
+ AGChartAxisConfig(type="number", position="left", title="Values"),
682
+ ]
683
+
684
+ return ChartArtifactModel(
685
+ parent_id=parent_id,
686
+ data=data,
687
+ title=chart_title,
688
+ series=series,
689
+ axes=axes,
690
+ )