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,111 @@
|
|
|
1
|
+
.. _lists:
|
|
2
|
+
|
|
3
|
+
List Mixins
|
|
4
|
+
===========
|
|
5
|
+
|
|
6
|
+
Simstack provides two main mixin classes to simplify the creation of models that behave like lists of other models: ``GenericListMixin`` and ``ObjectListMixin``. These mixins are located in ``simstack.models.base_lists``.
|
|
7
|
+
|
|
8
|
+
GenericListMixin
|
|
9
|
+
----------------
|
|
10
|
+
|
|
11
|
+
The ``GenericListMixin`` is intended for lists of items that are stored directly within the model, such as ``EmbeddedModel`` instances or basic Python types (strings, floats, etc.). It provides standard Python list-like behavior.
|
|
12
|
+
|
|
13
|
+
Requirements:
|
|
14
|
+
~~~~~~~~~~~~~
|
|
15
|
+
|
|
16
|
+
To use ``GenericListMixin``, your class must:
|
|
17
|
+
|
|
18
|
+
1. Inherit from ``GenericListMixin[T]``.
|
|
19
|
+
2. Have an attribute named ``elements`` of type ``List[T]``.
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
~~~~~~~~
|
|
23
|
+
|
|
24
|
+
.. code-block:: python
|
|
25
|
+
|
|
26
|
+
from typing import List
|
|
27
|
+
from odmantic import Model, Field
|
|
28
|
+
from simstack.models import simstack_model
|
|
29
|
+
from simstack.models.base_lists import GenericListMixin
|
|
30
|
+
|
|
31
|
+
@simstack_model
|
|
32
|
+
class StringList(Model, GenericListMixin[str]):
|
|
33
|
+
field_name: str = "string_list"
|
|
34
|
+
elements: List[str] = Field(default_factory=list)
|
|
35
|
+
|
|
36
|
+
Available Methods:
|
|
37
|
+
~~~~~~~~~~~~~~~~~~
|
|
38
|
+
|
|
39
|
+
- ``append(element: T)``: Adds an element to the list.
|
|
40
|
+
- ``extend(elements: Union[List[T], GenericListMixin[T]])``: Extends the list with another list or another mixin-based list.
|
|
41
|
+
- ``insert(index: int, element: T)``: Inserts an element at a specific index.
|
|
42
|
+
- ``remove(element: T)``: Removes the first occurrence of an element.
|
|
43
|
+
- ``pop(index: int = -1)``: Removes and returns the element at the given index.
|
|
44
|
+
- ``clear()``: Removes all elements.
|
|
45
|
+
- Standard list methods: ``index``, ``count``, ``reverse``, ``sort``, ``copy``.
|
|
46
|
+
- Support for standard operators: ``len()``, ``[]`` (getitem/setitem/delitem), ``iter()``, ``in``, ``bool()``.
|
|
47
|
+
|
|
48
|
+
Search and Filter:
|
|
49
|
+
~~~~~~~~~~~~~~~~~~
|
|
50
|
+
|
|
51
|
+
The mixin also provides convenience methods for searching elements if they have a ``name`` or ``size`` attribute:
|
|
52
|
+
|
|
53
|
+
- ``find(pattern: str)``: Returns the first element where ``element.name == pattern``.
|
|
54
|
+
- ``find_all(pattern: str)``: Returns all elements where ``element.name`` matches the regex ``pattern``.
|
|
55
|
+
- ``filter_by_size(min_size, max_size)``: Returns elements with a ``size`` attribute within the specified range.
|
|
56
|
+
- ``filter_by_property(property_name, value)``: Returns elements where ``getattr(element, property_name) == value``.
|
|
57
|
+
- ``sort_by_name()``, ``sort_by_size()``: Sorts the list based on these attributes.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
ObjectListMixin
|
|
61
|
+
---------------
|
|
62
|
+
|
|
63
|
+
The ``ObjectListMixin`` is designed for lists of ``Model`` instances. Instead of storing the full objects, it stores only their ``ObjectId``. This is useful for keeping the parent model small and avoiding deep nesting in MongoDB. Interaction with the objects is done asynchronously through the database.
|
|
64
|
+
|
|
65
|
+
Requirements:
|
|
66
|
+
~~~~~~~~~~~~~
|
|
67
|
+
|
|
68
|
+
To use ``ObjectListMixin``, your class must:
|
|
69
|
+
|
|
70
|
+
1. Inherit from ``ObjectListMixin[T]`` where ``T`` is an odmantic ``Model``.
|
|
71
|
+
2. Have an attribute named ``elements`` of type ``List[ObjectId]``.
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
~~~~~~~~
|
|
75
|
+
|
|
76
|
+
.. code-block:: python
|
|
77
|
+
|
|
78
|
+
from typing import List
|
|
79
|
+
from odmantic import Model, Field, ObjectId
|
|
80
|
+
from simstack.models import simstack_model, StringData
|
|
81
|
+
from simstack.models.base_lists import ObjectListMixin
|
|
82
|
+
|
|
83
|
+
@simstack_model
|
|
84
|
+
class StringDataList(Model, ObjectListMixin[StringData]):
|
|
85
|
+
field_name: str = "string_data_list"
|
|
86
|
+
elements: List[ObjectId] = Field(default_factory=list)
|
|
87
|
+
|
|
88
|
+
Concrete Implementations
|
|
89
|
+
------------------------
|
|
90
|
+
|
|
91
|
+
Several core SimStack models utilize these mixins:
|
|
92
|
+
|
|
93
|
+
* :doc:`files`: ``FileList`` and ``FileListModel`` use ``ObjectListMixin[FileStack]``.
|
|
94
|
+
* :doc:`array_lists`: ``ArrayList`` uses ``ObjectListMixin[ArrayStorage]``.
|
|
95
|
+
* :doc:`tables`: ``SimpleTable`` (while not using list mixins directly, it's a related data structure).
|
|
96
|
+
|
|
97
|
+
Available Methods (mostly Async):
|
|
98
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
99
|
+
|
|
100
|
+
- ``await append(element: T)``: Saves the ``Model`` instance to the database and adds its ID to the list.
|
|
101
|
+
- ``await extend(elements: Union[List[T], ObjectListMixin[T]])``: Extends the list, saving any new models to the database.
|
|
102
|
+
- ``await get(index: int) -> T``: Retrieves the full model from the database at the specified index.
|
|
103
|
+
- ``await find(pattern: str) -> Optional[T]``: Searches for a model with a matching ``name`` attribute in the database.
|
|
104
|
+
- ``await find_all(pattern: str) -> List[T]``: Searches for all models matching the regex ``pattern``.
|
|
105
|
+
- ``async for element in my_list``: Support for asynchronous iteration over the full objects.
|
|
106
|
+
- ``len(my_list)``: Returns the number of IDs in the list.
|
|
107
|
+
- ``my_list[index]``: Returns the ``ObjectId`` at the specified index (sync).
|
|
108
|
+
- ``element in my_list``: Checks if a ``Model`` or ``ObjectId`` is in the list (sync).
|
|
109
|
+
|
|
110
|
+
.. note::
|
|
111
|
+
Interaction with ``ObjectListMixin`` requires an active database engine context, which is typically provided during node execution.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
MassRunner
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
.. autoclass:: simstack.methods.mass_runner.MassRunner
|
|
5
|
+
:members:
|
|
6
|
+
:undoc-members:
|
|
7
|
+
:show-inheritance:
|
|
8
|
+
|
|
9
|
+
The ``MassRunner`` is a specialized ``NodeRunner`` utility designed to execute a large number of independent node tasks in parallel. It handles task orchestration, concurrency control, and result persistence within a ``DataSet``.
|
|
10
|
+
|
|
11
|
+
Key Features
|
|
12
|
+
------------
|
|
13
|
+
|
|
14
|
+
* **Parallel Execution**: Leverages ``asyncio`` to run multiple nodes concurrently.
|
|
15
|
+
* **Concurrency Control**: Supports an optional ``max_concurrency`` parameter using an internal semaphore.
|
|
16
|
+
* **Automatic Persistence**: Stores results (both successful and failed) in a ``DataSet`` model.
|
|
17
|
+
* **Result Recovery**: Can recover results from previous runs of the same or different nodes using ``recover_orphaned_datasets``.
|
|
18
|
+
* **Hashing and Caching**: Computes hashes for arguments to skip redundant executions.
|
|
19
|
+
|
|
20
|
+
Usage
|
|
21
|
+
-----
|
|
22
|
+
|
|
23
|
+
The ``MassRunner`` is typically used within an ``async with`` block inside a parent node.
|
|
24
|
+
|
|
25
|
+
.. code-block:: python
|
|
26
|
+
|
|
27
|
+
from applications.general.mass_runner import MassRunner
|
|
28
|
+
from simstack.models import IntData
|
|
29
|
+
|
|
30
|
+
@node
|
|
31
|
+
async def my_parallel_master(argument: IntData, **kwargs):
|
|
32
|
+
# Initialize MassRunner with the target node to be executed in parallel
|
|
33
|
+
async with MassRunner(target_node, max_concurrency=10, **kwargs) as runner:
|
|
34
|
+
for i in range(argument.value):
|
|
35
|
+
# Create tasks for individual inputs
|
|
36
|
+
runner.create_tasks(IntData(value=i))
|
|
37
|
+
|
|
38
|
+
# After the block, runner.dataset contains all results
|
|
39
|
+
return runner.dataset
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
The dataset will comprise a single ``DataSetSection`` called "tasks". Each row contains all inputs and outputs of the
|
|
43
|
+
node that has been called, success and error flags. The name of the row is the arg-hash of the arguments of the node.
|
|
44
|
+
|
|
45
|
+
.. :note:
|
|
46
|
+
The rows returned by MassRunner may contain much more data than is actually needed in the subsequent calculation.
|
|
47
|
+
It may therefore be better to immideatly create a derived dataset with only the relevent data.
|
|
48
|
+
|
|
49
|
+
.. :note:
|
|
50
|
+
MassRunner is meant for jobs which are expected to mostly suceed and which take roughly the same amount of time
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
Detailed Flow in MassRunner Tests
|
|
55
|
+
---------------------------------
|
|
56
|
+
|
|
57
|
+
The ``mass_runner_test.py`` file demonstrates how ``MassRunner`` handles task execution, failures, and recovery.
|
|
58
|
+
|
|
59
|
+
1. **Failure Demonstration (mass_runner_test_master_node)**
|
|
60
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
61
|
+
|
|
62
|
+
The test first calls ``mass_runner_test_master_node``, which uses ``MassRunner`` to call ``sad_node``.
|
|
63
|
+
|
|
64
|
+
* **sad_node logic**: Fails if the input integer is even (``argument.value % 2 == 0``).
|
|
65
|
+
* **Execution**: For inputs ``0, 1, 2``, inputs ``0`` and ``2`` will fail, while ``1`` will succeed.
|
|
66
|
+
* **Dataset State**: The resulting ``DataSet`` contains a "tasks" section where each entry records the success status and any error messages.
|
|
67
|
+
|
|
68
|
+
2. **Recovery and Fix (mass_runner_test_fix_master_node)**
|
|
69
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
70
|
+
|
|
71
|
+
The second part of the test demonstrates how to "fix" a failed workflow by reusing successful results and replacing failed ones with results from a different node (or a fixed version of the same node).
|
|
72
|
+
|
|
73
|
+
* **Context Setup**: It passes the ``previous_task_id`` and sets ``previous_node_name`` in ``kwargs``.
|
|
74
|
+
* **MassRunner Initialization**: It initializes ``MassRunner`` with ``happy_node`` (which always succeeds).
|
|
75
|
+
* **Orphan Recovery**: Calling ``await result.recover_orphaned_datasets()`` searches the database for the dataset generated in the first step.
|
|
76
|
+
* **Selective Execution**:
|
|
77
|
+
- When ``create_tasks`` is called, ``MassRunner`` checks the existing dataset for a matching ``arg_hash``.
|
|
78
|
+
- If a **successful** result is found for that hash, it is copied into the new dataset and the node execution is skipped.
|
|
79
|
+
- If no result or a **failed** result is found, it executes the new node (``happy_node``) and stores the new success.
|
|
80
|
+
* **Result**: The final dataset contains the reused success from the first run (for input ``1``) and the new successful results from ``happy_node`` (for inputs ``0`` and ``2``).
|
|
81
|
+
|
|
82
|
+
Logging and Metadata
|
|
83
|
+
--------------------
|
|
84
|
+
|
|
85
|
+
``MassRunner`` automatically attaches metadata to the ``DataSet``, including:
|
|
86
|
+
* The original node name.
|
|
87
|
+
* The task ID of the master node.
|
|
88
|
+
* The argument hash used for grouping.
|
|
89
|
+
* The call path within the workflow.
|
|
90
|
+
|
|
91
|
+
This metadata is crucial for the ``recover_orphaned_datasets`` method to correctly identify related data from previous executions.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Miscellaneous
|
|
2
|
+
==============
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
BUGS:
|
|
6
|
+
-----
|
|
7
|
+
|
|
8
|
+
Optional fields in embedded models are not handled correctly
|
|
9
|
+
|
|
10
|
+
https://github.com/art049/odmantic/issues/370
|
|
11
|
+
https://github.com/art049/odmantic/issues/484
|
|
12
|
+
|
|
13
|
+
References
|
|
14
|
+
----------
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
The challenge in Simstack II is to exploit the features of Next-JS frontend
|
|
19
|
+
without forcing the developer to write Next-JS or server components. In
|
|
20
|
+
Simstack II each user has his/her own MongoDB database, there is an
|
|
21
|
+
additional database used exclusively for authentication.
|
|
22
|
+
|
|
23
|
+
.. note:: Only one instance of a mongodb database server, of the fastapi
|
|
24
|
+
server and of the next-js frontend is required per installation.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
The workflow developer customizes the appearance of workflows for submission,
|
|
28
|
+
data analysis and data visualization using three main mechanisms:
|
|
29
|
+
|
|
30
|
+
* `React JSON Schema Form <https://rjsf-team.github.io/react-jsonschema-form/>`_
|
|
31
|
+
* `AG-Grid <https://www.ag-grid.com/>`_ is used to generate interactive tables (via Artifacts)
|
|
32
|
+
* `AG-Charts <https://charts.ag-grid.com/>`_ is used to generate interactive graphs (via Artifacts)
|
|
33
|
+
|
|
34
|
+
Customizing Simstack Models
|
|
35
|
+
---------------------------
|
|
36
|
+
|
|
37
|
+
.. note:: General information about Simstack models
|
|
38
|
+
|
|
39
|
+
Simstack models are built on top of `odmantic`, which uses `pydantic` for data validation.
|
|
40
|
+
By decorating a class with `@simstack_model`, you enable additional UI-related features.
|
|
41
|
+
You can customize how a model appears in the GUI by implementing `json_schema` and `ui_schema` methods.
|
|
42
|
+
Refer to :ref:`persisting_data` for more details.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
Running the above code as a workflow we would like to achieve the following:
|
|
47
|
+
|
|
48
|
+
* code can be executed on remote resources (possibly in parallel)
|
|
49
|
+
* users can inspect the results in a GUI
|
|
50
|
+
* results can be reused when the workflow failed or in other workflows
|
|
51
|
+
* the workflow can be run from a GUI
|
|
52
|
+
* (workflows can be created from existing components in a GUI)
|
|
53
|
+
|
|
54
|
+
To address the first points, all data must be serializable. This can be achieved by pickling the inputs/outputs but
|
|
55
|
+
then the data is hidden in the pickled string and not searchable. Here we have chosen odmantic classes to persist the
|
|
56
|
+
data in a database. See: :ref:`persisting-results-section`. This has the charm that routes to access this data can be
|
|
57
|
+
automatically generated.
|
|
58
|
+
|
|
59
|
+
Overall we need four "servers" to run the workflow:
|
|
60
|
+
|
|
61
|
+
* The "workflow server" that manages and executes workflows
|
|
62
|
+
* The "runners" that execute parts of workflows on remote resources
|
|
63
|
+
* The "database server" provides an API to the database for the GUI
|
|
64
|
+
* The webserver that serves the GUI
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
.. code-block:: python
|
|
68
|
+
|
|
69
|
+
@node(parameters=Parameters(resource="my_resource", queue="slurm-queue"))
|
|
70
|
+
def my_node(arg1: Model1, arg2: Model2, **kwargs) -> SimstackResult:
|
|
71
|
+
# do something with inputs
|
|
72
|
+
return outputs
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
.. note::
|
|
77
|
+
- Each node has a unique task_id which is the ObjectId of entry in the
|
|
78
|
+
node_registry table in the database
|
|
79
|
+
- Before control is passed to a node, the calling function will create
|
|
80
|
+
a directory as workdir/node_name/node_id which is unique to the node.
|
|
81
|
+
- all files generated by the node should be written into this directory.
|
|
82
|
+
- nodes can by synchronous or async functions.
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
**Allowed Arguments**
|
|
86
|
+
|
|
87
|
+
- All **positional** arguments of the wrapped function (my_node) must be
|
|
88
|
+
**registered** odmantic Models. These arguments are automatically persisted
|
|
89
|
+
in the database.
|
|
90
|
+
- The my_node function must have \*\*kwargs even if they are not used in the
|
|
91
|
+
function.
|
|
92
|
+
- \*\*kwargs is used to pass information to process the node, but
|
|
93
|
+
should not be used to pass arguments that affect the result of the
|
|
94
|
+
function. Presently, Model-type arguments in the \*\*kwargs are not persisted
|
|
95
|
+
in the database which precludes the execution of such nodes on resources
|
|
96
|
+
which are different from the function is called.
|
|
97
|
+
|
|
98
|
+
.. important::
|
|
99
|
+
Only positional arguments should affect the outcome of the function execution
|
|
100
|
+
|
|
101
|
+
**Return Types**
|
|
102
|
+
|
|
103
|
+
While it is easy to check whether the variables
|
|
104
|
+
passed to nodes can be persisted in the database, this can be checked for
|
|
105
|
+
results only in post-processing.
|
|
106
|
+
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
Overview
|
|
2
|
+
========
|
|
3
|
+
|
|
4
|
+
SimStack II
|
|
5
|
+
~~~~~~~~~~~
|
|
6
|
+
|
|
7
|
+
SimStack II is a modern, Python-based workflow system with a web-based graphical user interface (GUI). The GUI is generated automatically from your Python workflow code and supports interactive inspection of inputs, outputs, tables, and plots.
|
|
8
|
+
|
|
9
|
+
Key features
|
|
10
|
+
^^^^^^^^^^^^
|
|
11
|
+
|
|
12
|
+
* **GUI-driven execution:** Workflows are submitted via a :ref:`graphical user interface <using-gui-section>`, which is auto-generated from the :ref:`Python code <writing-gui-section>`.
|
|
13
|
+
* **Persistent results:** Inputs and results are stored automatically in a non-SQL database so they can be reused and re-analyzed.
|
|
14
|
+
* **Flexible workflows:** Workflows can be generated dynamically at runtime, nested, and executed across different remote resources.
|
|
15
|
+
* **Artifacts for analysis:** Tables, plots, and other artifacts can be created during or after workflow execution to support data analysis.
|
|
16
|
+
* **Simple authoring model:** :doc:`Workflows <workflows>` are written as decorated plain Python functions.
|
|
17
|
+
|
|
18
|
+
Roadmap
|
|
19
|
+
^^^^^^^
|
|
20
|
+
|
|
21
|
+
Future versions are planned to (roughly in this order):
|
|
22
|
+
|
|
23
|
+
* integrate research data management
|
|
24
|
+
* provide tools to wrap other workflow systems
|
|
25
|
+
* implement artifact generation via the GUI
|
|
26
|
+
* enable data aggregation via the GUI
|
|
27
|
+
* enable workflow development via the GUI
|
|
28
|
+
|
|
29
|
+
For a quick start, see :doc:`installation` and start using SimStack II via the :ref:`graphical user interface <using-gui-section>`.
|
|
30
|
+
|
|
31
|
+
Motivation
|
|
32
|
+
~~~~~~~~~~
|
|
33
|
+
|
|
34
|
+
Computational scientists produce data that ultimately becomes figures and tables in publications.
|
|
35
|
+
To aid this process many workflow environments already exist:
|
|
36
|
+
`Wikipedia <https://en.wikipedia.org/wiki/Workflow_management_system>`_ lists a wide range of systems
|
|
37
|
+
such as Airflow, Luigi, Nextflow, and Snakemake. Many widely used tools are file-based:
|
|
38
|
+
a workflow is defined in a static configuration file and executed by an engine.
|
|
39
|
+
This approach can be robust and has been very successful,
|
|
40
|
+
but it often becomes limiting when workflows must be assembled dynamically or adapted during execution.
|
|
41
|
+
|
|
42
|
+
In parallel, the AI/ML ecosystem has accelerated the development of powerful Python-native workflow
|
|
43
|
+
systems such as
|
|
44
|
+
`covalent <https://github.com/AgnostiqHQ/covalent>`_,
|
|
45
|
+
`prefect <https://github.com/PrefectHQ/prefect>`_, and
|
|
46
|
+
`pyiron <https://github.com/pyiron/pyiron>`_.
|
|
47
|
+
These systems embrace Python directly, enabling more dynamic and expressive computation pipelines.
|
|
48
|
+
|
|
49
|
+
Our experience with SimStack I suggests there are two only partially overlapping communities:
|
|
50
|
+
|
|
51
|
+
* expert workflow developers (in python or otherwise) who struggle to develop user-interfaces
|
|
52
|
+
make these workflows accessible to end-users
|
|
53
|
+
* a larger group of workflow users, but may not have the software engineering background
|
|
54
|
+
to develop the workflows on their own.
|
|
55
|
+
|
|
56
|
+
Bridging developers and users
|
|
57
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
58
|
+
|
|
59
|
+
SimStack II aims to bridge this gap by making workflow execution and result exploration accessible
|
|
60
|
+
through a GUI, while keeping workflow implementation in Python. This enables rapid development of
|
|
61
|
+
workflows using the full power of the python ecosystem. We believe this approach is much more
|
|
62
|
+
powerful than attempting to construct complex workflows in a graphical user interface.
|
|
63
|
+
|
|
64
|
+
Developers who can construct workflows via a GUI typically have the ability to
|
|
65
|
+
write them directly in Python. A GUI for *workflow development* thus adds overhead
|
|
66
|
+
without providing much benefit. A GUI for *workflow execution and analysis*,
|
|
67
|
+
however, can substantially lower the barrier for many users.
|
|
68
|
+
|
|
69
|
+
In developing a workflow system for scientific applications, we also need to consider another
|
|
70
|
+
issue: Workflows in IT settings (e.g., server or database maintenance) tend to be stable:
|
|
71
|
+
the goal is an environment where everything works all the time.
|
|
72
|
+
|
|
73
|
+
Scientific workflows often operate in a different environment: methods, hypotheses, and
|
|
74
|
+
analysis requirements evolve continuously. A workflow may succeed technically while
|
|
75
|
+
producing results that invalidate the motivating hypothesis—triggering
|
|
76
|
+
new analysis and iteration.
|
|
77
|
+
|
|
78
|
+
This reality makes persistence, traceability, and interactive re-analysis essential.
|
|
79
|
+
|
|
80
|
+
Design goals
|
|
81
|
+
^^^^^^^^^^^^
|
|
82
|
+
|
|
83
|
+
SimStack II is designed with the following priorities:
|
|
84
|
+
|
|
85
|
+
* Workflows are initialized, monitored, and managed through a GUI on a variety of compute resources.
|
|
86
|
+
* Results are persisted and accessible for re-analysis, ideally through the GUI.
|
|
87
|
+
* Workflow components are implemented in Python, with minimal coding overhead.
|
|
88
|
+
* Workflows expose results in a UI that is (to a large extent)
|
|
89
|
+
automatically generated on the basis of the python code additional frontend development.
|
|
90
|
+
|
|
91
|
+
.. include:: architecture.rst
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Recovery and Repair of Nodes
|
|
2
|
+
===========================
|
|
3
|
+
|
|
4
|
+
This document explains how to implement recovery mechanisms for failed nodes in SimStack.
|
|
5
|
+
The example `recovery_test.py` demonstrates how to handle nodes that might fail after producing some output, and how to recover that output using a recovery node.
|
|
6
|
+
|
|
7
|
+
Overview
|
|
8
|
+
--------
|
|
9
|
+
|
|
10
|
+
The recovery process involves three main components:
|
|
11
|
+
|
|
12
|
+
1. **The Failing Node**: A node that performs some work, writes output to a file, but then fails (e.g., due to an exception).
|
|
13
|
+
2. **The Repair Function**: A helper function that knows how to locate the output of a failed node and "repair" the result by collecting the files and marking it as successful.
|
|
14
|
+
3. **The Recovery Node**: A node that queries the database for failed instances of specific nodes and applies the repair function to them.
|
|
15
|
+
|
|
16
|
+
Implementation Details
|
|
17
|
+
----------------------
|
|
18
|
+
|
|
19
|
+
The example implementation can be found in `examples/testing/recovery_test.py`.
|
|
20
|
+
|
|
21
|
+
.. literalinclude:: ../../../examples/testing/recovery_test.py
|
|
22
|
+
:language: python
|
|
23
|
+
:linenos:
|
|
24
|
+
|
|
25
|
+
How it Works
|
|
26
|
+
------------
|
|
27
|
+
|
|
28
|
+
1. **sxt_failing_node**:
|
|
29
|
+
This node simulates a failure. Even though it fails, it ensures that its progress (in this case, `result.txt`) is saved in its working directory.
|
|
30
|
+
|
|
31
|
+
2. **stx_repair_node**:
|
|
32
|
+
This function takes a `NodeRegistry` entry. It constructs the path to the original node's working directory using `context.config.workdir`. If it finds the expected output files, it uses `node_runner.succeed()` to provide the missing data.
|
|
33
|
+
|
|
34
|
+
3. **sxt_recovery_node**:
|
|
35
|
+
This is the orchestrator for recovery. It uses `context.db.find` to search for `NodeRegistry` entries with a `failed` status and a specific `call_path`. For each failed node found, it calls `stx_repair_node`. If repair is successful, it updates the original node's status in the database.
|
|
36
|
+
|
|
37
|
+
4. **Main Execution**:
|
|
38
|
+
The `main` function first runs several instances of `sxt_failing_node`, which all fail. Then, it runs `sxt_recovery_node` to automatically fix these failures and recover the data.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Program Execution
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
When developers write new nodes that execute external programs they cannot know the specifics of the resources on which these nodes are to be run.
|
|
5
|
+
Simstack separates the program execution logic from the specifics of a particular resource. The ``ResourceConfig`` class handles resource-specific
|
|
6
|
+
configurations from a ``config.toml`` file. It provides methods to retrieve program parameters, setup scripts,
|
|
7
|
+
and run commands in a controlled environment (optionally using temporary directories).
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
The config toml is structured by resources, i.e. if you have resources hpc1 and small-computer and my-laptop sections starting with [hpc1], [small-computer], [my-laptop]
|
|
11
|
+
contain the data for each of these nodes. The convenience functions return the data for the actual resource. In principle you are totally free
|
|
12
|
+
which information you store in ``config.toml`` for your own nodes, but the convenience functions implement often used features, such as
|
|
13
|
+
|
|
14
|
+
- using scratch space for program execution and where that is
|
|
15
|
+
- startup scripts
|
|
16
|
+
- the actual command to execute to run the programs
|
|
17
|
+
|
|
18
|
+
.. note::
|
|
19
|
+
An instance of ``ResourceConfig`` is provided by the context
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
The documentation below explains the current defaults. Standard nodes are then simply executed by:
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
.. code-block:: python
|
|
27
|
+
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
from simstack.core.context import context
|
|
30
|
+
|
|
31
|
+
input_files: List[str | FileStack] = [...]
|
|
32
|
+
output_files: List[str | FileStack] = [...]
|
|
33
|
+
result = context.resource_config.run("program-name", input_files, output_files)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
ResourceConfig Class
|
|
39
|
+
--------------------
|
|
40
|
+
|
|
41
|
+
The ``ResourceConfig`` class is located in ``simstack.util.resource_config``.
|
|
42
|
+
|
|
43
|
+
.. autoclass:: simstack.util.resource_config.ResourceConfig
|
|
44
|
+
:members:
|
|
45
|
+
:undoc-members:
|
|
46
|
+
:show-inheritance:
|
|
47
|
+
|
|
48
|
+
Initialization
|
|
49
|
+
~~~~~~~~~~~~~~
|
|
50
|
+
|
|
51
|
+
The ``ResourceConfig`` is initialized with a path to the configuration file (or directory containing ``config.toml``) and the name of the resource.
|
|
52
|
+
|
|
53
|
+
.. code-block:: python
|
|
54
|
+
|
|
55
|
+
from pathlib import Path
|
|
56
|
+
from simstack.util.resource_config import ResourceConfig
|
|
57
|
+
|
|
58
|
+
config = ResourceConfig(Path("/path/to/project"), "local")
|
|
59
|
+
config.program = "orca"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
Methods
|
|
63
|
+
~~~~~~~
|
|
64
|
+
|
|
65
|
+
* ``os``: Property that returns the operating system of the resource (defaults to "linux").
|
|
66
|
+
* ``program``: Property to get or set the current program name.
|
|
67
|
+
* ``setup(node_runner=None)``: Executes the setup scripts defined for the resource.
|
|
68
|
+
* ``run(program_name=None, input_files=None, output_files=None, node_runner=None)``: Executes the program command, handling file transfers and temporary directories based on configuration.
|
|
69
|
+
* ``get_program()``: Retrieves configuration for the current program.
|
|
70
|
+
* ``get_setup_params()``: Retrieves setup configuration for the current resource.
|
|
71
|
+
* ``get_postprocessing_params()``: Retrieves post-processing configuration.
|
|
72
|
+
|
|
73
|
+
Integration with NodeRunner
|
|
74
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
75
|
+
|
|
76
|
+
If a ``node_runner`` instance is passed to ``setup()`` or ``run()``, it will use ``node_runner.subprocess()`` to execute commands, which provides better logging and integration with SimStack's task management.
|
|
77
|
+
|
|
78
|
+
Config.toml Structure
|
|
79
|
+
---------------------
|
|
80
|
+
|
|
81
|
+
The ``config.toml`` file is organized by resource name. Each resource can have several sections:
|
|
82
|
+
|
|
83
|
+
General Resource Settings
|
|
84
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
85
|
+
|
|
86
|
+
.. code-block:: toml
|
|
87
|
+
|
|
88
|
+
[resource_name]
|
|
89
|
+
os = "linux" # optional, defaults to "linux"
|
|
90
|
+
|
|
91
|
+
Setup Section
|
|
92
|
+
~~~~~~~~~~~~~
|
|
93
|
+
|
|
94
|
+
Contains scripts to be executed before any program run and configuration for temporary directories.
|
|
95
|
+
|
|
96
|
+
.. code-block:: toml
|
|
97
|
+
|
|
98
|
+
[resource_name.setup]
|
|
99
|
+
scripts = [
|
|
100
|
+
"module load orca",
|
|
101
|
+
"export MY_VAR=value"
|
|
102
|
+
]
|
|
103
|
+
tmp_base_dir = "/path/to/scratch" # Can also be a command like "set TMP_BASE_DIR=..."
|
|
104
|
+
|
|
105
|
+
Post-processing Section
|
|
106
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
107
|
+
|
|
108
|
+
Contains settings for cleanup after execution.
|
|
109
|
+
|
|
110
|
+
.. code-block:: toml
|
|
111
|
+
|
|
112
|
+
[resource_name.post-processing] # or [resource_name.postprocessing]
|
|
113
|
+
scratch_cleanup = true
|
|
114
|
+
|
|
115
|
+
Program Section
|
|
116
|
+
~~~~~~~~~~~~~~~
|
|
117
|
+
|
|
118
|
+
Defines configuration for specific applications on the resource.
|
|
119
|
+
|
|
120
|
+
.. code-block:: toml
|
|
121
|
+
|
|
122
|
+
[resource_name.program.orca]
|
|
123
|
+
use_tmp = true
|
|
124
|
+
run_command = "orca orca.inp > orca.out"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
Example config.toml
|
|
128
|
+
~~~~~~~~~~~~~~~~~~~
|
|
129
|
+
|
|
130
|
+
.. code-block:: toml
|
|
131
|
+
|
|
132
|
+
[local]
|
|
133
|
+
os = "windows"
|
|
134
|
+
|
|
135
|
+
[local.setup]
|
|
136
|
+
scripts = ["set USER=%USERNAME%"]
|
|
137
|
+
tmp_base_dir = "C:\\Temp"
|
|
138
|
+
|
|
139
|
+
[local.program.orca]
|
|
140
|
+
use_tmp = true
|
|
141
|
+
run_command = "orca orca.inp > orca.out"
|