simvue 2.6.1__tar.gz → 2.6.2__tar.gz
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.
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/common.yml +1 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/deploy.yaml +2 -0
- {simvue-2.6.1 → simvue-2.6.2}/CHANGELOG.md +4 -0
- {simvue-2.6.1 → simvue-2.6.2}/CITATION.cff +3 -3
- {simvue-2.6.1 → simvue-2.6.2}/PKG-INFO +2 -2
- {simvue-2.6.1 → simvue-2.6.2}/prek.toml +5 -5
- {simvue-2.6.1 → simvue-2.6.2}/pyproject.toml +2 -2
- {simvue-2.6.1 → simvue-2.6.2}/simvue/config/simvue_config_schema.json +91 -27
- {simvue-2.6.1 → simvue-2.6.2}/simvue/run.py +10 -7
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/python_poetry/poetry.lock +5 -5
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/python_uv/uv.lock +3 -3
- {simvue-2.6.1 → simvue-2.6.2}/tests/functional/test_run_class.py +90 -1
- {simvue-2.6.1 → simvue-2.6.2}/uv.lock +1039 -530
- {simvue-2.6.1 → simvue-2.6.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/PULL_REQUEST_TEMPLATE/bug_fix.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/dependabot.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/pull_request_template.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/citation.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/codeql.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/examples.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/prek.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/test_client_macos_nightlies.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/test_client_ubuntu.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/test_client_ubuntu_nightlies.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/test_client_windows_nightlies.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/test_group.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.github/workflows/test_multiple_python.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.gitignore +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/.gitmodules +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/CODE_OF_CONDUCT.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/CONTRIBUTING.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/LICENSE +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/README.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Bluemira/README.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Bluemira/geometry_optimisation.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Geant4/README.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Geant4/geant4_simvue.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Geant4/requirements.txt +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Logging/README.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Logging/logging-to-simvue.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Optuna/README.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Optuna/requirements.txt +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/Optuna/simvue_optuna_pytorch.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/PyTorch/README.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/PyTorch/main.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/PyTorch/requirements.txt +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/README.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/SU2/README.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/SU2/SU2.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/examples/SU2/SU2.sh +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/notebooks/README.md +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/notebooks/basic_example.ipynb +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/notebooks/detailed_example.ipynb +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/notebooks/non_python_example.ipynb +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/notebooks/temperatures.sh +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/poetry.lock +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/administrator/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/administrator/tenant.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/administrator/user.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/alert/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/alert/base.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/alert/events.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/alert/fetch.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/alert/metrics.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/alert/user.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/artifact/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/artifact/base.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/artifact/fetch.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/artifact/file.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/artifact/object.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/base.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/events.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/filter/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/filter/base.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/filter/folder.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/filter/run.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/folder.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/grids.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/metrics.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/run.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/stats.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/storage/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/storage/base.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/storage/fetch.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/storage/file.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/storage/s3.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/objects/tag.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/request.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/api/url.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/bin/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/bin/sender.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/client.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/config/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/config/files.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/config/parameters.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/config/user.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/converters.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/dispatch/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/dispatch/base.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/dispatch/direct.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/dispatch/dispatcher.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/dispatch/queued.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/eco/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/eco/api_client.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/eco/config.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/eco/emissions_monitor.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/exception.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/executor.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/handler.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/metadata.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/metrics.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/models.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/pynvml.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/sender/__init__.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/sender/actions.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/sender/base.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/serialization.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/simvue_types.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/system.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/utilities.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue/version.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/simvue-black.png +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/cli/test_sender_command.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/conftest.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/Cargo.lock +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/Cargo.toml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/Project.toml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/SU2_inv_ONERAM6.cfg +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/package-lock.json +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/pyproject.toml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/python_conda/environment.yml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/python_poetry/pyproject.toml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/example_data/python_uv/pyproject.toml +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/functional/test_client.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/functional/test_config.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/functional/test_dispatch.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/functional/test_executor.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/functional/test_run_artifact_upload.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/functional/test_run_execute_process.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/functional/test_scenarios.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/functional/test_utilities.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_conversion_to_dataframe.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_ecoclient.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_event_alert.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_events.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_fetch.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_file_artifact.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_file_storage.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_filters.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_folder.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_grids.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_matplotlib_figure_mime_type.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_metadata.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_metric_range_alert.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_metric_threshold_alert.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_metrics.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_numpy_array_mime_type.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_numpy_array_serialization.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_object_artifact.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_pandas_dataframe_mimetype.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_pandas_dataframe_serialization.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_pickle_serialization.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_plotly_figure_mime_type.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_pytorch_tensor_mime_type.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_pytorch_tensor_serialization.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_request.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_run.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_run_init_folder.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_run_init_tags.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_s3_storage.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_sender.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_stats.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_suppress_errors.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_tag.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_tenant.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_user.py +0 -0
- {simvue-2.6.1 → simvue-2.6.2}/tests/unit/test_user_alert.py +0 -0
|
@@ -109,6 +109,7 @@ jobs:
|
|
|
109
109
|
test-command: ${{ inputs.test-command }}
|
|
110
110
|
test-group: executor ${{ startsWith(inputs.platform, 'windows') && 'and not unix' || '' }}
|
|
111
111
|
group-label: Executor
|
|
112
|
+
parallel-tasks: 0
|
|
112
113
|
secrets:
|
|
113
114
|
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
|
|
114
115
|
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## [v2.6.2](https://github.com/simvue-io/python-api/releases/tag/v2.6.2) - 2026-10-21
|
|
4
|
+
|
|
5
|
+
- Added support for Python 3.15.
|
|
6
|
+
|
|
3
7
|
## [v2.6.1](https://github.com/simvue-io/python-api/releases/tag/v2.6.1) - 2026-09-29
|
|
4
8
|
|
|
5
9
|
- Revert `datetime.UTC` to `datetime.timezone.utc` for legacy support.
|
|
@@ -43,6 +43,6 @@ keywords:
|
|
|
43
43
|
- alerting
|
|
44
44
|
- simulation
|
|
45
45
|
license: Apache-2.0
|
|
46
|
-
commit:
|
|
47
|
-
version: 2.6.
|
|
48
|
-
date-released: "2026-
|
|
46
|
+
commit: 2081ea4ca78da2e05c12a29d10a6c2a6d3308e8d
|
|
47
|
+
version: 2.6.2
|
|
48
|
+
date-released: "2026-10-21"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: simvue
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.2
|
|
4
4
|
Summary: Simulation tracking and monitoring
|
|
5
5
|
Project-URL: homepage, https://simvue.io
|
|
6
6
|
Project-URL: repository, https://github.com/simvue-io/python-api
|
|
@@ -25,7 +25,7 @@ Classifier: Topic :: Scientific/Engineering
|
|
|
25
25
|
Classifier: Topic :: System :: Monitoring
|
|
26
26
|
Classifier: Topic :: Utilities
|
|
27
27
|
Classifier: Typing :: Typed
|
|
28
|
-
Requires-Python: <3.
|
|
28
|
+
Requires-Python: <3.16,>=3.10
|
|
29
29
|
Requires-Dist: click>=8.5.0
|
|
30
30
|
Requires-Dist: deepmerge>=3.0.1
|
|
31
31
|
Requires-Dist: email-validator>=2.3.0
|
|
@@ -34,7 +34,7 @@ id = "check-added-large-files"
|
|
|
34
34
|
|
|
35
35
|
[[repos]]
|
|
36
36
|
repo = "https://github.com/astral-sh/ruff-pre-commit"
|
|
37
|
-
rev = "v0.16.
|
|
37
|
+
rev = "v0.16.9"
|
|
38
38
|
|
|
39
39
|
[[repos.hooks]]
|
|
40
40
|
id = "ruff-check"
|
|
@@ -62,7 +62,7 @@ args = ["-lll", "--recursive", "clumper"]
|
|
|
62
62
|
|
|
63
63
|
[[repos]]
|
|
64
64
|
repo = "https://github.com/python-poetry/poetry"
|
|
65
|
-
rev = "2.
|
|
65
|
+
rev = "2.5.1"
|
|
66
66
|
[[repos.hooks]]
|
|
67
67
|
id = "poetry-check"
|
|
68
68
|
|
|
@@ -75,14 +75,14 @@ args = ["--all-extras", "--all-groups"]
|
|
|
75
75
|
|
|
76
76
|
[[repos]]
|
|
77
77
|
repo = "https://github.com/GabDug/sync-pre-commit-lock"
|
|
78
|
-
rev = "v0.9.
|
|
78
|
+
rev = "v0.9.1"
|
|
79
79
|
|
|
80
80
|
[[repos.hooks]]
|
|
81
81
|
id = "sync-pre-commit-uv"
|
|
82
82
|
|
|
83
83
|
[[repos]]
|
|
84
84
|
repo = "https://github.com/astral-sh/uv-pre-commit"
|
|
85
|
-
rev = "0.
|
|
85
|
+
rev = "0.12.21"
|
|
86
86
|
|
|
87
87
|
[[repos.hooks]]
|
|
88
88
|
id = "uv-lock"
|
|
@@ -96,7 +96,7 @@ id = "validate-cff"
|
|
|
96
96
|
|
|
97
97
|
[[repos]]
|
|
98
98
|
repo = "https://github.com/DetachHead/basedpyright-prek-mirror"
|
|
99
|
-
rev = "1.
|
|
99
|
+
rev = "1.40.1"
|
|
100
100
|
|
|
101
101
|
[[repos.hooks]]
|
|
102
102
|
id = "basedpyright"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "simvue"
|
|
3
|
-
version = "2.6.
|
|
3
|
+
version = "2.6.2"
|
|
4
4
|
description = "Simulation tracking and monitoring"
|
|
5
5
|
authors = [{ name = "Simvue Development Team", email = "info@simvue.io" }]
|
|
6
6
|
license = "Apache-2.0"
|
|
7
|
-
requires-python = ">=3.10,<3.
|
|
7
|
+
requires-python = ">=3.10,<3.16"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
classifiers = [
|
|
10
10
|
"Development Status :: 5 - Production/Stable",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$defs": {
|
|
3
3
|
"CertificateSpecifications": {
|
|
4
|
+
"additionalProperties": false,
|
|
4
5
|
"properties": {
|
|
5
6
|
"client_cert": {
|
|
6
7
|
"anyOf": [
|
|
@@ -60,6 +61,8 @@
|
|
|
60
61
|
"type": "object"
|
|
61
62
|
},
|
|
62
63
|
"ClientGeneralOptions": {
|
|
64
|
+
"additionalProperties": false,
|
|
65
|
+
"description": "Specify client options.",
|
|
63
66
|
"properties": {
|
|
64
67
|
"debug": {
|
|
65
68
|
"default": false,
|
|
@@ -71,6 +74,8 @@
|
|
|
71
74
|
"type": "object"
|
|
72
75
|
},
|
|
73
76
|
"DefaultRunSpecifications": {
|
|
77
|
+
"additionalProperties": false,
|
|
78
|
+
"description": "Specify run default configurations.",
|
|
74
79
|
"properties": {
|
|
75
80
|
"description": {
|
|
76
81
|
"anyOf": [
|
|
@@ -91,32 +96,14 @@
|
|
|
91
96
|
"type": "string"
|
|
92
97
|
},
|
|
93
98
|
"metadata": {
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"type": "integer"
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
"type": "number"
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
"type": "boolean"
|
|
109
|
-
}
|
|
110
|
-
]
|
|
111
|
-
},
|
|
112
|
-
"type": "object"
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
"type": "null"
|
|
116
|
-
}
|
|
117
|
-
],
|
|
118
|
-
"default": null,
|
|
119
|
-
"title": "Metadata"
|
|
99
|
+
"$ref": "#/$defs/MetadataSpecifications",
|
|
100
|
+
"default": {
|
|
101
|
+
"custom": null,
|
|
102
|
+
"environment": true,
|
|
103
|
+
"git": true,
|
|
104
|
+
"record_shell_vars": null,
|
|
105
|
+
"system": true
|
|
106
|
+
}
|
|
120
107
|
},
|
|
121
108
|
"mode": {
|
|
122
109
|
"default": "online",
|
|
@@ -267,7 +254,74 @@
|
|
|
267
254
|
"title": "EcoConfig",
|
|
268
255
|
"type": "object"
|
|
269
256
|
},
|
|
257
|
+
"MetadataSpecifications": {
|
|
258
|
+
"additionalProperties": false,
|
|
259
|
+
"properties": {
|
|
260
|
+
"custom": {
|
|
261
|
+
"anyOf": [
|
|
262
|
+
{
|
|
263
|
+
"additionalProperties": {
|
|
264
|
+
"anyOf": [
|
|
265
|
+
{
|
|
266
|
+
"type": "string"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"type": "integer"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"type": "number"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"type": "boolean"
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
},
|
|
279
|
+
"type": "object"
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"type": "null"
|
|
283
|
+
}
|
|
284
|
+
],
|
|
285
|
+
"default": null,
|
|
286
|
+
"title": "Custom"
|
|
287
|
+
},
|
|
288
|
+
"environment": {
|
|
289
|
+
"default": true,
|
|
290
|
+
"title": "Environment",
|
|
291
|
+
"type": "boolean"
|
|
292
|
+
},
|
|
293
|
+
"git": {
|
|
294
|
+
"default": true,
|
|
295
|
+
"title": "Git",
|
|
296
|
+
"type": "boolean"
|
|
297
|
+
},
|
|
298
|
+
"record_shell_vars": {
|
|
299
|
+
"anyOf": [
|
|
300
|
+
{
|
|
301
|
+
"items": {
|
|
302
|
+
"type": "string"
|
|
303
|
+
},
|
|
304
|
+
"type": "array"
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"type": "null"
|
|
308
|
+
}
|
|
309
|
+
],
|
|
310
|
+
"default": null,
|
|
311
|
+
"title": "Record Shell Vars"
|
|
312
|
+
},
|
|
313
|
+
"system": {
|
|
314
|
+
"default": true,
|
|
315
|
+
"title": "System",
|
|
316
|
+
"type": "boolean"
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
"title": "MetadataSpecifications",
|
|
320
|
+
"type": "object"
|
|
321
|
+
},
|
|
270
322
|
"MetricsSpecifications": {
|
|
323
|
+
"additionalProperties": false,
|
|
324
|
+
"description": "Specify metric configurations.",
|
|
271
325
|
"properties": {
|
|
272
326
|
"enable_emission_metrics": {
|
|
273
327
|
"default": false,
|
|
@@ -292,6 +346,8 @@
|
|
|
292
346
|
"type": "object"
|
|
293
347
|
},
|
|
294
348
|
"OfflineSpecifications": {
|
|
349
|
+
"additionalProperties": false,
|
|
350
|
+
"description": "Specify offline mode configurations.",
|
|
295
351
|
"properties": {
|
|
296
352
|
"cache": {
|
|
297
353
|
"anyOf": [
|
|
@@ -312,6 +368,7 @@
|
|
|
312
368
|
},
|
|
313
369
|
"ServerSpecifications": {
|
|
314
370
|
"additionalProperties": false,
|
|
371
|
+
"description": "Specify server configurations.",
|
|
315
372
|
"properties": {
|
|
316
373
|
"certificates": {
|
|
317
374
|
"$ref": "#/$defs/CertificateSpecifications"
|
|
@@ -367,6 +424,7 @@
|
|
|
367
424
|
}
|
|
368
425
|
},
|
|
369
426
|
"additionalProperties": false,
|
|
427
|
+
"description": "Configure session.",
|
|
370
428
|
"properties": {
|
|
371
429
|
"client": {
|
|
372
430
|
"$ref": "#/$defs/ClientGeneralOptions",
|
|
@@ -422,7 +480,13 @@
|
|
|
422
480
|
"default": {
|
|
423
481
|
"description": null,
|
|
424
482
|
"folder": "/",
|
|
425
|
-
"metadata":
|
|
483
|
+
"metadata": {
|
|
484
|
+
"custom": null,
|
|
485
|
+
"environment": true,
|
|
486
|
+
"git": true,
|
|
487
|
+
"record_shell_vars": null,
|
|
488
|
+
"system": true
|
|
489
|
+
},
|
|
426
490
|
"mode": "online",
|
|
427
491
|
"name": null,
|
|
428
492
|
"record_shell_vars": null,
|
|
@@ -189,6 +189,7 @@ class Run:
|
|
|
189
189
|
self._dispatcher: DispatcherBaseClass | None = None
|
|
190
190
|
|
|
191
191
|
self._meta_cache: dict[str, typing.Any] = {}
|
|
192
|
+
self._meta_cache_lock: threading.Lock = threading.Lock()
|
|
192
193
|
|
|
193
194
|
self._folder: Folder | None = None
|
|
194
195
|
self._term_color: bool = True
|
|
@@ -1779,10 +1780,11 @@ class Run:
|
|
|
1779
1780
|
```
|
|
1780
1781
|
|
|
1781
1782
|
"""
|
|
1782
|
-
#
|
|
1783
|
-
|
|
1783
|
+
# Ensure this cannot get into a race with set_metric_units
|
|
1784
|
+
with self._meta_cache_lock:
|
|
1785
|
+
_units = self._meta_cache.pop("metrics", None)
|
|
1786
|
+
if _units:
|
|
1784
1787
|
self.update_metadata({"simvue": {"metrics": _units}})
|
|
1785
|
-
del self._meta_cache["metrics"]
|
|
1786
1788
|
|
|
1787
1789
|
# TODO: When metrics and grids are combined into a single entity
|
|
1788
1790
|
# this can be removed. For now need to separate tensor based metrics
|
|
@@ -2753,18 +2755,19 @@ class Run:
|
|
|
2753
2755
|
```
|
|
2754
2756
|
|
|
2755
2757
|
"""
|
|
2756
|
-
self._meta_cache.setdefault("metrics", {})
|
|
2757
|
-
|
|
2758
2758
|
try:
|
|
2759
2759
|
_unit_obj: unyt_quantity = unyt_quantity.from_string(units)
|
|
2760
|
-
|
|
2760
|
+
_payload = {
|
|
2761
2761
|
"units": units,
|
|
2762
2762
|
"mks_conversion": mks_conversion or float(_unit_obj.in_mks().value),
|
|
2763
2763
|
"mks_units": mks_unit or f"{_unit_obj.in_mks().units}",
|
|
2764
2764
|
}
|
|
2765
2765
|
except (UnitParseError, ValueError):
|
|
2766
|
-
|
|
2766
|
+
_payload = {
|
|
2767
2767
|
"units": units,
|
|
2768
2768
|
"mks_conversion": mks_conversion,
|
|
2769
2769
|
"mks_units": mks_unit,
|
|
2770
2770
|
}
|
|
2771
|
+
# Ensure this cannot get into a race with log_metrics
|
|
2772
|
+
with self._meta_cache_lock:
|
|
2773
|
+
self._meta_cache.setdefault("metrics", {})[metric_name] = _payload
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# This file is automatically @generated by Poetry 2.
|
|
1
|
+
# This file is automatically @generated by Poetry 2.5.1 and should not be changed by hand.
|
|
2
2
|
|
|
3
3
|
[[package]]
|
|
4
4
|
name = "certifi"
|
|
@@ -366,14 +366,14 @@ files = [
|
|
|
366
366
|
|
|
367
367
|
[[package]]
|
|
368
368
|
name = "urllib3"
|
|
369
|
-
version = "2.
|
|
369
|
+
version = "2.8.0"
|
|
370
370
|
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
|
371
371
|
optional = false
|
|
372
|
-
python-versions = ">=3.
|
|
372
|
+
python-versions = ">=3.10"
|
|
373
373
|
groups = ["main"]
|
|
374
374
|
files = [
|
|
375
|
-
{file = "urllib3-2.
|
|
376
|
-
{file = "urllib3-2.
|
|
375
|
+
{file = "urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3"},
|
|
376
|
+
{file = "urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63"},
|
|
377
377
|
]
|
|
378
378
|
|
|
379
379
|
[package.extras]
|
|
@@ -172,9 +172,9 @@ wheels = [
|
|
|
172
172
|
|
|
173
173
|
[[package]]
|
|
174
174
|
name = "urllib3"
|
|
175
|
-
version = "2.
|
|
175
|
+
version = "2.8.0"
|
|
176
176
|
source = { registry = "https://pypi.org/simple" }
|
|
177
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
177
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", size = 458972, upload-time = "2026-09-15T19:29:36.253Z" }
|
|
178
178
|
wheels = [
|
|
179
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
179
|
+
{ url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", size = 135717, upload-time = "2026-09-15T19:29:34.577Z" },
|
|
180
180
|
]
|
|
@@ -12,12 +12,14 @@ import contextlib
|
|
|
12
12
|
import inspect
|
|
13
13
|
import tempfile
|
|
14
14
|
import threading
|
|
15
|
+
import traceback
|
|
15
16
|
import uuid
|
|
16
17
|
import psutil
|
|
17
18
|
import pathlib
|
|
18
19
|
import concurrent.futures
|
|
19
20
|
import random
|
|
20
21
|
import datetime
|
|
22
|
+
from unyt import unyt_quantity
|
|
21
23
|
import simvue
|
|
22
24
|
from simvue.api.objects import Alert, EventsAlert, Metrics, MetricsRangeAlert, MetricsThresholdAlert, UserAlert
|
|
23
25
|
from simvue.api.objects.grids import GridMetrics
|
|
@@ -1402,7 +1404,12 @@ def test_abort_on_alert_process(mocker: pytest_mock.MockerFixture) -> None:
|
|
|
1402
1404
|
assert run._system_metrics_interval == 1
|
|
1403
1405
|
for child in child_processes:
|
|
1404
1406
|
assert not child.is_running()
|
|
1405
|
-
|
|
1407
|
+
counter = 0
|
|
1408
|
+
while run._status != "terminated" and counter < 15:
|
|
1409
|
+
time.sleep(1)
|
|
1410
|
+
assert run._sv_obj.abort_trigger, "Abort trigger was not set"
|
|
1411
|
+
counter += 1
|
|
1412
|
+
if counter >= 15:
|
|
1406
1413
|
run.kill_all_processes()
|
|
1407
1414
|
raise AssertionError("Run was not terminated")
|
|
1408
1415
|
assert trigger.is_set()
|
|
@@ -1779,3 +1786,85 @@ def test_set_metric_units(create_plain_run: tuple[sv_run.Run, dict]) -> None:
|
|
|
1779
1786
|
assert _metric_data["x"] == {"units": "ft", "mks_units": "m", "mks_conversion": 0.3048}
|
|
1780
1787
|
assert _metric_data["y"] == {"units": "m", "mks_units": "m", "mks_conversion": 1}
|
|
1781
1788
|
assert _metric_data["z"] == {"units": "Foobars", "mks_units": "m", "mks_conversion": 3.542}
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
@pytest.mark.run
|
|
1792
|
+
@pytest.mark.offline
|
|
1793
|
+
def test_set_metric_units_thread_safety(
|
|
1794
|
+
create_plain_run_offline: tuple[sv_run.Run, dict],
|
|
1795
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
1796
|
+
) -> None:
|
|
1797
|
+
"""Concurrent set_metric_units / log_metrics must not corrupt the units cache.
|
|
1798
|
+
"""
|
|
1799
|
+
run, _ = create_plain_run_offline
|
|
1800
|
+
|
|
1801
|
+
# Seed a pending units entry so log_metrics takes the fetch path
|
|
1802
|
+
run.set_metric_units("seed", units="m")
|
|
1803
|
+
assert "metrics" in run._meta_cache
|
|
1804
|
+
|
|
1805
|
+
log_frozen = threading.Event()
|
|
1806
|
+
log_released = threading.Event()
|
|
1807
|
+
units_frozen = threading.Event()
|
|
1808
|
+
units_released = threading.Event()
|
|
1809
|
+
|
|
1810
|
+
_orig_update_metadata = run.update_metadata
|
|
1811
|
+
|
|
1812
|
+
def _blocking_update_metadata(metadata: dict[str, typing.Any]) -> bool:
|
|
1813
|
+
"""Freeze log_metrics after the units fetch, before the cache delete."""
|
|
1814
|
+
log_frozen.set()
|
|
1815
|
+
log_released.wait(timeout=10)
|
|
1816
|
+
return _orig_update_metadata(metadata)
|
|
1817
|
+
|
|
1818
|
+
_orig_from_string = unyt_quantity.from_string
|
|
1819
|
+
|
|
1820
|
+
def _blocking_from_string(
|
|
1821
|
+
cls: type, s: str, *args: typing.Any, **kwargs: typing.Any
|
|
1822
|
+
):
|
|
1823
|
+
"""Freeze set_metric_units after the setdefault, before the item assignment."""
|
|
1824
|
+
units_frozen.set()
|
|
1825
|
+
units_released.wait(timeout=10)
|
|
1826
|
+
return _orig_from_string(s, *args, **kwargs)
|
|
1827
|
+
|
|
1828
|
+
monkeypatch.setattr(run, "update_metadata", _blocking_update_metadata)
|
|
1829
|
+
monkeypatch.setattr(
|
|
1830
|
+
unyt_quantity, "from_string", classmethod(_blocking_from_string)
|
|
1831
|
+
)
|
|
1832
|
+
|
|
1833
|
+
errors: list[str] = []
|
|
1834
|
+
|
|
1835
|
+
def log_metrics_task() -> None:
|
|
1836
|
+
try:
|
|
1837
|
+
run.log_metrics({"a": 1.0}, step=0)
|
|
1838
|
+
except Exception:
|
|
1839
|
+
errors.append(f"log_metrics:\n{traceback.format_exc()}")
|
|
1840
|
+
|
|
1841
|
+
def set_metric_units_task() -> None:
|
|
1842
|
+
try:
|
|
1843
|
+
run.set_metric_units("b", units="ft")
|
|
1844
|
+
except Exception:
|
|
1845
|
+
errors.append(f"set_metric_units:\n{traceback.format_exc()}")
|
|
1846
|
+
|
|
1847
|
+
log_thread = threading.Thread(target=log_metrics_task, name="log-metrics")
|
|
1848
|
+
log_thread.start()
|
|
1849
|
+
assert log_frozen.wait(timeout=10), "log_metrics did not reach update_metadata"
|
|
1850
|
+
|
|
1851
|
+
units_thread = threading.Thread(
|
|
1852
|
+
target=set_metric_units_task, name="set-metric-units"
|
|
1853
|
+
)
|
|
1854
|
+
units_thread.start()
|
|
1855
|
+
assert units_frozen.wait(timeout=10), "set_metric_units did not reach unit parsing"
|
|
1856
|
+
|
|
1857
|
+
# Release in the fatal order: fetch / setdefault / delete / item-assignment
|
|
1858
|
+
log_released.set()
|
|
1859
|
+
log_thread.join(timeout=10)
|
|
1860
|
+
units_released.set()
|
|
1861
|
+
units_thread.join(timeout=10)
|
|
1862
|
+
|
|
1863
|
+
assert not log_thread.is_alive() and not units_thread.is_alive()
|
|
1864
|
+
assert not errors, "concurrent metric logging raised:\n" + "\n".join(errors)
|
|
1865
|
+
|
|
1866
|
+
# log_metrics must have uploaded the seeded units, and the units set by
|
|
1867
|
+
# set_metric_units must still be pending for the next log_metrics call
|
|
1868
|
+
assert run._meta_cache.get("metrics") == {
|
|
1869
|
+
"b": {"units": "ft", "mks_units": "m", "mks_conversion": 0.3048}
|
|
1870
|
+
}
|