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,766 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html class="no-js" lang="en" data-content_root="./">
|
|
3
|
+
<head><meta charset="utf-8">
|
|
4
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
5
|
+
<meta name="color-scheme" content="light dark"><meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<link rel="index" title="Index" href="genindex.html"><link rel="search" title="Search" href="search.html"><link rel="next" title="Graphical User Interface" href="ui_documentation.html"><link rel="prev" title="Overview" href="overview.html">
|
|
7
|
+
|
|
8
|
+
<!-- Generated with Sphinx 9.1.0 and Furo 2025.12.19 -->
|
|
9
|
+
<title>Workflows - SimStack II documentation</title>
|
|
10
|
+
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d111a655" />
|
|
11
|
+
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?v=7bdb33bb" />
|
|
12
|
+
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?v=8dab3a3b" />
|
|
13
|
+
<link rel="stylesheet" type="text/css" href="_static/cobalt2-theme.css?v=2d651046" />
|
|
14
|
+
<link rel="stylesheet" type="text/css" href="_static/docs-build-badge.css?v=803faff8" />
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
<style>
|
|
20
|
+
body {
|
|
21
|
+
--color-code-background: #f2f2f2;
|
|
22
|
+
--color-code-foreground: #1e1e1e;
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
@media not print {
|
|
26
|
+
body[data-theme="dark"] {
|
|
27
|
+
--color-code-background: #202020;
|
|
28
|
+
--color-code-foreground: #d0d0d0;
|
|
29
|
+
--color-background-primary: #132738;
|
|
30
|
+
--color-background-secondary: #1e3a52;
|
|
31
|
+
--color-foreground-primary: #ffffff;
|
|
32
|
+
--color-foreground-secondary: #bac8d3;
|
|
33
|
+
--color-brand-primary: #22d5ff;
|
|
34
|
+
--color-brand-content: #0088ff;
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
@media (prefers-color-scheme: dark) {
|
|
38
|
+
body:not([data-theme="light"]) {
|
|
39
|
+
--color-code-background: #202020;
|
|
40
|
+
--color-code-foreground: #d0d0d0;
|
|
41
|
+
--color-background-primary: #132738;
|
|
42
|
+
--color-background-secondary: #1e3a52;
|
|
43
|
+
--color-foreground-primary: #ffffff;
|
|
44
|
+
--color-foreground-secondary: #bac8d3;
|
|
45
|
+
--color-brand-primary: #22d5ff;
|
|
46
|
+
--color-brand-content: #0088ff;
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
</style></head>
|
|
52
|
+
<body>
|
|
53
|
+
|
|
54
|
+
<script>
|
|
55
|
+
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
|
60
|
+
<symbol id="svg-toc" viewBox="0 0 24 24">
|
|
61
|
+
<title>Contents</title>
|
|
62
|
+
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
|
|
63
|
+
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
|
|
64
|
+
</svg>
|
|
65
|
+
</symbol>
|
|
66
|
+
<symbol id="svg-menu" viewBox="0 0 24 24">
|
|
67
|
+
<title>Menu</title>
|
|
68
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
69
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
|
|
70
|
+
<line x1="3" y1="12" x2="21" y2="12"></line>
|
|
71
|
+
<line x1="3" y1="6" x2="21" y2="6"></line>
|
|
72
|
+
<line x1="3" y1="18" x2="21" y2="18"></line>
|
|
73
|
+
</svg>
|
|
74
|
+
</symbol>
|
|
75
|
+
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
|
|
76
|
+
<title>Expand</title>
|
|
77
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
78
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
|
|
79
|
+
<polyline points="9 18 15 12 9 6"></polyline>
|
|
80
|
+
</svg>
|
|
81
|
+
</symbol>
|
|
82
|
+
<symbol id="svg-sun" viewBox="0 0 24 24">
|
|
83
|
+
<title>Light mode</title>
|
|
84
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
85
|
+
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
|
|
86
|
+
<circle cx="12" cy="12" r="5"></circle>
|
|
87
|
+
<line x1="12" y1="1" x2="12" y2="3"></line>
|
|
88
|
+
<line x1="12" y1="21" x2="12" y2="23"></line>
|
|
89
|
+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
|
90
|
+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
|
91
|
+
<line x1="1" y1="12" x2="3" y2="12"></line>
|
|
92
|
+
<line x1="21" y1="12" x2="23" y2="12"></line>
|
|
93
|
+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
|
94
|
+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
|
95
|
+
</svg>
|
|
96
|
+
</symbol>
|
|
97
|
+
<symbol id="svg-moon" viewBox="0 0 24 24">
|
|
98
|
+
<title>Dark mode</title>
|
|
99
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
100
|
+
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
|
|
101
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
102
|
+
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
|
103
|
+
</svg>
|
|
104
|
+
</symbol>
|
|
105
|
+
<symbol id="svg-sun-with-moon" viewBox="0 0 24 24">
|
|
106
|
+
<title>Auto light/dark, in light mode</title>
|
|
107
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
108
|
+
stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
|
|
109
|
+
class="icon-custom-derived-from-feather-sun-and-tabler-moon">
|
|
110
|
+
<path style="opacity: 50%" d="M 5.411 14.504 C 5.471 14.504 5.532 14.504 5.591 14.504 C 3.639 16.319 4.383 19.569 6.931 20.352 C 7.693 20.586 8.512 20.551 9.25 20.252 C 8.023 23.207 4.056 23.725 2.11 21.184 C 0.166 18.642 1.702 14.949 4.874 14.536 C 5.051 14.512 5.231 14.5 5.411 14.5 L 5.411 14.504 Z"/>
|
|
111
|
+
<line x1="14.5" y1="3.25" x2="14.5" y2="1.25"/>
|
|
112
|
+
<line x1="14.5" y1="15.85" x2="14.5" y2="17.85"/>
|
|
113
|
+
<line x1="10.044" y1="5.094" x2="8.63" y2="3.68"/>
|
|
114
|
+
<line x1="19" y1="14.05" x2="20.414" y2="15.464"/>
|
|
115
|
+
<line x1="8.2" y1="9.55" x2="6.2" y2="9.55"/>
|
|
116
|
+
<line x1="20.8" y1="9.55" x2="22.8" y2="9.55"/>
|
|
117
|
+
<line x1="10.044" y1="14.006" x2="8.63" y2="15.42"/>
|
|
118
|
+
<line x1="19" y1="5.05" x2="20.414" y2="3.636"/>
|
|
119
|
+
<circle cx="14.5" cy="9.55" r="3.6"/>
|
|
120
|
+
</svg>
|
|
121
|
+
</symbol>
|
|
122
|
+
<symbol id="svg-moon-with-sun" viewBox="0 0 24 24">
|
|
123
|
+
<title>Auto light/dark, in dark mode</title>
|
|
124
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
125
|
+
stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
|
|
126
|
+
class="icon-custom-derived-from-feather-sun-and-tabler-moon">
|
|
127
|
+
<path d="M 8.282 7.007 C 8.385 7.007 8.494 7.007 8.595 7.007 C 5.18 10.184 6.481 15.869 10.942 17.24 C 12.275 17.648 13.706 17.589 15 17.066 C 12.851 22.236 5.91 23.143 2.505 18.696 C -0.897 14.249 1.791 7.786 7.342 7.063 C 7.652 7.021 7.965 7 8.282 7 L 8.282 7.007 Z"/>
|
|
128
|
+
<line style="opacity: 50%" x1="18" y1="3.705" x2="18" y2="2.5"/>
|
|
129
|
+
<line style="opacity: 50%" x1="18" y1="11.295" x2="18" y2="12.5"/>
|
|
130
|
+
<line style="opacity: 50%" x1="15.316" y1="4.816" x2="14.464" y2="3.964"/>
|
|
131
|
+
<line style="opacity: 50%" x1="20.711" y1="10.212" x2="21.563" y2="11.063"/>
|
|
132
|
+
<line style="opacity: 50%" x1="14.205" y1="7.5" x2="13.001" y2="7.5"/>
|
|
133
|
+
<line style="opacity: 50%" x1="21.795" y1="7.5" x2="23" y2="7.5"/>
|
|
134
|
+
<line style="opacity: 50%" x1="15.316" y1="10.184" x2="14.464" y2="11.036"/>
|
|
135
|
+
<line style="opacity: 50%" x1="20.711" y1="4.789" x2="21.563" y2="3.937"/>
|
|
136
|
+
<circle style="opacity: 50%" cx="18" cy="7.5" r="2.169"/>
|
|
137
|
+
</svg>
|
|
138
|
+
</symbol>
|
|
139
|
+
<symbol id="svg-pencil" viewBox="0 0 24 24">
|
|
140
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
141
|
+
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-pencil-code">
|
|
142
|
+
<path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" />
|
|
143
|
+
<path d="M13.5 6.5l4 4" />
|
|
144
|
+
<path d="M20 21l2 -2l-2 -2" />
|
|
145
|
+
<path d="M17 17l-2 2l2 2" />
|
|
146
|
+
</svg>
|
|
147
|
+
</symbol>
|
|
148
|
+
<symbol id="svg-eye" viewBox="0 0 24 24">
|
|
149
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
150
|
+
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-eye-code">
|
|
151
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
152
|
+
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
|
153
|
+
<path
|
|
154
|
+
d="M11.11 17.958c-3.209 -.307 -5.91 -2.293 -8.11 -5.958c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6c-.21 .352 -.427 .688 -.647 1.008" />
|
|
155
|
+
<path d="M20 21l2 -2l-2 -2" />
|
|
156
|
+
<path d="M17 17l-2 2l2 2" />
|
|
157
|
+
</svg>
|
|
158
|
+
</symbol>
|
|
159
|
+
</svg>
|
|
160
|
+
|
|
161
|
+
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation" aria-label="Toggle site navigation sidebar">
|
|
162
|
+
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc" aria-label="Toggle table of contents sidebar">
|
|
163
|
+
<label class="overlay sidebar-overlay" for="__navigation"></label>
|
|
164
|
+
<label class="overlay toc-overlay" for="__toc"></label>
|
|
165
|
+
|
|
166
|
+
<a class="skip-to-content muted-link" href="#furo-main-content">Skip to content</a>
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
<div class="page">
|
|
171
|
+
<header class="mobile-header">
|
|
172
|
+
<div class="header-left">
|
|
173
|
+
<label class="nav-overlay-icon" for="__navigation">
|
|
174
|
+
<span class="icon"><svg><use href="#svg-menu"></use></svg></span>
|
|
175
|
+
</label>
|
|
176
|
+
</div>
|
|
177
|
+
<div class="header-center">
|
|
178
|
+
<a href="index.html"><div class="brand">SimStack II documentation</div></a>
|
|
179
|
+
</div>
|
|
180
|
+
<div class="header-right">
|
|
181
|
+
<div class="theme-toggle-container theme-toggle-header">
|
|
182
|
+
<button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
|
|
183
|
+
<svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
|
|
184
|
+
<svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
|
|
185
|
+
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
|
186
|
+
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
|
187
|
+
</button>
|
|
188
|
+
</div>
|
|
189
|
+
<label class="toc-overlay-icon toc-header-icon" for="__toc">
|
|
190
|
+
<span class="icon"><svg><use href="#svg-toc"></use></svg></span>
|
|
191
|
+
</label>
|
|
192
|
+
</div>
|
|
193
|
+
</header>
|
|
194
|
+
<aside class="sidebar-drawer">
|
|
195
|
+
<div class="sidebar-container">
|
|
196
|
+
|
|
197
|
+
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
|
201
|
+
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
|
|
202
|
+
<input type="hidden" name="check_keywords" value="yes">
|
|
203
|
+
<input type="hidden" name="area" value="default">
|
|
204
|
+
</form>
|
|
205
|
+
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
|
206
|
+
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
|
207
|
+
<ul class="current">
|
|
208
|
+
<li class="toctree-l1"><a class="reference internal" href="overview.html">Overview</a></li>
|
|
209
|
+
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">Workflows</a></li>
|
|
210
|
+
<li class="toctree-l1"><a class="reference internal" href="ui_documentation.html">Graphical User Interface</a></li>
|
|
211
|
+
<li class="toctree-l1 has-children"><a class="reference internal" href="developer_guide.html">Developer Guide</a><input aria-label="Toggle navigation of Developer Guide" class="toctree-checkbox" id="toctree-checkbox-1" name="toctree-checkbox-1" role="switch" type="checkbox"/><label for="toctree-checkbox-1"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
|
|
212
|
+
<li class="toctree-l2"><a class="reference internal" href="data.html">Persisting and Visualizing Data</a></li>
|
|
213
|
+
<li class="toctree-l2"><a class="reference internal" href="datasets.html">Datasets</a></li>
|
|
214
|
+
<li class="toctree-l2"><a class="reference internal" href="lists.html">List Mixins</a></li>
|
|
215
|
+
<li class="toctree-l2"><a class="reference internal" href="array_lists.html">Array Lists</a></li>
|
|
216
|
+
<li class="toctree-l2"><a class="reference internal" href="tables.html">Tables</a></li>
|
|
217
|
+
<li class="toctree-l2"><a class="reference internal" href="files.html">File Management</a></li>
|
|
218
|
+
<li class="toctree-l2"><a class="reference internal" href="resource_config.html">Program Execution</a></li>
|
|
219
|
+
<li class="toctree-l2"><a class="reference internal" href="mass_runner.html">MassRunner</a></li>
|
|
220
|
+
<li class="toctree-l2"><a class="reference internal" href="fire_and_forget_runner.html">FireAndForgetRunner</a></li>
|
|
221
|
+
<li class="toctree-l2"><a class="reference internal" href="docker_nodes.html">Creating Docker Containers for SimStack Nodes</a></li>
|
|
222
|
+
<li class="toctree-l2"><a class="reference internal" href="testing_complex_nodes.html">Testing Complex Nodes</a></li>
|
|
223
|
+
<li class="toctree-l2"><a class="reference internal" href="database_migrations.html">Database Migrations</a></li>
|
|
224
|
+
<li class="toctree-l2"><a class="reference internal" href="ci_pipeline.html">CI Pipeline and Documentation Artifacts</a></li>
|
|
225
|
+
<li class="toctree-l2"><a class="reference internal" href="misc.html">Miscellaneous</a></li>
|
|
226
|
+
</ul>
|
|
227
|
+
</li>
|
|
228
|
+
<li class="toctree-l1"><a class="reference internal" href="installation.html">Simstack II Setup</a></li>
|
|
229
|
+
<li class="toctree-l1 has-children"><a class="reference internal" href="simstack/modules/modules.html">simstack</a><input aria-label="Toggle navigation of simstack" class="toctree-checkbox" id="toctree-checkbox-2" name="toctree-checkbox-2" role="switch" type="checkbox"/><label for="toctree-checkbox-2"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
|
|
230
|
+
<li class="toctree-l2 has-children"><a class="reference internal" href="simstack/modules/simstack.html">simstack package</a><input aria-label="Toggle navigation of simstack package" class="toctree-checkbox" id="toctree-checkbox-3" name="toctree-checkbox-3" role="switch" type="checkbox"/><label for="toctree-checkbox-3"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
|
|
231
|
+
<li class="toctree-l3 has-children"><a class="reference internal" href="simstack/modules/simstack.core.html">simstack.core package</a><input aria-label="Toggle navigation of simstack.core package" class="toctree-checkbox" id="toctree-checkbox-4" name="toctree-checkbox-4" role="switch" type="checkbox"/><label for="toctree-checkbox-4"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
|
|
232
|
+
<li class="toctree-l4"><a class="reference internal" href="simstack/modules/simstack.core.services.html">simstack.core.services package</a></li>
|
|
233
|
+
</ul>
|
|
234
|
+
</li>
|
|
235
|
+
<li class="toctree-l3"><a class="reference internal" href="simstack/modules/simstack.methods.html">simstack.methods package</a></li>
|
|
236
|
+
<li class="toctree-l3"><a class="reference internal" href="simstack/modules/simstack.models.html">simstack.models package</a></li>
|
|
237
|
+
<li class="toctree-l3"><a class="reference internal" href="simstack/modules/simstack.tables.html">simstack.tables package</a></li>
|
|
238
|
+
<li class="toctree-l3"><a class="reference internal" href="simstack/modules/simstack.util.html">simstack.util package</a></li>
|
|
239
|
+
</ul>
|
|
240
|
+
</li>
|
|
241
|
+
</ul>
|
|
242
|
+
</li>
|
|
243
|
+
</ul>
|
|
244
|
+
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
</div>
|
|
251
|
+
</aside>
|
|
252
|
+
<div class="main">
|
|
253
|
+
<div class="content">
|
|
254
|
+
<div class="article-container">
|
|
255
|
+
<a href="#" class="back-to-top muted-link">
|
|
256
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
257
|
+
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
|
|
258
|
+
</svg>
|
|
259
|
+
<span>Back to top</span>
|
|
260
|
+
</a>
|
|
261
|
+
<div class="content-icon-container">
|
|
262
|
+
<div class="view-this-page">
|
|
263
|
+
<a class="muted-link" href="_sources/workflows.rst.txt" title="View this page">
|
|
264
|
+
<svg><use href="#svg-eye"></use></svg>
|
|
265
|
+
<span class="visually-hidden">View this page</span>
|
|
266
|
+
</a>
|
|
267
|
+
</div>
|
|
268
|
+
<div class="theme-toggle-container theme-toggle-content">
|
|
269
|
+
<button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
|
|
270
|
+
<svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
|
|
271
|
+
<svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
|
|
272
|
+
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
|
273
|
+
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
|
274
|
+
</button>
|
|
275
|
+
</div>
|
|
276
|
+
<label class="toc-overlay-icon toc-content-icon" for="__toc">
|
|
277
|
+
<span class="icon"><svg><use href="#svg-toc"></use></svg></span>
|
|
278
|
+
</label>
|
|
279
|
+
</div>
|
|
280
|
+
<article role="main" id="furo-main-content">
|
|
281
|
+
<section id="workflows">
|
|
282
|
+
<span id="id1"></span><h1>Workflows<a class="headerlink" href="#workflows" title="Link to this heading">¶</a></h1>
|
|
283
|
+
<div class="admonition note">
|
|
284
|
+
<p class="admonition-title">Note</p>
|
|
285
|
+
<p>This section is intended for workflow developers but also helpful to users. A more detailed how-to for nodes is given in <span class="xref std std-ref">developer-guide</span></p>
|
|
286
|
+
</div>
|
|
287
|
+
<section id="from-python-to-workflows">
|
|
288
|
+
<h2>From Python to Workflows<a class="headerlink" href="#from-python-to-workflows" title="Link to this heading">¶</a></h2>
|
|
289
|
+
<p>The following section is intended to guide developers who are familiar with python to transform their code
|
|
290
|
+
into Simstack II. We will introduce the concepts step by step, starting with a simple python “workflow”.
|
|
291
|
+
Workflows are comprised of nodes, which are implemented as python functions.</p>
|
|
292
|
+
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">adder</span><span class="p">(</span><span class="n">arg1</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">arg2</span><span class="p">:</span> <span class="nb">float</span><span class="p">)</span> <span class="o">-></span> <span class="nb">float</span><span class="p">:</span>
|
|
293
|
+
<span class="k">return</span> <span class="n">arg1</span> <span class="o">+</span> <span class="n">arg2</span>
|
|
294
|
+
|
|
295
|
+
<span class="k">def</span><span class="w"> </span><span class="nf">multiplier</span><span class="p">(</span><span class="n">arg1</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">arg2</span><span class="p">:</span> <span class="nb">float</span><span class="p">)</span> <span class="o">-></span> <span class="nb">float</span><span class="p">:</span>
|
|
296
|
+
<span class="k">return</span> <span class="n">arg1</span> <span class="o">*</span> <span class="n">arg2</span>
|
|
297
|
+
|
|
298
|
+
<span class="k">def</span><span class="w"> </span><span class="nf">add_multiply_python</span><span class="p">(</span><span class="n">arg1</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">arg2</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">arg3</span><span class="p">:</span> <span class="nb">float</span><span class="p">)</span> <span class="o">-></span> <span class="nb">float</span><span class="p">:</span>
|
|
299
|
+
<span class="n">add_result</span> <span class="o">=</span> <span class="n">adder</span><span class="p">(</span><span class="n">arg1</span><span class="p">,</span> <span class="n">arg2</span><span class="p">)</span>
|
|
300
|
+
<span class="n">multiply_result</span> <span class="o">=</span> <span class="n">multiplier</span><span class="p">(</span><span class="n">add_result</span><span class="p">,</span> <span class="n">arg3</span><span class="p">)</span>
|
|
301
|
+
<span class="k">return</span> <span class="n">multiply_result</span>
|
|
302
|
+
</pre></div>
|
|
303
|
+
</div>
|
|
304
|
+
<p>In this code we have three nodes, <cite>adder</cite>, <cite>multiplier</cite>, and <cite>add_multiply_python</cite>. The first two nodes are simple
|
|
305
|
+
functions, the last function nests the 2 simple functions, making this function a template for a workflow.</p>
|
|
306
|
+
<p>To transform this code into a Simstack II workflow, we want to introduce minimal changes to the code above to accomplish
|
|
307
|
+
the following:</p>
|
|
308
|
+
<ul class="simple">
|
|
309
|
+
<li><p>One or more of the functions should be visible and startable in the GUI</p></li>
|
|
310
|
+
<li><p>The results of the nodes should be persisted in the database and visible in the GUI</p></li>
|
|
311
|
+
<li><p>The nodes should be executable on remote resources</p></li>
|
|
312
|
+
</ul>
|
|
313
|
+
<p>To achievieve this, we need to make the following changes in the code:</p>
|
|
314
|
+
<ul class="simple">
|
|
315
|
+
<li><p>decorate the functions that should be visible in the GUI with the <cite>@node</cite> decorator</p></li>
|
|
316
|
+
<li><p>ensure that all input and output types of the nodes are registered odmantic Models</p></li>
|
|
317
|
+
<li><p>specifiy where the nodes should be executed</p></li>
|
|
318
|
+
</ul>
|
|
319
|
+
<p>For the specific example above the code looks as follows:</p>
|
|
320
|
+
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nd">@node</span><span class="p">(</span><span class="n">parameters</span><span class="o">=</span><span class="n">Parameters</span><span class="p">(</span><span class="n">resource</span><span class="o">=</span><span class="s2">"my-remote-host"</span><span class="p">,</span> <span class="n">queue</span><span class="o">=</span><span class="s2">"slurm-queue"</span><span class="p">))</span>
|
|
321
|
+
<span class="k">def</span><span class="w"> </span><span class="nf">adder</span><span class="p">(</span><span class="n">arg1</span><span class="p">:</span> <span class="n">FloatData</span><span class="p">,</span> <span class="n">arg2</span><span class="p">:</span> <span class="n">FloatData</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-></span> <span class="n">FloatData</span><span class="p">:</span>
|
|
322
|
+
<span class="k">return</span> <span class="n">FloatData</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s2">"adder_result"</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">arg1</span><span class="o">.</span><span class="n">value</span> <span class="o">+</span> <span class="n">arg2</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
|
|
323
|
+
|
|
324
|
+
<span class="nd">@node</span><span class="p">(</span><span class="n">parameters</span><span class="o">=</span><span class="n">Parameters</span><span class="p">(</span><span class="n">resource</span><span class="o">=</span><span class="s2">"my-remote-host"</span><span class="p">,</span> <span class="n">queue</span><span class="o">=</span><span class="s2">"default"</span><span class="p">))</span>
|
|
325
|
+
<span class="k">def</span><span class="w"> </span><span class="nf">multiplier</span><span class="p">(</span><span class="n">arg1</span><span class="p">:</span> <span class="n">FloatData</span><span class="p">,</span> <span class="n">arg2</span><span class="p">:</span> <span class="n">FloatData</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-></span> <span class="n">FloatData</span><span class="p">:</span>
|
|
326
|
+
<span class="k">return</span> <span class="n">FloatData</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s2">"multiplier_result"</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">arg1</span><span class="o">.</span><span class="n">value</span> <span class="o">*</span> <span class="n">arg2</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
|
|
327
|
+
|
|
328
|
+
<span class="nd">@node</span>
|
|
329
|
+
<span class="k">def</span><span class="w"> </span><span class="nf">add_multiply_python</span><span class="p">(</span><span class="n">arg1</span><span class="p">:</span> <span class="n">FloatData</span><span class="p">,</span> <span class="n">arg2</span><span class="p">:</span> <span class="n">FloatData</span><span class="p">,</span> <span class="n">arg3</span><span class="p">:</span> <span class="n">FloatData</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-></span> <span class="n">FloatData</span><span class="p">:</span>
|
|
330
|
+
<span class="n">add_result</span> <span class="o">=</span> <span class="n">adder</span><span class="p">(</span><span class="n">arg1</span><span class="p">,</span> <span class="n">arg2</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="c1"># note passing the kwargs!!!!</span>
|
|
331
|
+
<span class="n">multiply_result</span> <span class="o">=</span> <span class="n">multiplier</span><span class="p">(</span><span class="n">add_result</span><span class="p">,</span> <span class="n">arg3</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
332
|
+
<span class="k">return</span> <span class="n">multiply_result</span>
|
|
333
|
+
</pre></div>
|
|
334
|
+
</div>
|
|
335
|
+
<p>The first thing you notice is that the datatypes have changed. Since int, floats etc appear a lot, Simstack provides
|
|
336
|
+
models for these types (see: <a class="reference internal" href="simstack/modules/simstack.models.html#module-simstack.models.base_types" title="simstack.models.base_types"><code class="xref py py-mod docutils literal notranslate"><span class="pre">simstack.models.base_types</span></code></a>).</p>
|
|
337
|
+
<p>The @node decorator embeds the simple python functions into a complex workflow class
|
|
338
|
+
(see: <a class="reference internal" href="simstack/modules/simstack.core.html#simstack.core.node.node" title="simstack.core.node.node"><code class="xref py py-func docutils literal notranslate"><span class="pre">simstack.core.node.node()</span></code></a> in module: <a class="reference internal" href="simstack/modules/simstack.core.html#module-simstack.core.node" title="simstack.core.node"><code class="xref py py-mod docutils literal notranslate"><span class="pre">simstack.core.node</span></code></a>).</p>
|
|
339
|
+
<p>To allow Simstack II with new data models you need to register them once, see <span class="xref std std-ref">persisting_models</span>.
|
|
340
|
+
In order execute nodes via the UI you need to register the nodes. This would result in a workflow where all nodes are
|
|
341
|
+
visible in the GUI (<span class="xref std std-ref">submitting-workflows</span>).
|
|
342
|
+
The nodes <cite>adder</cite> and <cite>multiplier</cite> would be executed on a runner running on “my-remote-host”.
|
|
343
|
+
The adder would be submitted to the “slurm-queue” and the multiplier would be executed immediately in the foreground.
|
|
344
|
+
add_multiply_python would be executed on the default resource by a runner called <cite>local</cite>. You can change these defaults in the UI.
|
|
345
|
+
The relationship between the classes in the code, the tables in the database
|
|
346
|
+
and the representation of this data in the GUI, these models are discussed in <span class="xref std std-ref">persisting-results-section</span>.</p>
|
|
347
|
+
<p>Here are some ground rules to write workflows in Simstack II:</p>
|
|
348
|
+
<div class="admonition important">
|
|
349
|
+
<p class="admonition-title">Important</p>
|
|
350
|
+
<ul class="simple">
|
|
351
|
+
<li><p>Node functions must have a <strong>unique name</strong> (across the whole installation).</p></li>
|
|
352
|
+
<li><p>Node functions must have the <strong>**kwargs argument</strong></p></li>
|
|
353
|
+
<li><p>Node functions must <strong>pass</strong> the **kwargs argument to nodes they call</p></li>
|
|
354
|
+
<li><p>Node functions must be <strong>registered in the node_model table</strong> of the database
|
|
355
|
+
by running make_node_table (<a class="reference internal" href="#registering"><span class="std std-ref">Registering Models and Nodes</span></a>)</p></li>
|
|
356
|
+
<li><p>All positional arguments of node functions must be <strong>registered Models</strong> in the model_table of the database
|
|
357
|
+
by running make_model_table (<a class="reference internal" href="#registering"><span class="std std-ref">Registering Models and Nodes</span></a>). Presently kwargs for models are not supported.</p></li>
|
|
358
|
+
</ul>
|
|
359
|
+
</div>
|
|
360
|
+
<p>Beyond that nodes functions are normal python functions which can use the full flexibility of python.
|
|
361
|
+
The can call other functions or other nodes, but should <strong>avoid “closures”</strong>, such as global variables.
|
|
362
|
+
For this reason, node function should <strong>not be class members</strong> unless they are class members of an odmantic model.</p>
|
|
363
|
+
<p>You can consult the documentation of this class to understand how this works but this is not required to write
|
|
364
|
+
workflows.</p>
|
|
365
|
+
<p>The choice, whether a function is a “normal” function or a node is influenced
|
|
366
|
+
by the following considerations:</p>
|
|
367
|
+
<ul class="simple">
|
|
368
|
+
<li><p>Only nodes are visible in the GUI</p></li>
|
|
369
|
+
<li><p>only nodes can be executed automatically on remote resources</p></li>
|
|
370
|
+
<li><p>in principle nodes can call normal functions which can call nodes, as long as the **kwargs
|
|
371
|
+
are passed correctly</p></li>
|
|
372
|
+
</ul>
|
|
373
|
+
<section id="return-types">
|
|
374
|
+
<h3>Return Types<a class="headerlink" href="#return-types" title="Link to this heading">¶</a></h3>
|
|
375
|
+
<p>In workflows, the results of node functions must be visible in the databse and may be
|
|
376
|
+
processed by other nodes. This means that <strong>results</strong> of the nodes must by odmantic models which
|
|
377
|
+
can be visualized in the GUI and passed to other nodes which may execute on different resources.</p>
|
|
378
|
+
<p>In order to encapsulate data processing, this essentially <strong>precludes the use
|
|
379
|
+
of files as relevant results</strong>. Many terminal nodes will call external
|
|
380
|
+
programs that return their output in file format. In Simstack, all human
|
|
381
|
+
readable content of these files should be <strong>parsed into Simstack Model types</strong>
|
|
382
|
+
that can be stored in the database. In many cases the output files of
|
|
383
|
+
terminal nodes will nevertheless be required input by other terminal nodes. In
|
|
384
|
+
order to facilitate processing, references to these files should be stored in
|
|
385
|
+
the output to avoid error-prone parsing and recreation.</p>
|
|
386
|
+
<p>THe following return types od node_functions are supported:</p>
|
|
387
|
+
<ul class="simple">
|
|
388
|
+
<li><p>any <strong>registered</strong> Model (<a class="reference internal" href="#registering"><span class="std std-ref">Registering Models and Nodes</span></a>),</p></li>
|
|
389
|
+
<li><p>True or False, the indicating success or failure,</p></li>
|
|
390
|
+
<li><p>a class derived from SimstackResult, in particular NodeRunner,</p></li>
|
|
391
|
+
<li><p>None will result in failure</p></li>
|
|
392
|
+
</ul>
|
|
393
|
+
<p><a class="reference internal" href="simstack/modules/simstack.core.html#simstack.core.simstack_result.SimstackResult" title="simstack.core.simstack_result.SimstackResult"><code class="xref py py-class docutils literal notranslate"><span class="pre">simstack.core.simstack_result.SimstackResult</span></code></a> provides a framework to
|
|
394
|
+
return more than one result, including files and info_files to the calling
|
|
395
|
+
function. The class NodeRunner is a child class of SimstackResult and
|
|
396
|
+
provides useful helper functions to manage results, files and logging
|
|
397
|
+
(see below).</p>
|
|
398
|
+
</section>
|
|
399
|
+
<section id="the-noderunner-helper-class">
|
|
400
|
+
<h3>The Noderunner Helper Class<a class="headerlink" href="#the-noderunner-helper-class" title="Link to this heading">¶</a></h3>
|
|
401
|
+
<p><a class="reference internal" href="simstack/modules/simstack.core.html#simstack.core.node_runner.NodeRunner" title="simstack.core.node_runner.NodeRunner"><code class="xref py py-class docutils literal notranslate"><span class="pre">simstack.core.node_runner.NodeRunner</span></code></a> instances provide
|
|
402
|
+
useful quality-of-life features from logging to
|
|
403
|
+
the management of results. In realistic applications, nodes generate a lot of
|
|
404
|
+
auxiliary data, such as log-files of external programs, that are not results,
|
|
405
|
+
but useful to keep track of the data-flow. To facilitate oversight over
|
|
406
|
+
nodes that are executed remotely, it is useful to capture the available
|
|
407
|
+
output of nodes, even when they fail. The NodeRunner
|
|
408
|
+
class offers some quality-of-life features for this. Each node is passed an
|
|
409
|
+
instance of NodeRunner in the **kwargs.</p>
|
|
410
|
+
<p>You can add output by:</p>
|
|
411
|
+
<ul class="simple">
|
|
412
|
+
<li><p>adding any <strong>registered</strong> Models to the node_runner as attributes</p></li>
|
|
413
|
+
<li><p>appending FileStack instances to node_runner.files</p></li>
|
|
414
|
+
<li><p>appending FileStack instances to node_runner.info_files</p></li>
|
|
415
|
+
</ul>
|
|
416
|
+
<p><strong>Node Example with NodeRunner</strong></p>
|
|
417
|
+
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nd">@node</span>
|
|
418
|
+
<span class="k">def</span><span class="w"> </span><span class="nf">my_node</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-></span> <span class="n">SimstackResult</span>
|
|
419
|
+
<span class="c1"># get the supplied node_runner first</span>
|
|
420
|
+
<span class="n">node_runner</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'node_runner'</span><span class="p">,</span><span class="kc">None</span><span class="p">)</span>
|
|
421
|
+
<span class="k">if</span> <span class="n">node_runner</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
422
|
+
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'no node_runner'</span><span class="p">)</span>
|
|
423
|
+
<span class="c1"># your code here ....</span>
|
|
424
|
+
|
|
425
|
+
<span class="n">file_with_data</span> <span class="o">=</span> <span class="n">FileStack</span><span class="o">.</span><span class="n">from_local_file</span><span class="p">(</span><span class="s2">"my_important_file.dat"</span><span class="p">)</span>
|
|
426
|
+
<span class="n">node_runner</span><span class="o">.</span><span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">file_with_data</span><span class="p">)</span> <span class="c1"># file_with_data will be added</span>
|
|
427
|
+
<span class="c1"># automatically to the result</span>
|
|
428
|
+
<span class="c1"># table of the NodeRegistry</span>
|
|
429
|
+
<span class="c1"># entry</span>
|
|
430
|
+
|
|
431
|
+
<span class="n">some_file_with_log_output</span> <span class="o">=</span> <span class="n">FileStack</span><span class="o">.</span><span class="n">from_local_file</span><span class="p">(</span><span class="s2">"my_log.txt"</span><span class="p">)</span>
|
|
432
|
+
<span class="c1"># will not be added to the result tables but to the info_files tab or the node and</span>
|
|
433
|
+
<span class="c1"># can be inspected in the gui for potential problems or output</span>
|
|
434
|
+
<span class="c1"># that has not been parsed.</span>
|
|
435
|
+
<span class="n">node_runner</span><span class="o">.</span><span class="n">make_info_files</span><span class="p">(</span><span class="n">some_file_with_log_output</span><span class="p">)</span>
|
|
436
|
+
|
|
437
|
+
<span class="k">if</span> <span class="n">some_error</span><span class="p">:</span>
|
|
438
|
+
<span class="c1"># this error will be caught in the calling function</span>
|
|
439
|
+
<span class="c1"># which will post-process the results above this line</span>
|
|
440
|
+
<span class="c1"># but set the task_status to TaskStatus.FAILED</span>
|
|
441
|
+
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Something went wrong"</span><span class="p">)</span>
|
|
442
|
+
|
|
443
|
+
<span class="n">my_data</span> <span class="o">=</span> <span class="n">ArrayStorage</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"my cool numpy result"</span><span class="p">)</span>
|
|
444
|
+
<span class="n">my_data</span><span class="o">.</span><span class="n">set_array</span><span class="p">(</span><span class="n">numpy_array</span><span class="p">)</span>
|
|
445
|
+
<span class="n">node_runner</span><span class="o">.</span><span class="n">my_data</span> <span class="o">=</span> <span class="n">my_data</span> <span class="c1"># will also be added to the result table</span>
|
|
446
|
+
|
|
447
|
+
<span class="k">return</span> <span class="n">node_runner</span><span class="o">.</span><span class="n">succeed</span><span class="p">(</span><span class="s2">"happy ending"</span><span class="p">)</span> <span class="c1"># node_runner is a child</span>
|
|
448
|
+
<span class="c1"># class of SimstackResult</span>
|
|
449
|
+
</pre></div>
|
|
450
|
+
</div>
|
|
451
|
+
<div class="admonition note">
|
|
452
|
+
<p class="admonition-title">Note</p>
|
|
453
|
+
<p>NodeRunner.make_info_files(file1,file2,pattern1,pattern2) is a more clever way to append many files to the info_files list.
|
|
454
|
+
NodeRunner.info_file_patterns defines a standard set of endings to include automatically</p>
|
|
455
|
+
</div>
|
|
456
|
+
<div class="admonition note">
|
|
457
|
+
<p class="admonition-title">Note</p>
|
|
458
|
+
<p>The instance of NodeRunner passed from the calling function, will be
|
|
459
|
+
post-processed by the calling function even when the node fails. This allows
|
|
460
|
+
capturing of partial output, in particular the info_files.</p>
|
|
461
|
+
</div>
|
|
462
|
+
<div class="admonition note">
|
|
463
|
+
<p class="admonition-title">Note</p>
|
|
464
|
+
<p>The call to your actual function is always wrapped in a try-except-block.
|
|
465
|
+
In most scenarios you do not need your own try-except-finally blocks in the
|
|
466
|
+
node</p>
|
|
467
|
+
</div>
|
|
468
|
+
<p><strong>Data Provided by **kwargs</strong></p>
|
|
469
|
+
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">node_runner</span> <span class="o">=</span> <span class="n">NodeRunner</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_func</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">task_id</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
|
|
470
|
+
<span class="n">node_kwargs</span> <span class="o">=</span> <span class="p">{</span>
|
|
471
|
+
<span class="s1">'node_runner'</span><span class="p">:</span> <span class="n">node_runner</span><span class="p">,</span>
|
|
472
|
+
<span class="s1">'parent_id'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="c1"># DO NOT CHANGE & pass to children</span>
|
|
473
|
+
|
|
474
|
+
<span class="s1">'task_id'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="c1"># DO NOT CHANGE & pass</span>
|
|
475
|
+
<span class="s1">'call_path'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">call_path</span><span class="p">,</span> <span class="c1"># DO NOT CHANGE &</span>
|
|
476
|
+
<span class="s1">'parent_parameters'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">parameters</span><span class="p">,</span> <span class="c1"># this must have a name different from parameters, because</span>
|
|
477
|
+
<span class="c1"># otherwise this setting will override all the parameters of</span>
|
|
478
|
+
<span class="c1"># the child nodes</span>
|
|
479
|
+
<span class="s1">'recompute_artifacts'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">recompute_artifacts</span><span class="p">,</span>
|
|
480
|
+
<span class="s1">'custom_name'</span> <span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">custom_name</span>
|
|
481
|
+
<span class="p">}</span>
|
|
482
|
+
|
|
483
|
+
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">force_rerun</span><span class="p">:</span>
|
|
484
|
+
<span class="n">node_kwargs</span><span class="p">[</span><span class="s1">'force_rerun'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
|
485
|
+
</pre></div>
|
|
486
|
+
</div>
|
|
487
|
+
<p><strong>Logging</strong></p>
|
|
488
|
+
<p>In order to keep track of the node execution, the Simstack core modules and
|
|
489
|
+
user written nodes should write logs. Simstack will initialize a custom
|
|
490
|
+
database logger which will be added to the logging system. In your node you
|
|
491
|
+
can therefore just instantiate and use a logger</p>
|
|
492
|
+
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">logging</span>
|
|
493
|
+
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">"name"</span><span class="p">)</span>
|
|
494
|
+
|
|
495
|
+
<span class="nd">@node</span>
|
|
496
|
+
<span class="k">def</span><span class="w"> </span><span class="nf">my_node</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-></span> <span class="n">SimstackResult</span>
|
|
497
|
+
|
|
498
|
+
<span class="n">node_runner</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">'node_runner'</span><span class="p">]</span> <span class="c1"># should never fail</span>
|
|
499
|
+
|
|
500
|
+
<span class="c1"># this will log to the database and be visible in the general logs</span>
|
|
501
|
+
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">"Some message I will never find"</span><span class="p">)</span>
|
|
502
|
+
|
|
503
|
+
<span class="c1"># this will be shown in a special tab called task-logs which collects</span>
|
|
504
|
+
<span class="c1"># only messages for this node</span>
|
|
505
|
+
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"task_id: </span><span class="si">{</span><span class="n">node_runner</span><span class="o">.</span><span class="n">task_id</span><span class="si">}</span><span class="s2"> informative message"</span><span class="p">)</span>
|
|
506
|
+
|
|
507
|
+
<span class="c1"># node_runner will add the task_id info</span>
|
|
508
|
+
<span class="n">node_runner</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">"another informative message"</span><span class="p">)</span>
|
|
509
|
+
</pre></div>
|
|
510
|
+
</div>
|
|
511
|
+
<p>The node_runner helper functions are provided for all log-levels.</p>
|
|
512
|
+
<div class="admonition note">
|
|
513
|
+
<p class="admonition-title">Note</p>
|
|
514
|
+
<p>Simstack generates a lot of log messages. Use the task_id mechanism as
|
|
515
|
+
much as possible to provide useful info</p>
|
|
516
|
+
</div>
|
|
517
|
+
<p><strong>Executing external programs</strong></p>
|
|
518
|
+
<p>The NodeRunner class provides <code class="xref py py-func docutils literal notranslate"><span class="pre">simstack.core.NodeRunner.subprocess()</span></code> to
|
|
519
|
+
facilitate execution of external programs. This helper function will execute
|
|
520
|
+
a command in the current shell and automatically add standard output and
|
|
521
|
+
error to the info_files of the node. The function returns True/False upon
|
|
522
|
+
success and failure. Stdout and sterr of the last command are also stored in
|
|
523
|
+
attributes so that they can be parsed by the node.</p>
|
|
524
|
+
</section>
|
|
525
|
+
<section id="node-decorator-arguments">
|
|
526
|
+
<h3>Node Decorator Arguments<a class="headerlink" href="#node-decorator-arguments" title="Link to this heading">¶</a></h3>
|
|
527
|
+
<p>The node decorator may have arguments.</p>
|
|
528
|
+
<ul class="simple">
|
|
529
|
+
<li><p>Parameters: <a class="reference internal" href="simstack/modules/simstack.models.html#simstack.models.Parameters" title="simstack.models.Parameters"><code class="xref py py-class docutils literal notranslate"><span class="pre">simstack.models.Parameters</span></code></a> where and how shall the node
|
|
530
|
+
be executed</p></li>
|
|
531
|
+
<li><p>force_rerun: force execution of the node, but not the children</p></li>
|
|
532
|
+
<li><p>recompute artifacts: without executing the node or its children recompute
|
|
533
|
+
all artifacts.</p></li>
|
|
534
|
+
</ul>
|
|
535
|
+
<p>The <a class="reference internal" href="simstack/modules/simstack.models.html#simstack.models.parameters.Parameters" title="simstack.models.parameters.Parameters"><code class="xref py py-class docutils literal notranslate"><span class="pre">simstack.models.parameters.Parameters</span></code></a> can specify</p>
|
|
536
|
+
<ul class="simple">
|
|
537
|
+
<li><p>a resource <a class="reference internal" href="simstack/modules/simstack.models.html#simstack.models.parameters.Resource" title="simstack.models.parameters.Resource"><code class="xref py py-class docutils literal notranslate"><span class="pre">simstack.models.parameters.Resource</span></code></a> which must be one
|
|
538
|
+
of the resource names listed in the configuration file(<a class="reference internal" href="installation.html#configuration-file"><span class="std std-ref">Create simstack.toml</span></a>).
|
|
539
|
+
Specifying the resource <code class="docutils literal notranslate"><span class="pre">self</span></code> (the default) means that the node will be
|
|
540
|
+
executed on the same resource as the calling node.</p></li>
|
|
541
|
+
<li><p>a queue (makes sense only for remote resources), with values <code class="docutils literal notranslate"><span class="pre">default</span></code> for
|
|
542
|
+
immediate execution, <code class="docutils literal notranslate"><span class="pre">slurm_queue</span></code> for submission to the batch system by
|
|
543
|
+
slurm</p></li>
|
|
544
|
+
</ul>
|
|
545
|
+
<p>The slurm parameters are specified in Parameters has an attribute
|
|
546
|
+
<code class="docutils literal notranslate"><span class="pre">slurm_parameters</span></code> of type: <a class="reference internal" href="simstack/modules/simstack.models.html#simstack.models.parameters.SlurmParameters" title="simstack.models.parameters.SlurmParameters"><code class="xref py py-class docutils literal notranslate"><span class="pre">simstack.models.parameters.SlurmParameters</span></code></a>.</p>
|
|
547
|
+
<p>When specifying parameters in the @node decoration, the developer should
|
|
548
|
+
specify sensible default parameters for node execution. These can be overwritten
|
|
549
|
+
on-the-fly when calling the node:</p>
|
|
550
|
+
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nd">@node</span><span class="p">(</span><span class="n">parameters</span><span class="o">=</span><span class="n">Parameters</span><span class="p">(</span><span class="n">resource</span><span class="o">=</span><span class="s2">"standard-resource"</span><span class="p">,</span>
|
|
551
|
+
<span class="n">queue</span><span class="o">=</span><span class="s2">"slurm-queue"</span><span class="p">))</span>
|
|
552
|
+
<span class="k">def</span><span class="w"> </span><span class="nf">some_node</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
553
|
+
<span class="o">.....</span>
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
<span class="k">def</span><span class="w"> </span><span class="nf">calling_function</span><span class="p">():</span>
|
|
557
|
+
<span class="c1"># we are already in a slurm job, we dont want to start another</span>
|
|
558
|
+
<span class="c1"># this node will run on the same resource</span>
|
|
559
|
+
<span class="n">some_node</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="n">parameters</span><span class="o">=</span><span class="n">Parameters</span><span class="p">(</span><span class="n">resource</span><span class="o">=</span><span class="s2">"self"</span><span class="p">))</span>
|
|
560
|
+
</pre></div>
|
|
561
|
+
</div>
|
|
562
|
+
</section>
|
|
563
|
+
</section>
|
|
564
|
+
<section id="node-execution">
|
|
565
|
+
<h2>Node Execution<a class="headerlink" href="#node-execution" title="Link to this heading">¶</a></h2>
|
|
566
|
+
<p>The node decorator wraps the actual execution of the function into a series
|
|
567
|
+
of operations controlled by the class Node.</p>
|
|
568
|
+
<ul class="simple">
|
|
569
|
+
<li><p>before execution all arguments and the function body are hashed using
|
|
570
|
+
<a class="reference internal" href="simstack/modules/simstack.core.html#simstack.core.hash.complex_hash_function" title="simstack.core.hash.complex_hash_function"><code class="xref py py-func docutils literal notranslate"><span class="pre">simstack.core.hash.complex_hash_function()</span></code></a>, which will infer how to
|
|
571
|
+
deal with nested objects, such as list, dicts, classes, etc.
|
|
572
|
+
For odmantic models which have a <code class="docutils literal notranslate"><span class="pre">complex_hash_function</span></code> this function will
|
|
573
|
+
override the default behavior. Odmantic ObjectId are not hashed.</p></li>
|
|
574
|
+
<li><p>if a NodeRegistry <a class="reference internal" href="simstack/modules/simstack.models.html#simstack.models.node_registry.NodeRegistry" title="simstack.models.node_registry.NodeRegistry"><code class="xref py py-class docutils literal notranslate"><span class="pre">simstack.models.node_registry.NodeRegistry</span></code></a> entry
|
|
575
|
+
matching the name of the function, the hash of the
|
|
576
|
+
arguments and the hash of the function is found, this registry entry is
|
|
577
|
+
returned, even if the node has failed unless force_rerun is True.</p></li>
|
|
578
|
+
<li><p>if no such NodeRegistry entry exists a new one is created with TaskStatus.SUBMITTED</p></li>
|
|
579
|
+
<li><p>the node class then calls the function <a class="reference internal" href="simstack/modules/simstack.core.html#simstack.core.node.Node.run_somewhere" title="simstack.core.node.Node.run_somewhere"><code class="xref py py-func docutils literal notranslate"><span class="pre">simstack.core.node.Node.run_somewhere()</span></code></a>
|
|
580
|
+
which executes the node locally using
|
|
581
|
+
<a class="reference internal" href="simstack/modules/simstack.core.html#simstack.core.node.Node.execute_node_locally" title="simstack.core.node.Node.execute_node_locally"><code class="xref py py-func docutils literal notranslate"><span class="pre">simstack.core.node.Node.execute_node_locally()</span></code></a> or waits until
|
|
582
|
+
the task status is changed in the database by a runner. This function will
|
|
583
|
+
set the <code class="docutils literal notranslate"><span class="pre">status</span></code> field in the <code class="docutils literal notranslate"><span class="pre">node_registry</span></code> entry depending on the
|
|
584
|
+
outcome of the node execution an process the data in <code class="docutils literal notranslate"><span class="pre">node_runner</span></code></p></li>
|
|
585
|
+
<li><p>after node execution the results from remote nodes are loaded from the
|
|
586
|
+
database.</p></li>
|
|
587
|
+
</ul>
|
|
588
|
+
<div class="admonition note">
|
|
589
|
+
<p class="admonition-title">Note</p>
|
|
590
|
+
<p>Timeouts for remote execution are not yet implemented.</p>
|
|
591
|
+
</div>
|
|
592
|
+
<section id="remote-execution">
|
|
593
|
+
<h3>Remote Execution<a class="headerlink" href="#remote-execution" title="Link to this heading">¶</a></h3>
|
|
594
|
+
<p>Nodes scheduled to run on a remote execution require a runner
|
|
595
|
+
(<code class="xref py py-func docutils literal notranslate"><span class="pre">simstack.core.runner.runner()</span></code>) to be running on that resource with the
|
|
596
|
+
–resource flag set to the name of that node. The user or the administrator
|
|
597
|
+
has to install Simstack and the relevant user repositories on the remote
|
|
598
|
+
server and specify the information relevant to the remote node in the
|
|
599
|
+
<code class="docutils literal notranslate"><span class="pre">simstack.toml</span></code> configuration file (see: <a class="reference internal" href="installation.html#configuration-file"><span class="std std-ref">Create simstack.toml</span></a>). This
|
|
600
|
+
needs to be done only once.</p>
|
|
601
|
+
<p>When someone is actively developing new nodes or other code to be run on the
|
|
602
|
+
remote node, it is important to keep the code on the remote server up-to-date.
|
|
603
|
+
The preferred way is to periodically check for a git-update or other server
|
|
604
|
+
crashes and restart the server if such events are detected.
|
|
605
|
+
The file <code class="file docutils literal notranslate"><span class="pre">simstack.scripts.check_runner.sh</span></code> provides a template that
|
|
606
|
+
must be adapted to the configuration of the remote node. This needs to be
|
|
607
|
+
done only once.</p>
|
|
608
|
+
</section>
|
|
609
|
+
<section id="registering-models-and-nodes">
|
|
610
|
+
<span id="registering"></span><h3>Registering Models and Nodes<a class="headerlink" href="#registering-models-and-nodes" title="Link to this heading">¶</a></h3>
|
|
611
|
+
<p>Database access to the mongodb database in Simstack II is facilitated by a
|
|
612
|
+
using the odmantic package, which provides asynchronous object oriented access
|
|
613
|
+
to the database (see <a class="reference internal" href="data.html#persisting-data"><span class="std std-ref">Persisting and Visualizing Data</span></a>). This means that data in the
|
|
614
|
+
generic code-base of Simstack is loaded/stored by storing class instances.</p>
|
|
615
|
+
<p>These classes cannot be imported via the standard <code class="docutils literal notranslate"><span class="pre">import</span></code> statements,
|
|
616
|
+
because they are unknown to the SimStack core modules. To overcome this
|
|
617
|
+
problem a dynamic import system has been implemented, where the module paths
|
|
618
|
+
of Simstack Models and Nodes are stored in database tables (<code class="docutils literal notranslate"><span class="pre">node_model</span></code>
|
|
619
|
+
and <code class="docutils literal notranslate"><span class="pre">model_table</span></code>, respectively).</p>
|
|
620
|
+
<p>The functions <code class="xref py py-func docutils literal notranslate"><span class="pre">simstack.core.model_table.make_model_table()</span></code> and
|
|
621
|
+
<code class="xref py py-func docutils literal notranslate"><span class="pre">simstack.core.node_table.make_node_table()</span></code> scan the directories
|
|
622
|
+
provided in the path section of the configuration file
|
|
623
|
+
(<span class="xref std std-ref">configuration_file</span>)</p>
|
|
624
|
+
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">paths</span><span class="p">]</span>
|
|
625
|
+
<span class="c1"># Path configuration for the PathManager.</span>
|
|
626
|
+
<span class="c1"># Each path entry should have a path and an optional drops value.</span>
|
|
627
|
+
<span class="c1"># The path is the directory to search for Python files</span>
|
|
628
|
+
<span class="c1"># The "drops" value is a prefix to drop from module names (for import paths)</span>
|
|
629
|
+
<span class="n">models</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s2">"src</span><span class="se">\\</span><span class="s2">simstack</span><span class="se">\\</span><span class="s2">models"</span><span class="p">,</span> <span class="n">drops</span> <span class="o">=</span> <span class="s2">"src"</span> <span class="p">}</span>
|
|
630
|
+
<span class="n">methods</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s2">"src</span><span class="se">\\</span><span class="s2">simstack</span><span class="se">\\</span><span class="s2">methods"</span><span class="p">,</span> <span class="n">drops</span> <span class="o">=</span> <span class="s2">"src"</span> <span class="p">}</span>
|
|
631
|
+
<span class="n">ui_testing</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s2">"src</span><span class="se">\\</span><span class="s2">simstack</span><span class="se">\\</span><span class="s2">ui_testing"</span><span class="p">,</span> <span class="n">drops</span> <span class="o">=</span> <span class="s2">"src"</span> <span class="p">}</span>
|
|
632
|
+
<span class="n">applications</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s2">"applications"</span><span class="p">,</span> <span class="n">drops</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span> <span class="n">use_pickle</span> <span class="o">=</span> <span class="n">false</span> <span class="p">}</span>
|
|
633
|
+
<span class="n">tests</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s2">"tests"</span><span class="p">,</span> <span class="n">drops</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span> <span class="n">use_pickle</span> <span class="o">=</span> <span class="n">false</span> <span class="p">}</span>
|
|
634
|
+
<span class="n">projects</span> <span class="o">=</span> <span class="p">{</span> <span class="n">path</span> <span class="o">=</span> <span class="s2">"projects"</span><span class="p">,</span> <span class="n">drops</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span>
|
|
635
|
+
<span class="n">use_pickle</span> <span class="o">=</span> <span class="n">false</span> <span class="p">}</span>
|
|
636
|
+
</pre></div>
|
|
637
|
+
</div>
|
|
638
|
+
<p>The first 4 entries are standard paths. The first three (models, methods,
|
|
639
|
+
ui_testing) belong to the Simstack core. <code class="docutils literal notranslate"><span class="pre">applications</span></code> is the standard
|
|
640
|
+
directory where you should install community application packages for
|
|
641
|
+
specific application domains.</p>
|
|
642
|
+
<p>The nodes and application programs written by you should go under
|
|
643
|
+
<code class="docutils literal notranslate"><span class="pre">projects</span></code>.</p>
|
|
644
|
+
</section>
|
|
645
|
+
<section id="most-common-errors-problems">
|
|
646
|
+
<h3>Most Common Errors & Problems<a class="headerlink" href="#most-common-errors-problems" title="Link to this heading">¶</a></h3>
|
|
647
|
+
<ul class="simple">
|
|
648
|
+
<li><p>remote runners are not on the same branch or not up-to-date (see Health
|
|
649
|
+
Check in the GUI)</p></li>
|
|
650
|
+
<li><p>you can set the branch of the runners in the GUI (in profile). Unless in ver special</p></li>
|
|
651
|
+
</ul>
|
|
652
|
+
<p>circumstances all runners should be on the same branch.
|
|
653
|
+
* all runners will periodically update from git. when the branch has changed the <strong>default runner</strong> will
|
|
654
|
+
recreate models and nodes. the runners will update –locked, i.e. they need an up-to-date uv.lock
|
|
655
|
+
* model and node creation is incremental. when you move things around the exisiting bindings will be
|
|
656
|
+
overridden, but if you delete models and nodes the database will not know this (which is intended because
|
|
657
|
+
data may still exist in the db)
|
|
658
|
+
* when you not only develop your own package but also the simstack core (you should not), it makes
|
|
659
|
+
sense to clone simstack as a subrepo into you main repo. You then must run <code class="docutils literal notranslate"><span class="pre">uv</span> <span class="pre">lock</span> <span class="pre">--upgrade-package</span> <span class="pre">simstack</span></code>
|
|
660
|
+
after commits of simstack to keep your pyproject.toml up to date. after that you must run `` uv sync –locked`` and commit again
|
|
661
|
+
your main repo so that the runners can update simstack.
|
|
662
|
+
* node or model not registered in the database (see <a class="reference internal" href="#registering"><span class="std std-ref">Registering Models and Nodes</span></a>)
|
|
663
|
+
* node or model not imported correctly (see below)
|
|
664
|
+
* forgetting **kwargs in the node function definition. Nodes will crash.
|
|
665
|
+
* relative imports suggested by IDE:</p>
|
|
666
|
+
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">models</span><span class="w"> </span><span class="kn">import</span> <span class="n">Model</span>
|
|
667
|
+
<span class="kn">from</span><span class="w"> </span><span class="nn">core.nodes</span><span class="w"> </span><span class="kn">import</span> <span class="n">node</span>
|
|
668
|
+
</pre></div>
|
|
669
|
+
</div>
|
|
670
|
+
<p>make sure all imports are relative to simstack. For example:</p>
|
|
671
|
+
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">simstack.core.parameters</span><span class="w"> </span><span class="kn">import</span> <span class="n">Parameters</span>
|
|
672
|
+
<span class="kn">from</span><span class="w"> </span><span class="nn">simstack.core.workflow</span><span class="w"> </span><span class="kn">import</span> <span class="n">Workflow</span>
|
|
673
|
+
<span class="kn">from</span><span class="w"> </span><span class="nn">simstack.core.runner</span><span class="w"> </span><span class="kn">import</span> <span class="n">Runner</span>
|
|
674
|
+
</pre></div>
|
|
675
|
+
</div>
|
|
676
|
+
<p>or relative the other top-level modules. e.g. applications</p>
|
|
677
|
+
</section>
|
|
678
|
+
</section>
|
|
679
|
+
</section>
|
|
680
|
+
|
|
681
|
+
</article>
|
|
682
|
+
</div>
|
|
683
|
+
<footer>
|
|
684
|
+
|
|
685
|
+
<div class="related-pages">
|
|
686
|
+
<a class="next-page" href="ui_documentation.html">
|
|
687
|
+
<div class="page-info">
|
|
688
|
+
<div class="context">
|
|
689
|
+
<span>Next</span>
|
|
690
|
+
</div>
|
|
691
|
+
<div class="title">Graphical User Interface</div>
|
|
692
|
+
</div>
|
|
693
|
+
<svg class="furo-related-icon"><use href="#svg-arrow-right"></use></svg>
|
|
694
|
+
</a>
|
|
695
|
+
<a class="prev-page" href="overview.html">
|
|
696
|
+
<svg class="furo-related-icon"><use href="#svg-arrow-right"></use></svg>
|
|
697
|
+
<div class="page-info">
|
|
698
|
+
<div class="context">
|
|
699
|
+
<span>Previous</span>
|
|
700
|
+
</div>
|
|
701
|
+
|
|
702
|
+
<div class="title">Overview</div>
|
|
703
|
+
|
|
704
|
+
</div>
|
|
705
|
+
</a>
|
|
706
|
+
</div>
|
|
707
|
+
<div class="bottom-of-page">
|
|
708
|
+
<div class="left-details">
|
|
709
|
+
<div class="copyright">
|
|
710
|
+
Copyright © 2026, Wolfgang Wenzel
|
|
711
|
+
</div>
|
|
712
|
+
Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
|
|
713
|
+
|
|
714
|
+
<a href="https://github.com/pradyunsg/furo">Furo</a>
|
|
715
|
+
|
|
716
|
+
</div>
|
|
717
|
+
<div class="right-details">
|
|
718
|
+
|
|
719
|
+
</div>
|
|
720
|
+
</div>
|
|
721
|
+
|
|
722
|
+
</footer>
|
|
723
|
+
</div>
|
|
724
|
+
<aside class="toc-drawer">
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
<div class="toc-sticky toc-scroll">
|
|
728
|
+
<div class="toc-title-container">
|
|
729
|
+
<span class="toc-title">
|
|
730
|
+
On this page
|
|
731
|
+
</span>
|
|
732
|
+
</div>
|
|
733
|
+
<div class="toc-tree-container">
|
|
734
|
+
<div class="toc-tree">
|
|
735
|
+
<ul>
|
|
736
|
+
<li><a class="reference internal" href="#">Workflows</a><ul>
|
|
737
|
+
<li><a class="reference internal" href="#from-python-to-workflows">From Python to Workflows</a><ul>
|
|
738
|
+
<li><a class="reference internal" href="#return-types">Return Types</a></li>
|
|
739
|
+
<li><a class="reference internal" href="#the-noderunner-helper-class">The Noderunner Helper Class</a></li>
|
|
740
|
+
<li><a class="reference internal" href="#node-decorator-arguments">Node Decorator Arguments</a></li>
|
|
741
|
+
</ul>
|
|
742
|
+
</li>
|
|
743
|
+
<li><a class="reference internal" href="#node-execution">Node Execution</a><ul>
|
|
744
|
+
<li><a class="reference internal" href="#remote-execution">Remote Execution</a></li>
|
|
745
|
+
<li><a class="reference internal" href="#registering-models-and-nodes">Registering Models and Nodes</a></li>
|
|
746
|
+
<li><a class="reference internal" href="#most-common-errors-problems">Most Common Errors & Problems</a></li>
|
|
747
|
+
</ul>
|
|
748
|
+
</li>
|
|
749
|
+
</ul>
|
|
750
|
+
</li>
|
|
751
|
+
</ul>
|
|
752
|
+
|
|
753
|
+
</div>
|
|
754
|
+
</div>
|
|
755
|
+
</div>
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
</aside>
|
|
759
|
+
</div>
|
|
760
|
+
</div><script src="_static/documentation_options.js?v=5929fcd5"></script>
|
|
761
|
+
<script src="_static/doctools.js?v=fd6eb6e6"></script>
|
|
762
|
+
<script src="_static/sphinx_highlight.js?v=6ffebe34"></script>
|
|
763
|
+
<script src="_static/scripts/furo.js?v=46bd48cc"></script>
|
|
764
|
+
<script data-docs-built-at="2026-07-17 10:50:10 UTC" src="_static/docs-build-badge.js?v=57cb9fc6"></script>
|
|
765
|
+
</body>
|
|
766
|
+
</html>
|