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,711 @@
1
+ <!doctype html>
2
+ <html class="no-js" lang="en" data-content_root="../../../">
3
+ <head><meta charset="utf-8">
4
+ <meta name="viewport" content="width=device-width,initial-scale=1">
5
+ <meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../../genindex.html"><link rel="search" title="Search" href="../../../search.html">
6
+
7
+ <!-- Generated with Sphinx 9.1.0 and Furo 2025.12.19 -->
8
+ <title>simstack.models.dataset_metadata - SimStack II documentation</title>
9
+ <link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d111a655" />
10
+ <link rel="stylesheet" type="text/css" href="../../../_static/styles/furo.css?v=7bdb33bb" />
11
+ <link rel="stylesheet" type="text/css" href="../../../_static/styles/furo-extensions.css?v=8dab3a3b" />
12
+ <link rel="stylesheet" type="text/css" href="../../../_static/cobalt2-theme.css?v=2d651046" />
13
+ <link rel="stylesheet" type="text/css" href="../../../_static/docs-build-badge.css?v=803faff8" />
14
+
15
+
16
+
17
+
18
+ <style>
19
+ body {
20
+ --color-code-background: #f2f2f2;
21
+ --color-code-foreground: #1e1e1e;
22
+
23
+ }
24
+ @media not print {
25
+ body[data-theme="dark"] {
26
+ --color-code-background: #202020;
27
+ --color-code-foreground: #d0d0d0;
28
+ --color-background-primary: #132738;
29
+ --color-background-secondary: #1e3a52;
30
+ --color-foreground-primary: #ffffff;
31
+ --color-foreground-secondary: #bac8d3;
32
+ --color-brand-primary: #22d5ff;
33
+ --color-brand-content: #0088ff;
34
+
35
+ }
36
+ @media (prefers-color-scheme: dark) {
37
+ body:not([data-theme="light"]) {
38
+ --color-code-background: #202020;
39
+ --color-code-foreground: #d0d0d0;
40
+ --color-background-primary: #132738;
41
+ --color-background-secondary: #1e3a52;
42
+ --color-foreground-primary: #ffffff;
43
+ --color-foreground-secondary: #bac8d3;
44
+ --color-brand-primary: #22d5ff;
45
+ --color-brand-content: #0088ff;
46
+
47
+ }
48
+ }
49
+ }
50
+ </style></head>
51
+ <body>
52
+
53
+ <script>
54
+ document.body.dataset.theme = localStorage.getItem("theme") || "auto";
55
+ </script>
56
+
57
+
58
+ <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
59
+ <symbol id="svg-toc" viewBox="0 0 24 24">
60
+ <title>Contents</title>
61
+ <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
62
+ <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
63
+ </svg>
64
+ </symbol>
65
+ <symbol id="svg-menu" viewBox="0 0 24 24">
66
+ <title>Menu</title>
67
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
68
+ stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
69
+ <line x1="3" y1="12" x2="21" y2="12"></line>
70
+ <line x1="3" y1="6" x2="21" y2="6"></line>
71
+ <line x1="3" y1="18" x2="21" y2="18"></line>
72
+ </svg>
73
+ </symbol>
74
+ <symbol id="svg-arrow-right" viewBox="0 0 24 24">
75
+ <title>Expand</title>
76
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
77
+ stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
78
+ <polyline points="9 18 15 12 9 6"></polyline>
79
+ </svg>
80
+ </symbol>
81
+ <symbol id="svg-sun" viewBox="0 0 24 24">
82
+ <title>Light mode</title>
83
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
84
+ stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
85
+ <circle cx="12" cy="12" r="5"></circle>
86
+ <line x1="12" y1="1" x2="12" y2="3"></line>
87
+ <line x1="12" y1="21" x2="12" y2="23"></line>
88
+ <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
89
+ <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
90
+ <line x1="1" y1="12" x2="3" y2="12"></line>
91
+ <line x1="21" y1="12" x2="23" y2="12"></line>
92
+ <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
93
+ <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
94
+ </svg>
95
+ </symbol>
96
+ <symbol id="svg-moon" viewBox="0 0 24 24">
97
+ <title>Dark mode</title>
98
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
99
+ stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
100
+ <path stroke="none" d="M0 0h24v24H0z" fill="none" />
101
+ <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
102
+ </svg>
103
+ </symbol>
104
+ <symbol id="svg-sun-with-moon" viewBox="0 0 24 24">
105
+ <title>Auto light/dark, in light mode</title>
106
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
107
+ stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
108
+ class="icon-custom-derived-from-feather-sun-and-tabler-moon">
109
+ <path style="opacity: 50%" d="M 5.411 14.504 C 5.471 14.504 5.532 14.504 5.591 14.504 C 3.639 16.319 4.383 19.569 6.931 20.352 C 7.693 20.586 8.512 20.551 9.25 20.252 C 8.023 23.207 4.056 23.725 2.11 21.184 C 0.166 18.642 1.702 14.949 4.874 14.536 C 5.051 14.512 5.231 14.5 5.411 14.5 L 5.411 14.504 Z"/>
110
+ <line x1="14.5" y1="3.25" x2="14.5" y2="1.25"/>
111
+ <line x1="14.5" y1="15.85" x2="14.5" y2="17.85"/>
112
+ <line x1="10.044" y1="5.094" x2="8.63" y2="3.68"/>
113
+ <line x1="19" y1="14.05" x2="20.414" y2="15.464"/>
114
+ <line x1="8.2" y1="9.55" x2="6.2" y2="9.55"/>
115
+ <line x1="20.8" y1="9.55" x2="22.8" y2="9.55"/>
116
+ <line x1="10.044" y1="14.006" x2="8.63" y2="15.42"/>
117
+ <line x1="19" y1="5.05" x2="20.414" y2="3.636"/>
118
+ <circle cx="14.5" cy="9.55" r="3.6"/>
119
+ </svg>
120
+ </symbol>
121
+ <symbol id="svg-moon-with-sun" viewBox="0 0 24 24">
122
+ <title>Auto light/dark, in dark mode</title>
123
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
124
+ stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
125
+ class="icon-custom-derived-from-feather-sun-and-tabler-moon">
126
+ <path d="M 8.282 7.007 C 8.385 7.007 8.494 7.007 8.595 7.007 C 5.18 10.184 6.481 15.869 10.942 17.24 C 12.275 17.648 13.706 17.589 15 17.066 C 12.851 22.236 5.91 23.143 2.505 18.696 C -0.897 14.249 1.791 7.786 7.342 7.063 C 7.652 7.021 7.965 7 8.282 7 L 8.282 7.007 Z"/>
127
+ <line style="opacity: 50%" x1="18" y1="3.705" x2="18" y2="2.5"/>
128
+ <line style="opacity: 50%" x1="18" y1="11.295" x2="18" y2="12.5"/>
129
+ <line style="opacity: 50%" x1="15.316" y1="4.816" x2="14.464" y2="3.964"/>
130
+ <line style="opacity: 50%" x1="20.711" y1="10.212" x2="21.563" y2="11.063"/>
131
+ <line style="opacity: 50%" x1="14.205" y1="7.5" x2="13.001" y2="7.5"/>
132
+ <line style="opacity: 50%" x1="21.795" y1="7.5" x2="23" y2="7.5"/>
133
+ <line style="opacity: 50%" x1="15.316" y1="10.184" x2="14.464" y2="11.036"/>
134
+ <line style="opacity: 50%" x1="20.711" y1="4.789" x2="21.563" y2="3.937"/>
135
+ <circle style="opacity: 50%" cx="18" cy="7.5" r="2.169"/>
136
+ </svg>
137
+ </symbol>
138
+ <symbol id="svg-pencil" viewBox="0 0 24 24">
139
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
140
+ stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-pencil-code">
141
+ <path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" />
142
+ <path d="M13.5 6.5l4 4" />
143
+ <path d="M20 21l2 -2l-2 -2" />
144
+ <path d="M17 17l-2 2l2 2" />
145
+ </svg>
146
+ </symbol>
147
+ <symbol id="svg-eye" viewBox="0 0 24 24">
148
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
149
+ stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-eye-code">
150
+ <path stroke="none" d="M0 0h24v24H0z" fill="none" />
151
+ <path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
152
+ <path
153
+ d="M11.11 17.958c-3.209 -.307 -5.91 -2.293 -8.11 -5.958c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6c-.21 .352 -.427 .688 -.647 1.008" />
154
+ <path d="M20 21l2 -2l-2 -2" />
155
+ <path d="M17 17l-2 2l2 2" />
156
+ </svg>
157
+ </symbol>
158
+ </svg>
159
+
160
+ <input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation" aria-label="Toggle site navigation sidebar">
161
+ <input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc" aria-label="Toggle table of contents sidebar">
162
+ <label class="overlay sidebar-overlay" for="__navigation"></label>
163
+ <label class="overlay toc-overlay" for="__toc"></label>
164
+
165
+ <a class="skip-to-content muted-link" href="#furo-main-content">Skip to content</a>
166
+
167
+
168
+
169
+ <div class="page">
170
+ <header class="mobile-header">
171
+ <div class="header-left">
172
+ <label class="nav-overlay-icon" for="__navigation">
173
+ <span class="icon"><svg><use href="#svg-menu"></use></svg></span>
174
+ </label>
175
+ </div>
176
+ <div class="header-center">
177
+ <a href="../../../index.html"><div class="brand">SimStack II documentation</div></a>
178
+ </div>
179
+ <div class="header-right">
180
+ <div class="theme-toggle-container theme-toggle-header">
181
+ <button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
182
+ <svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
183
+ <svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
184
+ <svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
185
+ <svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
186
+ </button>
187
+ </div>
188
+ <label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
189
+ <span class="icon"><svg><use href="#svg-toc"></use></svg></span>
190
+ </label>
191
+ </div>
192
+ </header>
193
+ <aside class="sidebar-drawer">
194
+ <div class="sidebar-container">
195
+
196
+ <div class="sidebar-sticky"><a class="sidebar-brand" href="../../../index.html">
197
+
198
+
199
+ </a><form class="sidebar-search-container" method="get" action="../../../search.html" role="search">
200
+ <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
201
+ <input type="hidden" name="check_keywords" value="yes">
202
+ <input type="hidden" name="area" value="default">
203
+ </form>
204
+ <div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
205
+ <p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
206
+ <ul>
207
+ <li class="toctree-l1"><a class="reference internal" href="../../../overview.html">Overview</a></li>
208
+ <li class="toctree-l1"><a class="reference internal" href="../../../workflows.html">Workflows</a></li>
209
+ <li class="toctree-l1"><a class="reference internal" href="../../../ui_documentation.html">Graphical User Interface</a></li>
210
+ <li class="toctree-l1 has-children"><a class="reference internal" href="../../../developer_guide.html">Developer Guide</a><input aria-label="Toggle navigation of Developer Guide" class="toctree-checkbox" id="toctree-checkbox-1" name="toctree-checkbox-1" role="switch" type="checkbox"/><label for="toctree-checkbox-1"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
211
+ <li class="toctree-l2"><a class="reference internal" href="../../../data.html">Persisting and Visualizing Data</a></li>
212
+ <li class="toctree-l2"><a class="reference internal" href="../../../datasets.html">Datasets</a></li>
213
+ <li class="toctree-l2"><a class="reference internal" href="../../../lists.html">List Mixins</a></li>
214
+ <li class="toctree-l2"><a class="reference internal" href="../../../array_lists.html">Array Lists</a></li>
215
+ <li class="toctree-l2"><a class="reference internal" href="../../../tables.html">Tables</a></li>
216
+ <li class="toctree-l2"><a class="reference internal" href="../../../files.html">File Management</a></li>
217
+ <li class="toctree-l2"><a class="reference internal" href="../../../resource_config.html">Program Execution</a></li>
218
+ <li class="toctree-l2"><a class="reference internal" href="../../../mass_runner.html">MassRunner</a></li>
219
+ <li class="toctree-l2"><a class="reference internal" href="../../../fire_and_forget_runner.html">FireAndForgetRunner</a></li>
220
+ <li class="toctree-l2"><a class="reference internal" href="../../../docker_nodes.html">Creating Docker Containers for SimStack Nodes</a></li>
221
+ <li class="toctree-l2"><a class="reference internal" href="../../../testing_complex_nodes.html">Testing Complex Nodes</a></li>
222
+ <li class="toctree-l2"><a class="reference internal" href="../../../database_migrations.html">Database Migrations</a></li>
223
+ <li class="toctree-l2"><a class="reference internal" href="../../../ci_pipeline.html">CI Pipeline and Documentation Artifacts</a></li>
224
+ <li class="toctree-l2"><a class="reference internal" href="../../../misc.html">Miscellaneous</a></li>
225
+ </ul>
226
+ </li>
227
+ <li class="toctree-l1"><a class="reference internal" href="../../../installation.html">Simstack II Setup</a></li>
228
+ <li class="toctree-l1 has-children"><a class="reference internal" href="../../../simstack/modules/modules.html">simstack</a><input aria-label="Toggle navigation of simstack" class="toctree-checkbox" id="toctree-checkbox-2" name="toctree-checkbox-2" role="switch" type="checkbox"/><label for="toctree-checkbox-2"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
229
+ <li class="toctree-l2 has-children"><a class="reference internal" href="../../../simstack/modules/simstack.html">simstack package</a><input aria-label="Toggle navigation of simstack package" class="toctree-checkbox" id="toctree-checkbox-3" name="toctree-checkbox-3" role="switch" type="checkbox"/><label for="toctree-checkbox-3"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
230
+ <li class="toctree-l3 has-children"><a class="reference internal" href="../../../simstack/modules/simstack.core.html">simstack.core package</a><input aria-label="Toggle navigation of simstack.core package" class="toctree-checkbox" id="toctree-checkbox-4" name="toctree-checkbox-4" role="switch" type="checkbox"/><label for="toctree-checkbox-4"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
231
+ <li class="toctree-l4"><a class="reference internal" href="../../../simstack/modules/simstack.core.services.html">simstack.core.services package</a></li>
232
+ </ul>
233
+ </li>
234
+ <li class="toctree-l3"><a class="reference internal" href="../../../simstack/modules/simstack.methods.html">simstack.methods package</a></li>
235
+ <li class="toctree-l3"><a class="reference internal" href="../../../simstack/modules/simstack.models.html">simstack.models package</a></li>
236
+ <li class="toctree-l3"><a class="reference internal" href="../../../simstack/modules/simstack.tables.html">simstack.tables package</a></li>
237
+ <li class="toctree-l3"><a class="reference internal" href="../../../simstack/modules/simstack.util.html">simstack.util package</a></li>
238
+ </ul>
239
+ </li>
240
+ </ul>
241
+ </li>
242
+ </ul>
243
+
244
+ </div>
245
+ </div>
246
+
247
+ </div>
248
+
249
+ </div>
250
+ </aside>
251
+ <div class="main">
252
+ <div class="content">
253
+ <div class="article-container">
254
+ <a href="#" class="back-to-top muted-link">
255
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
256
+ <path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
257
+ </svg>
258
+ <span>Back to top</span>
259
+ </a>
260
+ <div class="content-icon-container">
261
+ <div class="theme-toggle-container theme-toggle-content">
262
+ <button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
263
+ <svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
264
+ <svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
265
+ <svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
266
+ <svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
267
+ </button>
268
+ </div>
269
+ <label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
270
+ <span class="icon"><svg><use href="#svg-toc"></use></svg></span>
271
+ </label>
272
+ </div>
273
+ <article role="main" id="furo-main-content">
274
+ <h1>Source code for simstack.models.dataset_metadata</h1><div class="highlight"><pre>
275
+ <span></span><span class="kn">from</span><span class="w"> </span><span class="nn">datetime</span><span class="w"> </span><span class="kn">import</span> <span class="n">datetime</span>
276
+ <span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Union</span><span class="p">,</span> <span class="n">List</span>
277
+
278
+ <span class="kn">from</span><span class="w"> </span><span class="nn">odmantic</span><span class="w"> </span><span class="kn">import</span> <span class="n">Model</span><span class="p">,</span> <span class="n">EmbeddedModel</span><span class="p">,</span> <span class="n">Field</span>
279
+
280
+ <span class="kn">from</span><span class="w"> </span><span class="nn">simstack.core.asnyc_helper</span><span class="w"> </span><span class="kn">import</span> <span class="n">async_helper</span>
281
+ <span class="kn">from</span><span class="w"> </span><span class="nn">simstack.models</span><span class="w"> </span><span class="kn">import</span> <span class="n">simstack_model</span>
282
+
283
+
284
+ <span class="k">def</span><span class="w"> </span><span class="nf">_get_json_schema</span><span class="p">(</span><span class="n">data</span><span class="p">:</span> <span class="n">Dict</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
285
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
286
+ <span class="sd"> Inspects the current data dict and returns a JSON schema for that dict.</span>
287
+
288
+ <span class="sd"> Returns:</span>
289
+ <span class="sd"> dict: JSON schema describing the structure and types of the current data dict</span>
290
+ <span class="sd"> &quot;&quot;&quot;</span>
291
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span>
292
+ <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;object&quot;</span><span class="p">,</span> <span class="s2">&quot;properties&quot;</span><span class="p">:</span> <span class="p">{},</span> <span class="s2">&quot;additionalProperties&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">}</span>
293
+
294
+ <span class="n">properties</span> <span class="o">=</span> <span class="p">{}</span>
295
+
296
+ <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
297
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
298
+ <span class="n">properties</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;string&quot;</span><span class="p">}</span>
299
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">bool</span><span class="p">):</span>
300
+ <span class="c1"># Check bool before int/float since bool is a subclass of int in Python</span>
301
+ <span class="n">properties</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;boolean&quot;</span><span class="p">}</span>
302
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
303
+ <span class="n">properties</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;integer&quot;</span><span class="p">}</span>
304
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
305
+ <span class="n">properties</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;number&quot;</span><span class="p">}</span>
306
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="p">):</span>
307
+ <span class="n">properties</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;string&quot;</span><span class="p">,</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span> <span class="s2">&quot;date-time&quot;</span><span class="p">}</span>
308
+ <span class="k">else</span><span class="p">:</span>
309
+ <span class="c1"># Fallback for any unexpected types</span>
310
+ <span class="n">properties</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;string&quot;</span><span class="p">}</span>
311
+
312
+ <span class="n">schema</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;object&quot;</span><span class="p">,</span> <span class="s2">&quot;properties&quot;</span><span class="p">:</span> <span class="n">properties</span><span class="p">,</span> <span class="s2">&quot;additionalProperties&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">}</span>
313
+
314
+ <span class="k">return</span> <span class="n">schema</span>
315
+
316
+
317
+ <div class="viewcode-block" id="DataSetMetadataTemplate">
318
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadataTemplate">[docs]</a>
319
+ <span class="k">class</span><span class="w"> </span><span class="nc">DataSetMetadataTemplate</span><span class="p">(</span><span class="n">Model</span><span class="p">):</span>
320
+ <span class="n">dataset_type</span><span class="p">:</span> <span class="nb">str</span>
321
+ <span class="n">model_json</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
322
+ <span class="n">structure</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">dict</span><span class="p">)</span></div>
323
+
324
+
325
+
326
+ <div class="viewcode-block" id="DataSetMetadata">
327
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata">[docs]</a>
328
+ <span class="nd">@simstack_model</span>
329
+ <span class="k">class</span><span class="w"> </span><span class="nc">DataSetMetadata</span><span class="p">(</span><span class="n">EmbeddedModel</span><span class="p">):</span>
330
+ <span class="n">field_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">unique</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
331
+ <span class="n">data</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">datetime</span><span class="p">]]</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span>
332
+ <span class="n">default_factory</span><span class="o">=</span><span class="nb">dict</span>
333
+ <span class="p">)</span>
334
+ <span class="n">is_validated</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
335
+ <span class="n">structure</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">dict</span><span class="p">)</span>
336
+
337
+ <div class="viewcode-block" id="DataSetMetadata.get_json_schema">
338
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.get_json_schema">[docs]</a>
339
+ <span class="k">def</span><span class="w"> </span><span class="nf">get_json_schema</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
340
+ <span class="k">return</span> <span class="n">_get_json_schema</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span></div>
341
+
342
+
343
+ <div class="viewcode-block" id="DataSetMetadata.validate_dict">
344
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.validate_dict">[docs]</a>
345
+ <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">validate_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new_structure</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]])</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
346
+
347
+ <span class="kn">from</span><span class="w"> </span><span class="nn">simstack.core.context</span><span class="w"> </span><span class="kn">import</span> <span class="n">context</span>
348
+ <span class="n">reference_metadata</span> <span class="o">=</span> <span class="k">await</span> <span class="n">context</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">find_one</span><span class="p">(</span>
349
+ <span class="n">DataSetMetadataTemplate</span><span class="p">,</span>
350
+ <span class="n">DataSetMetadataTemplate</span><span class="o">.</span><span class="n">dataset_type</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">field_name</span><span class="p">,</span>
351
+ <span class="p">)</span>
352
+ <span class="c1"># remove empty sections without mutating the dict during iteration</span>
353
+ <span class="n">new_structure</span> <span class="o">=</span> <span class="p">{</span>
354
+ <span class="n">key</span><span class="p">:</span> <span class="n">value</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">new_structure</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">value</span>
355
+ <span class="p">}</span>
356
+
357
+ <span class="k">if</span> <span class="n">reference_metadata</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
358
+ <span class="n">metadata_template</span> <span class="o">=</span> <span class="n">DataSetMetadataTemplate</span><span class="p">(</span>
359
+ <span class="n">dataset_type</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">field_name</span><span class="p">,</span>
360
+ <span class="n">model_json</span><span class="o">=</span><span class="n">_get_json_schema</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">),</span>
361
+ <span class="n">structure</span><span class="o">=</span><span class="n">new_structure</span><span class="p">,</span>
362
+ <span class="p">)</span>
363
+ <span class="k">await</span> <span class="n">context</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">metadata_template</span><span class="p">)</span>
364
+ <span class="k">return</span> <span class="kc">True</span> <span class="c1"># first model of this type</span>
365
+
366
+ <span class="n">new_data_json</span> <span class="o">=</span> <span class="n">_get_json_schema</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
367
+
368
+ <span class="c1"># Compare schemas element by element</span>
369
+ <span class="n">ref_props</span> <span class="o">=</span> <span class="n">reference_metadata</span><span class="o">.</span><span class="n">model_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;properties&quot;</span><span class="p">,</span> <span class="p">{})</span>
370
+ <span class="n">new_props</span> <span class="o">=</span> <span class="n">new_data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;properties&quot;</span><span class="p">,</span> <span class="p">{})</span>
371
+
372
+ <span class="c1"># Check if property keys match</span>
373
+ <span class="k">if</span> <span class="nb">set</span><span class="p">(</span><span class="n">ref_props</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> <span class="o">!=</span> <span class="nb">set</span><span class="p">(</span><span class="n">new_props</span><span class="o">.</span><span class="n">keys</span><span class="p">()):</span>
374
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
375
+ <span class="sa">f</span><span class="s2">&quot;Data schema properties mismatch. Reference keys: </span><span class="si">{</span><span class="nb">set</span><span class="p">(</span><span class="n">ref_props</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span><span class="si">}</span><span class="s2">, Current keys: </span><span class="si">{</span><span class="nb">set</span><span class="p">(</span><span class="n">new_props</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span><span class="si">}</span><span class="s2">&quot;</span>
376
+ <span class="p">)</span>
377
+
378
+ <span class="c1"># Check each property type, allowing string format differences</span>
379
+ <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">ref_props</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
380
+ <span class="n">ref_prop</span> <span class="o">=</span> <span class="n">ref_props</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
381
+ <span class="n">new_prop</span> <span class="o">=</span> <span class="n">new_props</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
382
+
383
+ <span class="n">ref_type</span> <span class="o">=</span> <span class="n">ref_prop</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;type&quot;</span><span class="p">)</span>
384
+ <span class="n">new_type</span> <span class="o">=</span> <span class="n">new_prop</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;type&quot;</span><span class="p">)</span>
385
+
386
+ <span class="k">if</span> <span class="n">ref_type</span> <span class="o">!=</span> <span class="n">new_type</span><span class="p">:</span>
387
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
388
+ <span class="sa">f</span><span class="s2">&quot;Property &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; type mismatch. Reference: </span><span class="si">{</span><span class="n">ref_type</span><span class="si">}</span><span class="s2">, Current: </span><span class="si">{</span><span class="n">new_type</span><span class="si">}</span><span class="s2">&quot;</span>
389
+ <span class="p">)</span>
390
+
391
+ <span class="c1"># For string types, allow the format field to differ or be missing</span>
392
+ <span class="k">if</span> <span class="n">ref_type</span> <span class="o">==</span> <span class="s2">&quot;string&quot;</span><span class="p">:</span>
393
+ <span class="c1"># Compare all fields except &#39;format&#39;</span>
394
+ <span class="n">ref_without_format</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">ref_prop</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">k</span> <span class="o">!=</span> <span class="s2">&quot;format&quot;</span><span class="p">}</span>
395
+ <span class="n">new_without_format</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">new_prop</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">k</span> <span class="o">!=</span> <span class="s2">&quot;format&quot;</span><span class="p">}</span>
396
+ <span class="k">if</span> <span class="n">ref_without_format</span> <span class="o">!=</span> <span class="n">new_without_format</span><span class="p">:</span>
397
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
398
+ <span class="sa">f</span><span class="s2">&quot;Property &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; schema mismatch (excluding format). Reference: </span><span class="si">{</span><span class="n">ref_without_format</span><span class="si">}</span><span class="s2">, Current: </span><span class="si">{</span><span class="n">new_without_format</span><span class="si">}</span><span class="s2">&quot;</span>
399
+ <span class="p">)</span>
400
+ <span class="k">else</span><span class="p">:</span>
401
+ <span class="c1"># For non-string types, require exact match</span>
402
+ <span class="k">if</span> <span class="n">ref_prop</span> <span class="o">!=</span> <span class="n">new_prop</span><span class="p">:</span>
403
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
404
+ <span class="sa">f</span><span class="s2">&quot;Property &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; schema mismatch. Reference: </span><span class="si">{</span><span class="n">ref_prop</span><span class="si">}</span><span class="s2">, Current: </span><span class="si">{</span><span class="n">new_prop</span><span class="si">}</span><span class="s2">&quot;</span>
405
+ <span class="p">)</span>
406
+
407
+ <span class="c1"># Check if model types in existing sections match, and add new keys</span>
408
+ <span class="n">save_template</span> <span class="o">=</span> <span class="kc">False</span>
409
+ <span class="n">updated_structure</span> <span class="o">=</span> <span class="n">reference_metadata</span><span class="o">.</span><span class="n">structure</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
410
+
411
+ <span class="k">for</span> <span class="n">section_name</span><span class="p">,</span> <span class="n">new_section_content</span> <span class="ow">in</span> <span class="n">new_structure</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
412
+ <span class="k">if</span> <span class="n">section_name</span> <span class="ow">in</span> <span class="n">updated_structure</span><span class="p">:</span>
413
+ <span class="n">ref_section_content</span> <span class="o">=</span> <span class="n">updated_structure</span><span class="p">[</span><span class="n">section_name</span><span class="p">]</span>
414
+ <span class="c1"># Check if the structure of the section matches exactly</span>
415
+ <span class="k">if</span> <span class="n">ref_section_content</span> <span class="o">!=</span> <span class="n">new_section_content</span><span class="p">:</span>
416
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
417
+ <span class="sa">f</span><span class="s2">&quot;Section </span><span class="si">{</span><span class="n">section_name</span><span class="si">}</span><span class="s2"> has different content in existing structure. &quot;</span>
418
+ <span class="sa">f</span><span class="s2">&quot;Reference: </span><span class="si">{</span><span class="n">ref_section_content</span><span class="si">}</span><span class="s2">, Current: </span><span class="si">{</span><span class="n">new_section_content</span><span class="si">}</span><span class="s2">&quot;</span>
419
+ <span class="p">)</span>
420
+ <span class="k">else</span><span class="p">:</span>
421
+ <span class="c1"># Completely new section</span>
422
+ <span class="n">updated_structure</span><span class="p">[</span><span class="n">section_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_section_content</span>
423
+ <span class="n">save_template</span> <span class="o">=</span> <span class="kc">True</span>
424
+
425
+ <span class="k">if</span> <span class="n">save_template</span><span class="p">:</span>
426
+ <span class="n">reference_metadata</span><span class="o">.</span><span class="n">structure</span> <span class="o">=</span> <span class="n">new_structure</span>
427
+ <span class="k">await</span> <span class="n">context</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">reference_metadata</span><span class="p">)</span>
428
+ <span class="bp">self</span><span class="o">.</span><span class="n">structure</span> <span class="o">=</span> <span class="n">new_structure</span>
429
+ <span class="k">return</span> <span class="kc">True</span></div>
430
+
431
+
432
+ <div class="viewcode-block" id="DataSetMetadata.freeze">
433
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.freeze">[docs]</a>
434
+ <span class="nd">@async_helper</span>
435
+ <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">freeze</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new_structure</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]])</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
436
+ <span class="kn">from</span><span class="w"> </span><span class="nn">simstack.core.context</span><span class="w"> </span><span class="kn">import</span> <span class="n">context</span>
437
+ <span class="n">db</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">db</span>
438
+ <span class="n">reference_metadata</span> <span class="o">=</span> <span class="k">await</span> <span class="n">db</span><span class="o">.</span><span class="n">find_one</span><span class="p">(</span>
439
+ <span class="n">DataSetMetadataTemplate</span><span class="p">,</span>
440
+ <span class="n">DataSetMetadataTemplate</span><span class="o">.</span><span class="n">dataset_type</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">field_name</span><span class="p">,</span>
441
+ <span class="p">)</span>
442
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">reference_metadata</span><span class="p">:</span>
443
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Metadata does not exist&quot;</span><span class="p">)</span>
444
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">structure</span> <span class="o">!=</span> <span class="n">reference_metadata</span><span class="o">.</span><span class="n">structure</span><span class="p">:</span>
445
+ <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Metadata structure has changed in the database&quot;</span><span class="p">)</span>
446
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">structure</span> <span class="o">==</span> <span class="p">{}:</span>
447
+ <span class="bp">self</span><span class="o">.</span><span class="n">structure</span> <span class="o">=</span> <span class="n">new_structure</span>
448
+ <span class="n">reference_metadata</span><span class="o">.</span><span class="n">structure</span> <span class="o">=</span> <span class="n">new_structure</span>
449
+ <span class="k">await</span> <span class="n">db</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">reference_metadata</span><span class="p">)</span>
450
+ <span class="c1"># some structure exists already</span>
451
+ <span class="k">return</span> <span class="n">new_structure</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">structure</span></div>
452
+
453
+
454
+ <span class="nd">@property</span>
455
+ <span class="k">def</span><span class="w"> </span><span class="nf">initialized</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
456
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Check if the model has been fully constructed.&quot;&quot;&quot;</span>
457
+ <span class="c1"># A simple heuristic: if we have an ID or if type is set, we&#39;re initialized</span>
458
+ <span class="k">return</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;dataset_type&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">field_name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
459
+
460
+ <span class="c1"># Dict-like behavior methods</span>
461
+ <span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
462
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get item from data dict.&quot;&quot;&quot;</span>
463
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
464
+
465
+ <span class="k">def</span><span class="w"> </span><span class="fm">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">datetime</span><span class="p">]):</span>
466
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Set item in data dict with validation.&quot;&quot;&quot;</span>
467
+ <span class="c1"># Validate value type</span>
468
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">datetime</span><span class="p">)):</span>
469
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
470
+ <span class="sa">f</span><span class="s2">&quot;Value must be str, int, float, bool, or datetime, got </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">&quot;</span>
471
+ <span class="p">)</span>
472
+
473
+ <span class="c1"># Only check for structural changes after initialization</span>
474
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialized</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
475
+ <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span>
476
+ <span class="sa">f</span><span class="s2">&quot;Cannot add new key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; after initialization. Existing keys: </span><span class="si">{</span><span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span><span class="si">}</span><span class="s2">&quot;</span>
477
+ <span class="p">)</span>
478
+
479
+ <span class="c1"># Only check for type changes after initialization</span>
480
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialized</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
481
+ <span class="n">existing_value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
482
+ <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">existing_value</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
483
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
484
+ <span class="sa">f</span><span class="s2">&quot;Cannot change type of key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; from </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">existing_value</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2"> &quot;</span>
485
+ <span class="sa">f</span><span class="s2">&quot;to </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">&quot;</span>
486
+ <span class="p">)</span>
487
+
488
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
489
+
490
+ <span class="k">def</span><span class="w"> </span><span class="fm">__delitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
491
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Delete item from data dict.&quot;&quot;&quot;</span>
492
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialized</span><span class="p">:</span>
493
+ <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot delete key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; after initialization&quot;</span><span class="p">)</span>
494
+ <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
495
+
496
+ <span class="k">def</span><span class="w"> </span><span class="fm">__contains__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
497
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Check if key exists in data dict.&quot;&quot;&quot;</span>
498
+ <span class="k">return</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
499
+
500
+ <span class="k">def</span><span class="w"> </span><span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
501
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Iterate over keys in data dict.&quot;&quot;&quot;</span>
502
+ <span class="k">return</span> <span class="nb">iter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
503
+
504
+ <span class="k">def</span><span class="w"> </span><span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
505
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get number of items in data dict.&quot;&quot;&quot;</span>
506
+ <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
507
+
508
+ <div class="viewcode-block" id="DataSetMetadata.keys">
509
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.keys">[docs]</a>
510
+ <span class="k">def</span><span class="w"> </span><span class="nf">keys</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
511
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get keys from data dict.&quot;&quot;&quot;</span>
512
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span></div>
513
+
514
+
515
+ <div class="viewcode-block" id="DataSetMetadata.values">
516
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.values">[docs]</a>
517
+ <span class="k">def</span><span class="w"> </span><span class="nf">values</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
518
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get values from data dict.&quot;&quot;&quot;</span>
519
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">values</span><span class="p">()</span></div>
520
+
521
+
522
+ <div class="viewcode-block" id="DataSetMetadata.items">
523
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.items">[docs]</a>
524
+ <span class="k">def</span><span class="w"> </span><span class="nf">items</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
525
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get items from data dict.&quot;&quot;&quot;</span>
526
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">()</span></div>
527
+
528
+
529
+ <div class="viewcode-block" id="DataSetMetadata.get">
530
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.get">[docs]</a>
531
+ <span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
532
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get item from data dict with default.&quot;&quot;&quot;</span>
533
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span></div>
534
+
535
+
536
+ <div class="viewcode-block" id="DataSetMetadata.pop">
537
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.pop">[docs]</a>
538
+ <span class="k">def</span><span class="w"> </span><span class="nf">pop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
539
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Pop item from data dict.&quot;&quot;&quot;</span>
540
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialized</span><span class="p">:</span>
541
+ <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot pop key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; after initialization&quot;</span><span class="p">)</span>
542
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span></div>
543
+
544
+
545
+ <div class="viewcode-block" id="DataSetMetadata.popitem">
546
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.popitem">[docs]</a>
547
+ <span class="k">def</span><span class="w"> </span><span class="nf">popitem</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
548
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Pop item from data dict.&quot;&quot;&quot;</span>
549
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialized</span><span class="p">:</span>
550
+ <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="s2">&quot;Cannot pop items after initialization&quot;</span><span class="p">)</span>
551
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">popitem</span><span class="p">()</span></div>
552
+
553
+
554
+ <div class="viewcode-block" id="DataSetMetadata.clear">
555
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.clear">[docs]</a>
556
+ <span class="k">def</span><span class="w"> </span><span class="nf">clear</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
557
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Clear data dict.&quot;&quot;&quot;</span>
558
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialized</span><span class="p">:</span>
559
+ <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Cannot clear data after initialization&quot;</span><span class="p">)</span>
560
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span></div>
561
+
562
+
563
+ <div class="viewcode-block" id="DataSetMetadata.update">
564
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.update">[docs]</a>
565
+ <span class="k">def</span><span class="w"> </span><span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
566
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Update data dict with validation.&quot;&quot;&quot;</span>
567
+ <span class="c1"># Handle different update signatures</span>
568
+ <span class="k">if</span> <span class="n">args</span><span class="p">:</span>
569
+ <span class="n">other</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
570
+ <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="s2">&quot;items&quot;</span><span class="p">):</span>
571
+ <span class="n">items_to_update</span> <span class="o">=</span> <span class="n">other</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
572
+ <span class="k">else</span><span class="p">:</span>
573
+ <span class="n">items_to_update</span> <span class="o">=</span> <span class="n">other</span>
574
+ <span class="k">else</span><span class="p">:</span>
575
+ <span class="n">items_to_update</span> <span class="o">=</span> <span class="p">[]</span>
576
+
577
+ <span class="c1"># Combine with kwargs</span>
578
+ <span class="n">all_items</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">items_to_update</span><span class="p">)</span> <span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="n">kwargs</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
579
+
580
+ <span class="c1"># Validate all items before updating</span>
581
+ <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">all_items</span><span class="p">:</span>
582
+ <span class="c1"># Type validation (always required)</span>
583
+ <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">datetime</span><span class="p">)):</span>
584
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
585
+ <span class="sa">f</span><span class="s2">&quot;Value for key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; must be str, int, float, bool, or datetime, got </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">&quot;</span>
586
+ <span class="p">)</span>
587
+
588
+ <span class="c1"># Structural validation (only after initialization)</span>
589
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialized</span><span class="p">:</span>
590
+ <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
591
+ <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot add new key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; after initialization&quot;</span><span class="p">)</span>
592
+
593
+ <span class="n">existing_value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
594
+ <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">existing_value</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
595
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
596
+ <span class="sa">f</span><span class="s2">&quot;Cannot change type of key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; from </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">existing_value</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2"> &quot;</span>
597
+ <span class="sa">f</span><span class="s2">&quot;to </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">&quot;</span>
598
+ <span class="p">)</span>
599
+
600
+ <span class="c1"># If all validations pass, update the data</span>
601
+ <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">all_items</span><span class="p">:</span>
602
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span></div>
603
+
604
+
605
+ <div class="viewcode-block" id="DataSetMetadata.setdefault">
606
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.setdefault">[docs]</a>
607
+ <span class="k">def</span><span class="w"> </span><span class="nf">setdefault</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
608
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Set default value for key if not exists.&quot;&quot;&quot;</span>
609
+ <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
610
+ <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialized</span><span class="p">:</span>
611
+ <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot add new key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; after initialization&quot;</span><span class="p">)</span>
612
+
613
+ <span class="k">if</span> <span class="n">default</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span>
614
+ <span class="n">default</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">datetime</span><span class="p">)</span>
615
+ <span class="p">):</span>
616
+ <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
617
+ <span class="sa">f</span><span class="s2">&quot;Default value must be str, int, float, bool, or datetime, got </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">default</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">&quot;</span>
618
+ <span class="p">)</span>
619
+
620
+ <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">default</span>
621
+
622
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span></div>
623
+
624
+
625
+ <span class="c1"># Additional utility methods (no initialization checks needed)</span>
626
+ <div class="viewcode-block" id="DataSetMetadata.copy_data">
627
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.copy_data">[docs]</a>
628
+ <span class="k">def</span><span class="w"> </span><span class="nf">copy_data</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">datetime</span><span class="p">]]:</span>
629
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Return a copy of the data dict.&quot;&quot;&quot;</span>
630
+ <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span></div>
631
+
632
+
633
+ <div class="viewcode-block" id="DataSetMetadata.is_type_compatible">
634
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.is_type_compatible">[docs]</a>
635
+ <span class="k">def</span><span class="w"> </span><span class="nf">is_type_compatible</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
636
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Check if a value is type-compatible with existing key.&quot;&quot;&quot;</span>
637
+ <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
638
+ <span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">datetime</span><span class="p">))</span>
639
+ <span class="k">return</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">])</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span></div>
640
+
641
+
642
+ <div class="viewcode-block" id="DataSetMetadata.get_key_type">
643
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.get_key_type">[docs]</a>
644
+ <span class="k">def</span><span class="w"> </span><span class="nf">get_key_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">type</span><span class="p">:</span>
645
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get the type of a specific key.&quot;&quot;&quot;</span>
646
+ <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
647
+ <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; not found&quot;</span><span class="p">)</span>
648
+ <span class="k">return</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">])</span></div>
649
+
650
+
651
+ <div class="viewcode-block" id="DataSetMetadata.get_schema_for_key">
652
+ <a class="viewcode-back" href="../../../simstack/modules/simstack.models.html#simstack.models.dataset_metadata.DataSetMetadata.get_schema_for_key">[docs]</a>
653
+ <span class="k">def</span><span class="w"> </span><span class="nf">get_schema_for_key</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
654
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get JSON schema for a specific key.&quot;&quot;&quot;</span>
655
+ <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
656
+ <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Key &#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; not found&quot;</span><span class="p">)</span>
657
+
658
+ <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
659
+ <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
660
+ <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;string&quot;</span><span class="p">}</span>
661
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">bool</span><span class="p">):</span>
662
+ <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;boolean&quot;</span><span class="p">}</span>
663
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
664
+ <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;integer&quot;</span><span class="p">}</span>
665
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
666
+ <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;number&quot;</span><span class="p">}</span>
667
+ <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="p">):</span>
668
+ <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;string&quot;</span><span class="p">,</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span> <span class="s2">&quot;date-time&quot;</span><span class="p">}</span>
669
+ <span class="k">else</span><span class="p">:</span>
670
+ <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;string&quot;</span><span class="p">}</span></div>
671
+ </div>
672
+
673
+ </pre></div>
674
+ </article>
675
+ </div>
676
+ <footer>
677
+
678
+ <div class="related-pages">
679
+
680
+
681
+ </div>
682
+ <div class="bottom-of-page">
683
+ <div class="left-details">
684
+ <div class="copyright">
685
+ Copyright &#169; 2026, Wolfgang Wenzel
686
+ </div>
687
+ Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
688
+
689
+ <a href="https://github.com/pradyunsg/furo">Furo</a>
690
+
691
+ </div>
692
+ <div class="right-details">
693
+
694
+ </div>
695
+ </div>
696
+
697
+ </footer>
698
+ </div>
699
+ <aside class="toc-drawer no-toc">
700
+
701
+
702
+
703
+ </aside>
704
+ </div>
705
+ </div><script src="../../../_static/documentation_options.js?v=5929fcd5"></script>
706
+ <script src="../../../_static/doctools.js?v=fd6eb6e6"></script>
707
+ <script src="../../../_static/sphinx_highlight.js?v=6ffebe34"></script>
708
+ <script src="../../../_static/scripts/furo.js?v=46bd48cc"></script>
709
+ <script data-docs-built-at="2026-07-17 10:50:10 UTC" src="../../../_static/docs-build-badge.js?v=57cb9fc6"></script>
710
+ </body>
711
+ </html>