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.
- simstack/__init__.py +0 -0
- simstack/_version.py +24 -0
- simstack/core/__init__.py +0 -0
- simstack/core/artifacts.py +406 -0
- simstack/core/asnyc_helper.py +14 -0
- simstack/core/config_file.py +60 -0
- simstack/core/context.py +283 -0
- simstack/core/definitions.py +22 -0
- simstack/core/engine.py +115 -0
- simstack/core/find_simstack_modules.py +41 -0
- simstack/core/hash.py +179 -0
- simstack/core/node.py +1137 -0
- simstack/core/node_claim.py +31 -0
- simstack/core/node_runner.py +362 -0
- simstack/core/process_results.py +102 -0
- simstack/core/recompute_artifacts.py +117 -0
- simstack/core/reset_db.py +12 -0
- simstack/core/resource_assignment.py +222 -0
- simstack/core/resources.py +90 -0
- simstack/core/route_table.py +24 -0
- simstack/core/run_docker.py +109 -0
- simstack/core/run_node.py +71 -0
- simstack/core/runner.py +169 -0
- simstack/core/services/__init__.py +11 -0
- simstack/core/services/base_service.py +191 -0
- simstack/core/services/file_transfer_service.py +117 -0
- simstack/core/services/git_restart_service.py +12 -0
- simstack/core/services/git_uv_update_service.py +105 -0
- simstack/core/services/node_execution_service.py +182 -0
- simstack/core/services/resource_branch_monitor_service.py +71 -0
- simstack/core/services/runner_cleanup_service.py +149 -0
- simstack/core/services/runner_manager.py +163 -0
- simstack/core/services/runner_status_service.py +10 -0
- simstack/core/services/slurm_status_service.py +67 -0
- simstack/core/services/stop_check_service.py +27 -0
- simstack/core/services/timeout_restart_service.py +26 -0
- simstack/core/simstack_result.py +39 -0
- simstack/core/submit_node.py +217 -0
- simstack/core/task_id.py +22 -0
- simstack/methods/__init__.py +0 -0
- simstack/methods/archive_files.py +292 -0
- simstack/methods/fire_and_forget_runner.py +113 -0
- simstack/methods/generate_test.py +125 -0
- simstack/methods/get_file.py +26 -0
- simstack/methods/mass_runner.py +154 -0
- simstack/methods/multiple_executor.py +307 -0
- simstack/methods/switch_git.py +16 -0
- simstack/methods/upload_helpers.py +81 -0
- simstack/models/__init__.py +74 -0
- simstack/models/array_list.py +21 -0
- simstack/models/array_storage.py +83 -0
- simstack/models/artifact_models.py +127 -0
- simstack/models/base_lists.py +51 -0
- simstack/models/base_types.py +209 -0
- simstack/models/charts_artifact.py +690 -0
- simstack/models/dataset.py +451 -0
- simstack/models/dataset_metadata.py +390 -0
- simstack/models/datasettuple.py +587 -0
- simstack/models/file_instance.py +150 -0
- simstack/models/file_list.py +45 -0
- simstack/models/files.py +424 -0
- simstack/models/fire_and_forget_result.py +19 -0
- simstack/models/images2d.py +113 -0
- simstack/models/log_entry_model.py +37 -0
- simstack/models/models.py +52 -0
- simstack/models/named_data_reference.py +36 -0
- simstack/models/node_registry.py +96 -0
- simstack/models/pandas_model.py +239 -0
- simstack/models/parameters.py +402 -0
- simstack/models/pickle_models.py +300 -0
- simstack/models/project.py +13 -0
- simstack/models/resource_assignment.py +170 -0
- simstack/models/resource_definition.py +125 -0
- simstack/models/runner_model.py +39 -0
- simstack/models/simple_table.py +79 -0
- simstack/models/simstack_model.py +97 -0
- simstack/models/slurm_info.py +17 -0
- simstack/models/table_artifact.py +87 -0
- simstack/models/tag.py +12 -0
- simstack/models/unused_test_file.py +5 -0
- simstack/simstack_marker.com +1 -0
- simstack/static/docs/.buildinfo +4 -0
- simstack/static/docs/_images/GUI Concept.webp +0 -0
- simstack/static/docs/_modules/index.html +434 -0
- simstack/static/docs/_modules/simstack/core/artifacts.html +743 -0
- simstack/static/docs/_modules/simstack/core/asnyc_helper.html +330 -0
- simstack/static/docs/_modules/simstack/core/config_file.html +379 -0
- simstack/static/docs/_modules/simstack/core/definitions.html +341 -0
- simstack/static/docs/_modules/simstack/core/engine.html +437 -0
- simstack/static/docs/_modules/simstack/core/find_simstack_modules.html +360 -0
- simstack/static/docs/_modules/simstack/core/hash.html +528 -0
- simstack/static/docs/_modules/simstack/core/node.html +1392 -0
- simstack/static/docs/_modules/simstack/core/node_claim.html +347 -0
- simstack/static/docs/_modules/simstack/core/node_runner.html +711 -0
- simstack/static/docs/_modules/simstack/core/process_results.html +418 -0
- simstack/static/docs/_modules/simstack/core/recompute_artifacts.html +433 -0
- simstack/static/docs/_modules/simstack/core/reset_db.html +328 -0
- simstack/static/docs/_modules/simstack/core/resource_assignment.html +553 -0
- simstack/static/docs/_modules/simstack/core/resources.html +424 -0
- simstack/static/docs/_modules/simstack/core/route_table.html +349 -0
- simstack/static/docs/_modules/simstack/core/run_docker.html +425 -0
- simstack/static/docs/_modules/simstack/core/run_node.html +390 -0
- simstack/static/docs/_modules/simstack/core/runner.html +491 -0
- simstack/static/docs/_modules/simstack/core/services/base_service.html +522 -0
- simstack/static/docs/_modules/simstack/core/services/file_transfer_service.html +436 -0
- simstack/static/docs/_modules/simstack/core/services/git_restart_service.html +331 -0
- simstack/static/docs/_modules/simstack/core/services/git_uv_update_service.html +427 -0
- simstack/static/docs/_modules/simstack/core/services/node_execution_service.html +507 -0
- simstack/static/docs/_modules/simstack/core/services/resource_branch_monitor_service.html +390 -0
- simstack/static/docs/_modules/simstack/core/services/runner_cleanup_service.html +468 -0
- simstack/static/docs/_modules/simstack/core/services/runner_manager.html +485 -0
- simstack/static/docs/_modules/simstack/core/services/runner_status_service.html +329 -0
- simstack/static/docs/_modules/simstack/core/services/slurm_status_service.html +386 -0
- simstack/static/docs/_modules/simstack/core/services/stop_check_service.html +346 -0
- simstack/static/docs/_modules/simstack/core/services/timeout_restart_service.html +345 -0
- simstack/static/docs/_modules/simstack/core/simstack_result.html +355 -0
- simstack/static/docs/_modules/simstack/core/submit_node.html +536 -0
- simstack/static/docs/_modules/simstack/core/task_id.html +344 -0
- simstack/static/docs/_modules/simstack/methods/archive_files.html +598 -0
- simstack/static/docs/_modules/simstack/methods/fire_and_forget_runner.html +432 -0
- simstack/static/docs/_modules/simstack/methods/generate_test.html +443 -0
- simstack/static/docs/_modules/simstack/methods/get_file.html +342 -0
- simstack/static/docs/_modules/simstack/methods/mass_runner.html +476 -0
- simstack/static/docs/_modules/simstack/methods/multiple_executor.html +674 -0
- simstack/static/docs/_modules/simstack/methods/switch_git.html +332 -0
- simstack/static/docs/_modules/simstack/methods/upload_helpers.html +403 -0
- simstack/static/docs/_modules/simstack/models/array_list.html +337 -0
- simstack/static/docs/_modules/simstack/models/array_storage.html +417 -0
- simstack/static/docs/_modules/simstack/models/base_lists.html +374 -0
- simstack/static/docs/_modules/simstack/models/base_types.html +588 -0
- simstack/static/docs/_modules/simstack/models/charts_artifact.html +1035 -0
- simstack/static/docs/_modules/simstack/models/dataset.html +866 -0
- simstack/static/docs/_modules/simstack/models/dataset_metadata.html +711 -0
- simstack/static/docs/_modules/simstack/models/datasettuple.html +1005 -0
- simstack/static/docs/_modules/simstack/models/file_instance.html +472 -0
- simstack/static/docs/_modules/simstack/models/file_list.html +367 -0
- simstack/static/docs/_modules/simstack/models/files.html +773 -0
- simstack/static/docs/_modules/simstack/models/fire_and_forget_result.html +335 -0
- simstack/static/docs/_modules/simstack/models/images2d.html +447 -0
- simstack/static/docs/_modules/simstack/models/log_entry_model.html +356 -0
- simstack/static/docs/_modules/simstack/models/models.html +374 -0
- simstack/static/docs/_modules/simstack/models/named_data_reference.html +355 -0
- simstack/static/docs/_modules/simstack/models/node_registry.html +415 -0
- simstack/static/docs/_modules/simstack/models/pandas_model.html +570 -0
- simstack/static/docs/_modules/simstack/models/parameters.html +739 -0
- simstack/static/docs/_modules/simstack/models/pickle_models.html +631 -0
- simstack/static/docs/_modules/simstack/models/project.html +329 -0
- simstack/static/docs/_modules/simstack/models/resource_assignment.html +501 -0
- simstack/static/docs/_modules/simstack/models/resource_definition.html +477 -0
- simstack/static/docs/_modules/simstack/models/runner_model.html +361 -0
- simstack/static/docs/_modules/simstack/models/simple_table.html +413 -0
- simstack/static/docs/_modules/simstack/models/simstack_model.html +416 -0
- simstack/static/docs/_modules/simstack/models/slurm_info.html +333 -0
- simstack/static/docs/_modules/simstack/models/table_artifact.html +406 -0
- simstack/static/docs/_modules/simstack/models/tag.html +328 -0
- simstack/static/docs/_modules/simstack/tables/model_table.html +519 -0
- simstack/static/docs/_modules/simstack/tables/node_children.html +538 -0
- simstack/static/docs/_modules/simstack/tables/node_table.html +854 -0
- simstack/static/docs/_modules/simstack/tables/table_builder.html +642 -0
- simstack/static/docs/_modules/simstack/util/async_zip_utils.html +337 -0
- simstack/static/docs/_modules/simstack/util/b64mixin.html +339 -0
- simstack/static/docs/_modules/simstack/util/cleaned_json_schema.html +336 -0
- simstack/static/docs/_modules/simstack/util/config_reader.html +498 -0
- simstack/static/docs/_modules/simstack/util/custom_model_dump.html +391 -0
- simstack/static/docs/_modules/simstack/util/database_information.html +488 -0
- simstack/static/docs/_modules/simstack/util/db.html +1392 -0
- simstack/static/docs/_modules/simstack/util/db_logger.html +448 -0
- simstack/static/docs/_modules/simstack/util/default_from_dict.html +376 -0
- simstack/static/docs/_modules/simstack/util/directory_iterator.html +553 -0
- simstack/static/docs/_modules/simstack/util/docstring_parser.html +526 -0
- simstack/static/docs/_modules/simstack/util/file_hashing.html +394 -0
- simstack/static/docs/_modules/simstack/util/file_transfer_client.html +791 -0
- simstack/static/docs/_modules/simstack/util/files.html +733 -0
- simstack/static/docs/_modules/simstack/util/find_python_files.html +349 -0
- simstack/static/docs/_modules/simstack/util/generate_ui_schema.html +396 -0
- simstack/static/docs/_modules/simstack/util/generic_list_mixin.html +487 -0
- simstack/static/docs/_modules/simstack/util/get_module_path.html +336 -0
- simstack/static/docs/_modules/simstack/util/git_pull.html +381 -0
- simstack/static/docs/_modules/simstack/util/git_repository_status.html +411 -0
- simstack/static/docs/_modules/simstack/util/import_module.html +377 -0
- simstack/static/docs/_modules/simstack/util/importer.html +637 -0
- simstack/static/docs/_modules/simstack/util/init_data_source.html +357 -0
- simstack/static/docs/_modules/simstack/util/make_graph.html +423 -0
- simstack/static/docs/_modules/simstack/util/make_table.html +1171 -0
- simstack/static/docs/_modules/simstack/util/mappings.html +378 -0
- simstack/static/docs/_modules/simstack/util/minimal_route_finder.html +388 -0
- simstack/static/docs/_modules/simstack/util/mock_db.html +472 -0
- simstack/static/docs/_modules/simstack/util/module_path_checker.html +354 -0
- simstack/static/docs/_modules/simstack/util/object_list_mixin.html +649 -0
- simstack/static/docs/_modules/simstack/util/path_manager.html +566 -0
- simstack/static/docs/_modules/simstack/util/project_root_finder.html +357 -0
- simstack/static/docs/_modules/simstack/util/queue_watcher.html +593 -0
- simstack/static/docs/_modules/simstack/util/resource_config.html +532 -0
- simstack/static/docs/_modules/simstack/util/route_finder.html +390 -0
- simstack/static/docs/_modules/simstack/util/runner_util.html +487 -0
- simstack/static/docs/_modules/simstack/util/runner_utils.html +468 -0
- simstack/static/docs/_modules/simstack/util/safe_code_executor.html +510 -0
- simstack/static/docs/_modules/simstack/util/sample_config.html +414 -0
- simstack/static/docs/_modules/simstack/util/sensitive_content_filter.html +364 -0
- simstack/static/docs/_modules/simstack/util/setup_logging.html +365 -0
- simstack/static/docs/_modules/simstack/util/submit_to_watchdog.html +425 -0
- simstack/static/docs/_modules/simstack/util/toml_reader.html +482 -0
- simstack/static/docs/_modules/simstack/util/transform_file_name.html +357 -0
- simstack/static/docs/_modules/simstack/util/ui_tools.html +541 -0
- simstack/static/docs/_sources/architecture.rst.txt +25 -0
- simstack/static/docs/_sources/array_lists.rst.txt +60 -0
- simstack/static/docs/_sources/ci_pipeline.rst.txt +34 -0
- simstack/static/docs/_sources/data.rst.txt +175 -0
- simstack/static/docs/_sources/database_migrations.rst.txt +310 -0
- simstack/static/docs/_sources/datasets.rst.txt +93 -0
- simstack/static/docs/_sources/developer_guide.rst.txt +25 -0
- simstack/static/docs/_sources/docker_nodes.rst.txt +149 -0
- simstack/static/docs/_sources/files.rst.txt +159 -0
- simstack/static/docs/_sources/fire_and_forget_runner.rst.txt +67 -0
- simstack/static/docs/_sources/index.rst.txt +25 -0
- simstack/static/docs/_sources/installation.rst.txt +213 -0
- simstack/static/docs/_sources/lists.rst.txt +111 -0
- simstack/static/docs/_sources/mass_runner.rst.txt +91 -0
- simstack/static/docs/_sources/misc.rst.txt +106 -0
- simstack/static/docs/_sources/overview.rst.txt +91 -0
- simstack/static/docs/_sources/recovery.rst.txt +38 -0
- simstack/static/docs/_sources/resource_config.rst.txt +141 -0
- simstack/static/docs/_sources/simstack/modules/modules.rst.txt +7 -0
- simstack/static/docs/_sources/simstack/modules/simstack.core.rst.txt +205 -0
- simstack/static/docs/_sources/simstack/modules/simstack.core.services.rst.txt +109 -0
- simstack/static/docs/_sources/simstack/modules/simstack.methods.rst.txt +77 -0
- simstack/static/docs/_sources/simstack/modules/simstack.models.rst.txt +261 -0
- simstack/static/docs/_sources/simstack/modules/simstack.rst.txt +22 -0
- simstack/static/docs/_sources/simstack/modules/simstack.tables.rst.txt +45 -0
- simstack/static/docs/_sources/simstack/modules/simstack.util.rst.txt +381 -0
- simstack/static/docs/_sources/submit.rst.txt +141 -0
- simstack/static/docs/_sources/tables.rst.txt +50 -0
- simstack/static/docs/_sources/testing_complex_nodes.rst.txt +92 -0
- simstack/static/docs/_sources/ui_documentation.rst.txt +272 -0
- simstack/static/docs/_sources/workflows.rst.txt +446 -0
- simstack/static/docs/_static/base-stemmer.js +476 -0
- simstack/static/docs/_static/basic.css +906 -0
- simstack/static/docs/_static/cobalt2-theme.css +1 -0
- simstack/static/docs/_static/debug.css +69 -0
- simstack/static/docs/_static/docs-build-badge.css +51 -0
- simstack/static/docs/_static/docs-build-badge.js +51 -0
- simstack/static/docs/_static/doctools.js +150 -0
- simstack/static/docs/_static/documentation_options.js +13 -0
- simstack/static/docs/_static/english-stemmer.js +1066 -0
- simstack/static/docs/_static/file.png +0 -0
- simstack/static/docs/_static/language_data.js +13 -0
- simstack/static/docs/_static/minus.png +0 -0
- simstack/static/docs/_static/plus.png +0 -0
- simstack/static/docs/_static/pygments.css +250 -0
- simstack/static/docs/_static/scripts/furo-extensions.js +0 -0
- simstack/static/docs/_static/scripts/furo.js +3 -0
- simstack/static/docs/_static/scripts/furo.js.LICENSE.txt +7 -0
- simstack/static/docs/_static/scripts/furo.js.map +1 -0
- simstack/static/docs/_static/searchtools.js +693 -0
- simstack/static/docs/_static/skeleton.css +296 -0
- simstack/static/docs/_static/sphinx_highlight.js +159 -0
- simstack/static/docs/_static/styles/furo-extensions.css +2 -0
- simstack/static/docs/_static/styles/furo-extensions.css.map +1 -0
- simstack/static/docs/_static/styles/furo.css +2 -0
- simstack/static/docs/_static/styles/furo.css.map +1 -0
- simstack/static/docs/architecture.html +340 -0
- simstack/static/docs/array_lists.html +678 -0
- simstack/static/docs/ci_pipeline.html +385 -0
- simstack/static/docs/data.html +545 -0
- simstack/static/docs/database_migrations.html +652 -0
- simstack/static/docs/datasets.html +1268 -0
- simstack/static/docs/developer_guide.html +359 -0
- simstack/static/docs/docker_nodes.html +503 -0
- simstack/static/docs/files.html +718 -0
- simstack/static/docs/fire_and_forget_runner.html +641 -0
- simstack/static/docs/genindex.html +6390 -0
- simstack/static/docs/index.html +516 -0
- simstack/static/docs/installation.html +553 -0
- simstack/static/docs/lists.html +478 -0
- simstack/static/docs/mass_runner.html +481 -0
- simstack/static/docs/misc.html +454 -0
- simstack/static/docs/objects.inv +0 -0
- simstack/static/docs/overview.html +469 -0
- simstack/static/docs/py-modindex.html +1111 -0
- simstack/static/docs/recovery.html +371 -0
- simstack/static/docs/resource_config.html +590 -0
- simstack/static/docs/search.html +327 -0
- simstack/static/docs/searchindex.js +1 -0
- simstack/static/docs/simstack/modules/modules.html +489 -0
- simstack/static/docs/simstack/modules/simstack.core.html +1883 -0
- simstack/static/docs/simstack/modules/simstack.core.services.html +698 -0
- simstack/static/docs/simstack/modules/simstack.html +3060 -0
- simstack/static/docs/simstack/modules/simstack.methods.html +1150 -0
- simstack/static/docs/simstack/modules/simstack.models.html +13113 -0
- simstack/static/docs/simstack/modules/simstack.tables.html +635 -0
- simstack/static/docs/simstack/modules/simstack.util.html +3320 -0
- simstack/static/docs/submit.html +487 -0
- simstack/static/docs/tables.html +539 -0
- simstack/static/docs/testing_complex_nodes.html +458 -0
- simstack/static/docs/ui_documentation.html +788 -0
- simstack/static/docs/workflows.html +766 -0
- simstack/tables/__init__.py +0 -0
- simstack/tables/model_table.py +191 -0
- simstack/tables/node_children.py +219 -0
- simstack/tables/node_table.py +517 -0
- simstack/tables/table_builder.py +314 -0
- simstack/util/__init__.py +0 -0
- simstack/util/async_zip_utils.py +18 -0
- simstack/util/b64mixin.py +23 -0
- simstack/util/cleaned_json_schema.py +20 -0
- simstack/util/config_reader.py +179 -0
- simstack/util/custom_model_dump.py +75 -0
- simstack/util/database_information.py +160 -0
- simstack/util/db.py +1013 -0
- simstack/util/db_logger.py +117 -0
- simstack/util/default_from_dict.py +57 -0
- simstack/util/directory_iterator.py +216 -0
- simstack/util/docstring_parser.py +186 -0
- simstack/util/file_hashing.py +72 -0
- simstack/util/file_transfer_client.py +427 -0
- simstack/util/files.py +396 -0
- simstack/util/find_python_files.py +33 -0
- simstack/util/generate_ui_schema.py +80 -0
- simstack/util/generic_list_mixin.py +120 -0
- simstack/util/geometry_utils.py +118 -0
- simstack/util/get_module_path.py +20 -0
- simstack/util/git_pull.py +65 -0
- simstack/util/git_repository_status.py +95 -0
- simstack/util/import_module.py +63 -0
- simstack/util/importer.py +312 -0
- simstack/util/init_data_source.py +41 -0
- simstack/util/make_graph.py +107 -0
- simstack/util/make_table.py +837 -0
- simstack/util/mappings.py +41 -0
- simstack/util/minimal_route_finder.py +72 -0
- simstack/util/mock_db.py +144 -0
- simstack/util/module_path_checker.py +38 -0
- simstack/util/object_list_mixin.py +282 -0
- simstack/util/path_manager.py +223 -0
- simstack/util/project_root_finder.py +41 -0
- simstack/util/queue_watcher.py +262 -0
- simstack/util/resource_config.py +198 -0
- simstack/util/route_finder.py +74 -0
- simstack/util/runner_util.py +166 -0
- simstack/util/runner_utils.py +143 -0
- simstack/util/safe_code_executor.py +194 -0
- simstack/util/sample_config.py +98 -0
- simstack/util/sensitive_content_filter.py +48 -0
- simstack/util/setup_logging.py +49 -0
- simstack/util/submit_to_watchdog.py +106 -0
- simstack/util/toml_reader.py +142 -0
- simstack/util/transform_file_name.py +41 -0
- simstack/util/ui_tools.py +213 -0
- simstack-2.0.1.dist-info/METADATA +454 -0
- simstack-2.0.1.dist-info/RECORD +354 -0
- simstack-2.0.1.dist-info/WHEEL +5 -0
- simstack-2.0.1.dist-info/entry_points.txt +12 -0
- simstack-2.0.1.dist-info/licenses/LICENSE +21 -0
- simstack-2.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
.. _array_lists:
|
|
2
|
+
|
|
3
|
+
Array Lists
|
|
4
|
+
===========
|
|
5
|
+
|
|
6
|
+
SimStack II provides a specialized way to handle collections of arrays (typically numpy arrays) through the ``ArrayList`` and ``ArrayStorage`` models.
|
|
7
|
+
|
|
8
|
+
ArrayStorage
|
|
9
|
+
------------
|
|
10
|
+
|
|
11
|
+
``ArrayStorage`` is the model used to store an individual array. It handles compression and serialization of the array data.
|
|
12
|
+
|
|
13
|
+
**Key Features:**
|
|
14
|
+
|
|
15
|
+
* **Compression**: Array data is automatically compressed before being stored in the database.
|
|
16
|
+
* **Shape Preservation**: Automatically stores and restores the shape of the array.
|
|
17
|
+
* **Property Access**: Use the ``array`` property to get or set the numpy array directly.
|
|
18
|
+
|
|
19
|
+
**Usage:**
|
|
20
|
+
|
|
21
|
+
.. code-block:: python
|
|
22
|
+
|
|
23
|
+
import numpy as np
|
|
24
|
+
from simstack.models.array_storage import ArrayStorage
|
|
25
|
+
|
|
26
|
+
storage = ArrayStorage(name="my_array")
|
|
27
|
+
storage.array = np.random.rand(10, 10)
|
|
28
|
+
|
|
29
|
+
ArrayList
|
|
30
|
+
---------
|
|
31
|
+
|
|
32
|
+
``ArrayList`` is a top-level ``Model`` that stores a collection of ``ArrayStorage`` objects. Like ``FileListModel``, it inherits from ``ObjectListMixin``, providing a familiar list-like interface.
|
|
33
|
+
|
|
34
|
+
**Usage:**
|
|
35
|
+
|
|
36
|
+
.. code-block:: python
|
|
37
|
+
|
|
38
|
+
from simstack.models.array_list import ArrayList
|
|
39
|
+
from simstack.models.array_storage import ArrayStorage
|
|
40
|
+
import numpy as np
|
|
41
|
+
|
|
42
|
+
array_list = ArrayList()
|
|
43
|
+
|
|
44
|
+
storage = ArrayStorage(name="first")
|
|
45
|
+
storage.array = np.zeros((5, 5))
|
|
46
|
+
|
|
47
|
+
array_list.append(storage)
|
|
48
|
+
|
|
49
|
+
API Reference
|
|
50
|
+
-------------
|
|
51
|
+
|
|
52
|
+
.. autoclass:: simstack.models.array_list.ArrayList
|
|
53
|
+
:members:
|
|
54
|
+
:undoc-members:
|
|
55
|
+
:show-inheritance:
|
|
56
|
+
|
|
57
|
+
.. autoclass:: simstack.models.array_storage.ArrayStorage
|
|
58
|
+
:members:
|
|
59
|
+
:undoc-members:
|
|
60
|
+
:show-inheritance:
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
.. _ci_pipeline:
|
|
2
|
+
|
|
3
|
+
CI Pipeline and Documentation Artifacts
|
|
4
|
+
=======================================
|
|
5
|
+
|
|
6
|
+
The SimStack II project uses GitHub Actions for Continuous Integration. One of the jobs in the pipeline is ``package-html-docs``, which automatically generates the API documentation and builds the Sphinx HTML documentation for the installed package.
|
|
7
|
+
|
|
8
|
+
Where the HTML documentation lives
|
|
9
|
+
----------------------------------
|
|
10
|
+
|
|
11
|
+
The generated HTML documentation is owned by the ``simstack`` package and is stored under:
|
|
12
|
+
|
|
13
|
+
.. code-block:: text
|
|
14
|
+
|
|
15
|
+
src/simstack/static/docs
|
|
16
|
+
|
|
17
|
+
This directory is included as package data. Any application that installs ``simstack`` can serve the generated HTML from the installed package instead of rebuilding or copying documentation from this repository.
|
|
18
|
+
|
|
19
|
+
How the CI job updates docs
|
|
20
|
+
---------------------------
|
|
21
|
+
|
|
22
|
+
On branch pushes and manual workflow runs, the ``package-html-docs`` job:
|
|
23
|
+
|
|
24
|
+
1. Runs ``sphinx-apidoc`` to refresh generated API documentation sources.
|
|
25
|
+
2. Builds Sphinx HTML into ``src/simstack/static/docs``.
|
|
26
|
+
3. Uploads the generated HTML as the ``sphinx-docs`` artifact for inspection.
|
|
27
|
+
4. Commits changed generated HTML back to the same branch.
|
|
28
|
+
|
|
29
|
+
The auto-commit message contains ``[skip ci]`` so the generated-docs commit does not start another CI run.
|
|
30
|
+
|
|
31
|
+
How other projects should consume docs
|
|
32
|
+
--------------------------------------
|
|
33
|
+
|
|
34
|
+
Other projects should not download CI artifacts or rebuild these docs. They should install the desired ``simstack`` revision and use/serve ``simstack/static/docs`` from the installed package.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
.. _persisting_data:
|
|
2
|
+
|
|
3
|
+
Persisting and Visualizing Data
|
|
4
|
+
===============================
|
|
5
|
+
|
|
6
|
+
.. note::
|
|
7
|
+
This section is intended for node-developers.
|
|
8
|
+
|
|
9
|
+
Simstack persists data using a MongoDB database, which is exposed via the
|
|
10
|
+
fast-api server to a web-frontend. Each user has a dedicated database
|
|
11
|
+
on a MongoDB server which is configured in the configuration file
|
|
12
|
+
(:ref:`configuration-file`).
|
|
13
|
+
|
|
14
|
+
To facilitate access to the database in the python workflows, Simstack II uses the odmantic
|
|
15
|
+
package to provide an object-oriented access to the data via odmantic
|
|
16
|
+
Models. Odmantic Models are drived from pydantic (V2) classes and developers
|
|
17
|
+
of nodes (:ref:`workflows`) can define their own classes deriving from Model.
|
|
18
|
+
|
|
19
|
+
To customize the appearance of the models in the UI, the model definition
|
|
20
|
+
should be decorated by ``@simstack_model``
|
|
21
|
+
(:func:`simstack.core.simstack_model.simstack_model`)
|
|
22
|
+
which provides ui-related functionality discussed below
|
|
23
|
+
(:ref:`model-appearance`)
|
|
24
|
+
|
|
25
|
+
Model Definitions
|
|
26
|
+
~~~~~~~~~~~~~~~~~~
|
|
27
|
+
|
|
28
|
+
For detailed information on odmantic models, consult the odmantic
|
|
29
|
+
documentation.
|
|
30
|
+
|
|
31
|
+
A basic model definition look like:
|
|
32
|
+
|
|
33
|
+
.. code-block:: python
|
|
34
|
+
|
|
35
|
+
from typing import Optional, List
|
|
36
|
+
from odmantic import Model, EmbeddedModel, Field
|
|
37
|
+
|
|
38
|
+
@simstack_model
|
|
39
|
+
class OtherModel(Model):
|
|
40
|
+
observations: List[float]
|
|
41
|
+
max: float
|
|
42
|
+
|
|
43
|
+
@simstack_model
|
|
44
|
+
class SmallData(EmbeddedModel)
|
|
45
|
+
number: int
|
|
46
|
+
|
|
47
|
+
@simstack_model
|
|
48
|
+
class ComplexData(Model)
|
|
49
|
+
counter: int = Field(default=1)
|
|
50
|
+
limit: Optional[int] = None
|
|
51
|
+
other_model: OtherModel = Reference() # this defines a reference to the
|
|
52
|
+
# other table in the db
|
|
53
|
+
# loading ComplexData will load
|
|
54
|
+
# the other model too
|
|
55
|
+
small_data: SmallData # directly stored in the complex_data table
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
.. important::
|
|
60
|
+
- The node developer does not have explicitly save models to the db, the
|
|
61
|
+
@node decorator will take care of this.
|
|
62
|
+
- There is **no Model inheritance**, which is a real pain.
|
|
63
|
+
- ODMantic Issue #484: https://github.com/art049/odmantic/issues/484
|
|
64
|
+
|
|
65
|
+
.. note::
|
|
66
|
+
Even though its formally allowed do not use Dict[str,Any] in models,
|
|
67
|
+
because the UI behavior is unpredictable (see below).
|
|
68
|
+
Dict[str,known_type] is ok.
|
|
69
|
+
|
|
70
|
+
**Standard Models**
|
|
71
|
+
|
|
72
|
+
:mod:`simstack.models.base_types` provides basic models:
|
|
73
|
+
|
|
74
|
+
- IntData
|
|
75
|
+
- StrData
|
|
76
|
+
- FloatData
|
|
77
|
+
- BooleanData
|
|
78
|
+
|
|
79
|
+
And :mod:`simstack.models.array_storage`:
|
|
80
|
+
|
|
81
|
+
- ArrayStorage
|
|
82
|
+
- ArrayList
|
|
83
|
+
|
|
84
|
+
And the list mixins for creating custom list models (see :doc:`lists`):
|
|
85
|
+
|
|
86
|
+
- GenericListMixin
|
|
87
|
+
- ObjectListMixin
|
|
88
|
+
|
|
89
|
+
And for file management (see :doc:`files`):
|
|
90
|
+
|
|
91
|
+
- FileStack
|
|
92
|
+
- FileList
|
|
93
|
+
- FileListModel
|
|
94
|
+
|
|
95
|
+
And the parallel execution utilities (see :doc:`mass_runner` and :doc:`fire_and_forget_runner`):
|
|
96
|
+
|
|
97
|
+
- MassRunner
|
|
98
|
+
- FireAndForgetRunner
|
|
99
|
+
|
|
100
|
+
:class:`simstack.models.array_storage.ArrayStorage` is an example of a class which
|
|
101
|
+
packs its content by serializing and deserializing it. This is the
|
|
102
|
+
recommended procedure for all content which MongoDB cannot natively store. To
|
|
103
|
+
interact with such classes, the developer has to provide access functions and
|
|
104
|
+
a member function ``custom_model_dump`` which the fast-api server to convert
|
|
105
|
+
the content of the class into a dict which can be visualized in the GUI.
|
|
106
|
+
|
|
107
|
+
.. _model-appearance:
|
|
108
|
+
|
|
109
|
+
Model Appearance in the GUI
|
|
110
|
+
---------------------------
|
|
111
|
+
|
|
112
|
+
The :class:`simstack.models.models.ModelTable` table in the database stores
|
|
113
|
+
for each class a json-schema (derived from the pydantic json-schema) and a
|
|
114
|
+
``ui_scheme`` which is created by
|
|
115
|
+
:func:`simstack.core.model_table.make_model_table`.
|
|
116
|
+
|
|
117
|
+
The UI used a package react-json-forms (rjsf) to interpret these schema to
|
|
118
|
+
provide input and output representations of the model. When queried the
|
|
119
|
+
routes of the fast-api server provide (get) or store (post) dicts that are
|
|
120
|
+
compatible with the json-schema. 8
|
|
121
|
+
|
|
122
|
+
**Class Methods**
|
|
123
|
+
|
|
124
|
+
+---------------+-------------------------------------+------------------+
|
|
125
|
+
| Function Name | Purpose | default |
|
|
126
|
+
+---------------+-------------------------------------+------------------+
|
|
127
|
+
| json_schema | json schema for rjsf | pydantic-schema |
|
|
128
|
+
+---------------+-------------------------------------+------------------+
|
|
129
|
+
| ui_schema | ui_schema dict for rjsf | hide id |
|
|
130
|
+
+---------------+-------------------------------------+------------------+
|
|
131
|
+
| ui_make_title | title for the model in ui | class name |
|
|
132
|
+
+---------------+-------------------------------------+------------------+
|
|
133
|
+
| from_dict | create model instance from dict | odmantic func |
|
|
134
|
+
+---------------+-------------------------------------+------------------+
|
|
135
|
+
| from_model | copy constructor | odmantic default |
|
|
136
|
+
+---------------+-------------------------------------+------------------+
|
|
137
|
+
|
|
138
|
+
**Instance Functions**
|
|
139
|
+
|
|
140
|
+
+-------------------+--------------------------------+------------------+
|
|
141
|
+
| Function Name | Purpose | default |
|
|
142
|
+
+-------------------+--------------------------------+------------------+
|
|
143
|
+
| custom_model_dump | convert model to dict | model_dump |
|
|
144
|
+
+-------------------+--------------------------------+------------------+
|
|
145
|
+
|
|
146
|
+
Advanced Tools
|
|
147
|
+
~~~~~~~~~~~~~~
|
|
148
|
+
|
|
149
|
+
Conditional Schema
|
|
150
|
+
|
|
151
|
+
.. code-block:: python
|
|
152
|
+
|
|
153
|
+
schema['properties']['test'] = {
|
|
154
|
+
"type": "object",
|
|
155
|
+
"oneOf": [
|
|
156
|
+
{
|
|
157
|
+
"properties": {
|
|
158
|
+
"lorem": {
|
|
159
|
+
"type": "string"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"required": [
|
|
163
|
+
"lorem"
|
|
164
|
+
]
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"properties": {
|
|
168
|
+
"ipsum": {
|
|
169
|
+
"type": "string"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"required": [
|
|
173
|
+
"ipsum"
|
|
174
|
+
]
|
|
175
|
+
}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
.. _database_migrations:
|
|
2
|
+
|
|
3
|
+
Database Migrations
|
|
4
|
+
===================
|
|
5
|
+
|
|
6
|
+
Use a migration when stored MongoDB data must change: model updates, field
|
|
7
|
+
backfills, key renames, embedded-model rewrites, index changes, or one-off data
|
|
8
|
+
repairs.
|
|
9
|
+
|
|
10
|
+
Add One
|
|
11
|
+
-------
|
|
12
|
+
|
|
13
|
+
1. Define the target state first: model code, collection shape, and recovery
|
|
14
|
+
flow.
|
|
15
|
+
2. Add one file under ``server/migrations/`` named
|
|
16
|
+
``YYYYMMDDHHMMSS_short_name.py``.
|
|
17
|
+
3. Set ``name`` to the file stem and ``dependencies`` to the latest migration.
|
|
18
|
+
4. Take a backup before running the migration on any real workspace database.
|
|
19
|
+
5. Check ``CONNECTION_STRING`` before running:
|
|
20
|
+
|
|
21
|
+
- The current runner requires a MongoDB user with ``admin.root``.
|
|
22
|
+
- This applies to both ``--scope ALL`` and ``--scope DATABASES`` in the
|
|
23
|
+
current implementation.
|
|
24
|
+
|
|
25
|
+
6. Decide rollout before writing code:
|
|
26
|
+
|
|
27
|
+
- **If old runners or old server code cannot read the new schema, stop
|
|
28
|
+
runners and stop writes until the migration is finished.**
|
|
29
|
+
- If a mixed schema must be tolerated for a short rollout window, ship
|
|
30
|
+
compatibility code first, run the migration second, remove compatibility
|
|
31
|
+
code last.
|
|
32
|
+
|
|
33
|
+
7. Define recovery before merge:
|
|
34
|
+
|
|
35
|
+
- Prefer a real ``downgrade``.
|
|
36
|
+
- If downgrade would drop data or cannot fully restore the old state,
|
|
37
|
+
document a forward-only recovery flow:
|
|
38
|
+
backup, stop writers, rerun or restore.
|
|
39
|
+
|
|
40
|
+
8. Keep the migration strict:
|
|
41
|
+
|
|
42
|
+
- Touch only the affected collections and fields.
|
|
43
|
+
- Fail fast on unsupported data.
|
|
44
|
+
- Log migration-specific counts or checkpoints. The runner already logs the
|
|
45
|
+
target database.
|
|
46
|
+
- If the migration is started again after a partial failure, it must not
|
|
47
|
+
duplicate or corrupt already migrated data.
|
|
48
|
+
|
|
49
|
+
9. Test on one workspace DB first.
|
|
50
|
+
|
|
51
|
+
.. code-block:: bash
|
|
52
|
+
|
|
53
|
+
uv run python -m server.migrations.run_workspace_migrations \
|
|
54
|
+
--scope DATABASES \
|
|
55
|
+
--databases my_test_user_db \
|
|
56
|
+
show
|
|
57
|
+
|
|
58
|
+
uv run python -m server.migrations.run_workspace_migrations \
|
|
59
|
+
--scope DATABASES \
|
|
60
|
+
--databases my_test_user_db \
|
|
61
|
+
migrate
|
|
62
|
+
|
|
63
|
+
uv run python -m server.migrations.run_workspace_migrations \
|
|
64
|
+
--scope ALL \
|
|
65
|
+
migrate
|
|
66
|
+
|
|
67
|
+
10. ``db_migrations.yml`` runs ``--scope ALL migrate`` by default. Use that
|
|
68
|
+
only after one workspace DB is verified.
|
|
69
|
+
|
|
70
|
+
.. code-block:: bash
|
|
71
|
+
|
|
72
|
+
docker compose -f db_migrations.yml run --rm simstack-migrations
|
|
73
|
+
|
|
74
|
+
To target one database from Docker, override the command:
|
|
75
|
+
|
|
76
|
+
.. code-block:: bash
|
|
77
|
+
|
|
78
|
+
docker compose -f db_migrations.yml run --rm simstack-migrations \
|
|
79
|
+
uv run python -m server.migrations.run_workspace_migrations \
|
|
80
|
+
--scope DATABASES \
|
|
81
|
+
--databases my_test_user_db \
|
|
82
|
+
migrate
|
|
83
|
+
|
|
84
|
+
Example 1: Add Field - ResourceDefinition.is_enabled
|
|
85
|
+
----------------------------------------------------
|
|
86
|
+
|
|
87
|
+
Case: ``ResourceDefinition`` gets a new field ``is_enabled: bool = True`` and
|
|
88
|
+
old resource documents must receive the default.
|
|
89
|
+
|
|
90
|
+
Model change:
|
|
91
|
+
|
|
92
|
+
.. code-block:: python
|
|
93
|
+
|
|
94
|
+
is_enabled: bool = True
|
|
95
|
+
|
|
96
|
+
Create ``server/migrations/20260527120000_resource_definition_is_enabled.py``:
|
|
97
|
+
|
|
98
|
+
.. code-block:: python
|
|
99
|
+
|
|
100
|
+
"""Backfill ResourceDefinition.is_enabled with True when missing."""
|
|
101
|
+
from __future__ import annotations
|
|
102
|
+
|
|
103
|
+
import logging
|
|
104
|
+
|
|
105
|
+
name = "20260527120000_resource_definition_is_enabled"
|
|
106
|
+
dependencies = ["20260527110000_previous_migration"]
|
|
107
|
+
|
|
108
|
+
logger = logging.getLogger(__name__)
|
|
109
|
+
MISSING_IS_ENABLED_QUERY = {"is_enabled": {"$exists": False}}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def upgrade(db):
|
|
113
|
+
resources_collection = db["resource_definition"]
|
|
114
|
+
result = resources_collection.update_many(
|
|
115
|
+
MISSING_IS_ENABLED_QUERY,
|
|
116
|
+
{"$set": {"is_enabled": True}},
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
remaining_missing_count = resources_collection.count_documents(MISSING_IS_ENABLED_QUERY)
|
|
120
|
+
if remaining_missing_count != 0:
|
|
121
|
+
raise RuntimeError(
|
|
122
|
+
f"[{name}] Expected 0 resources without is_enabled, found {remaining_missing_count}."
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
logger.info("[%s] Completed database=%s backfilled_resources=%s", name, db.name, result.modified_count)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def downgrade(db):
|
|
129
|
+
resources_collection = db["resource_definition"]
|
|
130
|
+
result = resources_collection.update_many(
|
|
131
|
+
{},
|
|
132
|
+
{"$unset": {"is_enabled": ""}},
|
|
133
|
+
)
|
|
134
|
+
logger.info("[%s] Completed database=%s removed_is_enabled_field=%s", name, db.name, result.modified_count)
|
|
135
|
+
|
|
136
|
+
Example 2: Edit Field - QMInput.print_level Enum Rewrite
|
|
137
|
+
--------------------------------------------------------
|
|
138
|
+
|
|
139
|
+
Case: ``QMInput.print_level`` changes from legacy integers ``0``-``4`` to the
|
|
140
|
+
existing ``PrintLevel`` enum strings.
|
|
141
|
+
|
|
142
|
+
Model change:
|
|
143
|
+
|
|
144
|
+
.. code-block:: python
|
|
145
|
+
|
|
146
|
+
print_level: PrintLevel = Field(
|
|
147
|
+
PrintLevel.LOW,
|
|
148
|
+
json_schema_extra={"description": "Print level for the calculation"},
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
Create ``server/migrations/20260527121000_qm_input_print_level_enum.py``:
|
|
152
|
+
|
|
153
|
+
.. code-block:: python
|
|
154
|
+
|
|
155
|
+
"""Convert QMInput.print_level from legacy integers to PrintLevel strings."""
|
|
156
|
+
from __future__ import annotations
|
|
157
|
+
|
|
158
|
+
import logging
|
|
159
|
+
|
|
160
|
+
name = "20260527121000_qm_input_print_level_enum"
|
|
161
|
+
dependencies = ["20260527120000_resource_definition_is_enabled"]
|
|
162
|
+
|
|
163
|
+
logger = logging.getLogger(__name__)
|
|
164
|
+
|
|
165
|
+
PRINT_LEVEL_BY_INT = {
|
|
166
|
+
0: "SILENT",
|
|
167
|
+
1: "LOW",
|
|
168
|
+
2: "MEDIUM",
|
|
169
|
+
3: "HIGH",
|
|
170
|
+
4: "EXTREME",
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def upgrade(db):
|
|
175
|
+
qm_inputs = db["qm_input"]
|
|
176
|
+
migrated_count = 0
|
|
177
|
+
|
|
178
|
+
for old_value, new_value in PRINT_LEVEL_BY_INT.items():
|
|
179
|
+
result = qm_inputs.update_many(
|
|
180
|
+
{"print_level": old_value},
|
|
181
|
+
{"$set": {"print_level": new_value}},
|
|
182
|
+
)
|
|
183
|
+
migrated_count += result.modified_count
|
|
184
|
+
|
|
185
|
+
remaining_legacy_count = qm_inputs.count_documents({"print_level": {"$type": "int"}})
|
|
186
|
+
if remaining_legacy_count:
|
|
187
|
+
raise RuntimeError(
|
|
188
|
+
f"[{name}] Found {remaining_legacy_count} QMInput documents with unsupported integer print_level."
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
logger.info("[%s] database=%s migrated_print_levels=%s", name, db.name, migrated_count)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def downgrade(db):
|
|
195
|
+
qm_inputs = db["qm_input"]
|
|
196
|
+
migrated_count = 0
|
|
197
|
+
|
|
198
|
+
for old_value, new_value in PRINT_LEVEL_BY_INT.items():
|
|
199
|
+
result = qm_inputs.update_many(
|
|
200
|
+
{"print_level": new_value},
|
|
201
|
+
{"$set": {"print_level": old_value}},
|
|
202
|
+
)
|
|
203
|
+
migrated_count += result.modified_count
|
|
204
|
+
|
|
205
|
+
logger.info("[%s] database=%s downgraded_print_levels=%s", name, db.name, migrated_count)
|
|
206
|
+
|
|
207
|
+
Example 3: Delete Field - QMInput.name
|
|
208
|
+
--------------------------------------
|
|
209
|
+
|
|
210
|
+
Case: ``QMInput`` drops the legacy ``name`` field because the node title is the
|
|
211
|
+
single source of truth and old documents must stop storing the duplicate value.
|
|
212
|
+
|
|
213
|
+
Model change:
|
|
214
|
+
|
|
215
|
+
.. code-block:: python
|
|
216
|
+
|
|
217
|
+
# Remove this field from QMInput
|
|
218
|
+
name: Optional[str] = None
|
|
219
|
+
|
|
220
|
+
Create ``server/migrations/20260527122000_qm_input_remove_name.py``:
|
|
221
|
+
|
|
222
|
+
.. code-block:: python
|
|
223
|
+
|
|
224
|
+
"""Remove the legacy QMInput.name field."""
|
|
225
|
+
from __future__ import annotations
|
|
226
|
+
|
|
227
|
+
import logging
|
|
228
|
+
|
|
229
|
+
name = "20260527122000_qm_input_remove_name"
|
|
230
|
+
dependencies = ["20260527121000_qm_input_print_level_enum"]
|
|
231
|
+
|
|
232
|
+
logger = logging.getLogger(__name__)
|
|
233
|
+
NAME_EXISTS_QUERY = {"name": {"$exists": True}}
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def upgrade(db):
|
|
237
|
+
qm_inputs = db["qm_input"]
|
|
238
|
+
result = qm_inputs.update_many(NAME_EXISTS_QUERY, {"$unset": {"name": ""}})
|
|
239
|
+
|
|
240
|
+
remaining_name_count = qm_inputs.count_documents(NAME_EXISTS_QUERY)
|
|
241
|
+
if remaining_name_count != 0:
|
|
242
|
+
raise RuntimeError(f"[{name}] Expected 0 QMInput documents with legacy name, found {remaining_name_count}.")
|
|
243
|
+
|
|
244
|
+
logger.info("[%s] database=%s removed_legacy_name=%s", name, db.name, result.modified_count)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def downgrade(db):
|
|
248
|
+
raise RuntimeError(
|
|
249
|
+
f"[{name}] Forward-only migration. Restore QMInput.name from backup if rollback is required."
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
Example 4: Edit Embedded Model - FileList to References
|
|
253
|
+
-------------------------------------------------------
|
|
254
|
+
|
|
255
|
+
Case: a parent document stores a full ``FileList`` object inside its own data,
|
|
256
|
+
and each ``FileStack`` inside that list must be moved to its own collection.
|
|
257
|
+
|
|
258
|
+
Partial migration shape:
|
|
259
|
+
|
|
260
|
+
.. code-block:: python
|
|
261
|
+
|
|
262
|
+
def _migrate_embedded_file_stack(file_stack_collection, file_stack_data: dict):
|
|
263
|
+
file_stack_id = file_stack_data.setdefault("_id", ObjectId())
|
|
264
|
+
existing = file_stack_collection.find_one({"_id": file_stack_id})
|
|
265
|
+
if existing is None:
|
|
266
|
+
file_stack_collection.insert_one(file_stack_data)
|
|
267
|
+
|
|
268
|
+
return file_stack_id
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def _migrate_file_list_data(file_stack_collection, file_list_data: dict) -> bool:
|
|
272
|
+
if "file_stacks" not in file_list_data:
|
|
273
|
+
return False
|
|
274
|
+
|
|
275
|
+
new_elements = []
|
|
276
|
+
for file_stack in file_list_data["file_stacks"]:
|
|
277
|
+
if isinstance(file_stack, dict):
|
|
278
|
+
file_stack_id = _migrate_embedded_file_stack(file_stack_collection, file_stack)
|
|
279
|
+
new_elements.append(file_stack_id)
|
|
280
|
+
else:
|
|
281
|
+
new_elements.append(file_stack)
|
|
282
|
+
|
|
283
|
+
del file_list_data["file_stacks"]
|
|
284
|
+
file_list_data["elements"] = new_elements
|
|
285
|
+
return True
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _migrate_parent_collection(parent_collection, parent_fields: list[str], file_stack_collection) -> int:
|
|
289
|
+
migrated_count = 0
|
|
290
|
+
|
|
291
|
+
for doc in parent_collection.find():
|
|
292
|
+
changed = False
|
|
293
|
+
|
|
294
|
+
for parent_field in parent_fields:
|
|
295
|
+
parent_value = doc.get(parent_field)
|
|
296
|
+
if isinstance(parent_value, dict) and _migrate_file_list_data(file_stack_collection, parent_value):
|
|
297
|
+
changed = True
|
|
298
|
+
|
|
299
|
+
if changed:
|
|
300
|
+
parent_collection.replace_one({"_id": doc["_id"]}, doc)
|
|
301
|
+
migrated_count += 1
|
|
302
|
+
|
|
303
|
+
return migrated_count
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def upgrade(db):
|
|
307
|
+
file_stack_collection = db["file_stack"]
|
|
308
|
+
node_registry_count = _migrate_parent_collection(db["node_registry"], ["info_files"], file_stack_collection)
|
|
309
|
+
file_list_io_count = _migrate_parent_collection(db["file_list_io"], ["file_list"], file_stack_collection)
|
|
310
|
+
logger.info("[%s] database=%s migrated_node_registry=%s migrated_file_list_io=%s", name, db.name, node_registry_count, file_list_io_count)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
.. _datasets:
|
|
2
|
+
|
|
3
|
+
Datasets
|
|
4
|
+
========
|
|
5
|
+
|
|
6
|
+
SimStack II uses a structured way to handle datasets through the ``DataSet``, ``DataSetSection``, and ``DataSetSelection`` models defined in ``simstack.models.dataset``.
|
|
7
|
+
|
|
8
|
+
DataSet
|
|
9
|
+
-------
|
|
10
|
+
|
|
11
|
+
The ``DataSet`` model is the top-level container for data.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
It consists of:
|
|
15
|
+
|
|
16
|
+
* **metadata**: A ``DataSetMetadata`` object that defines the type and validation rules for the dataset.
|
|
17
|
+
* **sections**: A dictionary of ``DataSetSection`` objects, keyed by section name.
|
|
18
|
+
|
|
19
|
+
It behaves like a dictionary of sections. Think of a dataset as an excel file, where each ``DataSetSection`` is a sheet.
|
|
20
|
+
|
|
21
|
+
Metadata
|
|
22
|
+
--------
|
|
23
|
+
|
|
24
|
+
Metadata in SimStack II is handled by the ``DataSetMetadata`` and ``DataSetMetadataTemplate`` classes.
|
|
25
|
+
|
|
26
|
+
- **DataSetMetadata**: This is an ``EmbeddedModel`` used within a ``DataSet``. It behaves like a dictionary and stores key-value pairs of information about the dataset (e.g., experimental conditions, parameters). It also ensures structural consistency of the data.
|
|
27
|
+
- **DataSetMetadataTemplate**: This model defines the expected structure and schema for a specific type of dataset metadata. When a new ``DataSet`` is saved, its metadata is validated against the corresponding template.
|
|
28
|
+
|
|
29
|
+
The metadata provides:
|
|
30
|
+
* **Validation**: Ensures that all datasets of the same type have consistent metadata keys and value types.
|
|
31
|
+
* **JSON Schema**: Automatically generates JSON schemas for the stored metadata.
|
|
32
|
+
* **Dict-like API**: Supports standard dictionary operations like ``__getitem__``, ``keys()``, ``items()``, and ``update()``.
|
|
33
|
+
|
|
34
|
+
DataSetSection
|
|
35
|
+
--------------
|
|
36
|
+
|
|
37
|
+
A ``DataSetSection`` represents a collection of rows within a dataset. Each row is a dictionary of models, but only the model ids are stored when saving.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
Key features:
|
|
41
|
+
* **Type consistency**: All rows in a section must have the same model types for the same keys.
|
|
42
|
+
* **Lazy loading**: Models are cached and only loaded from the database when needed.
|
|
43
|
+
* **Table representation**: It can automatically generate column definitions and table entries for UI components (like ag-grid).
|
|
44
|
+
|
|
45
|
+
To add data to a section, you can use the ``add_row`` method:
|
|
46
|
+
|
|
47
|
+
.. code-block:: python
|
|
48
|
+
|
|
49
|
+
section.add_row({"model_a": instance_a, "model_b": instance_b})
|
|
50
|
+
|
|
51
|
+
DataSetSelection
|
|
52
|
+
----------------
|
|
53
|
+
|
|
54
|
+
The ``DataSetSelection`` model is used to reference specific items within a ``DataSet``. Instead of duplicating data, it stores the ``dataset_id`` and a list of indices for each section.
|
|
55
|
+
|
|
56
|
+
This is particularly useful for workflows where a user selects a subset of a dataset to be processed by a subsequent node.
|
|
57
|
+
|
|
58
|
+
Example usage:
|
|
59
|
+
|
|
60
|
+
.. code-block:: python
|
|
61
|
+
|
|
62
|
+
selection = DataSetSelection(dataset_id=my_dataset.id)
|
|
63
|
+
selection.dataset_selection_fields.append(
|
|
64
|
+
DataSetSelectionField(section_name="default", indices=[0, 2, 5])
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
API Reference
|
|
68
|
+
-------------
|
|
69
|
+
|
|
70
|
+
.. autoclass:: simstack.models.dataset.DataSet
|
|
71
|
+
:members:
|
|
72
|
+
:undoc-members:
|
|
73
|
+
:show-inheritance:
|
|
74
|
+
|
|
75
|
+
.. autoclass:: simstack.models.dataset.DataSetSection
|
|
76
|
+
:members:
|
|
77
|
+
:undoc-members:
|
|
78
|
+
:show-inheritance:
|
|
79
|
+
|
|
80
|
+
.. autoclass:: simstack.models.dataset.DataSetSelection
|
|
81
|
+
:members:
|
|
82
|
+
:undoc-members:
|
|
83
|
+
:show-inheritance:
|
|
84
|
+
|
|
85
|
+
.. autoclass:: simstack.models.dataset_metadata.DataSetMetadata
|
|
86
|
+
:members:
|
|
87
|
+
:undoc-members:
|
|
88
|
+
:show-inheritance:
|
|
89
|
+
|
|
90
|
+
.. autoclass:: simstack.models.dataset_metadata.DataSetMetadataTemplate
|
|
91
|
+
:members:
|
|
92
|
+
:undoc-members:
|
|
93
|
+
:show-inheritance:
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
.. _developer_guide:
|
|
2
|
+
|
|
3
|
+
Developer Guide
|
|
4
|
+
===============
|
|
5
|
+
|
|
6
|
+
In this section we compiled a list of how-to's to help developers to use simstack efficiently.
|
|
7
|
+
|
|
8
|
+
.. toctree::
|
|
9
|
+
:maxdepth: 1
|
|
10
|
+
|
|
11
|
+
data
|
|
12
|
+
datasets
|
|
13
|
+
lists
|
|
14
|
+
array_lists
|
|
15
|
+
tables
|
|
16
|
+
files
|
|
17
|
+
resource_config
|
|
18
|
+
mass_runner
|
|
19
|
+
fire_and_forget_runner
|
|
20
|
+
docker_nodes
|
|
21
|
+
testing_complex_nodes
|
|
22
|
+
database_migrations
|
|
23
|
+
ci_pipeline
|
|
24
|
+
misc
|
|
25
|
+
|