diff --git a/simvue/config/user.py b/simvue/config/user.py index 8e80bb0b..5c89ba3f 100644 --- a/simvue/config/user.py +++ b/simvue/config/user.py @@ -4,6 +4,7 @@ """ +import contextlib import functools import http import logging @@ -70,6 +71,7 @@ class SimvueConfiguration(pydantic.BaseModel): eco: EcoConfig = EcoConfig() current_profile: str | None = None _server_version: semver.Version | None = None + _nosim_version: semver.Version | None = None @property def server_verify(self) -> str | bool: @@ -84,6 +86,11 @@ def server_version(self) -> semver.Version: raise RuntimeError("Expected server version to be defined") return self._server_version + @property + def nosim_version(self) -> semver.Version | None: + """Retrieve current noSim version if available.""" + return self._nosim_version + @classmethod def _load_pyproject_configs(cls) -> dict | None: """Recover any Simvue non-authentication configurations from pyproject.toml.""" @@ -127,14 +134,16 @@ def _check_server( url: str, mode: typing.Literal["offline", "online", "disabled"], verify: str | bool, - ) -> semver.Version | None: + ) -> tuple[semver.Version | None, semver.Version | None]: if mode in {"offline", "disabled"}: - return None + return None, None headers: dict[str, str] = { "Authorization": f"Bearer {token}", "User-Agent": f"Simvue Python client {__version__}", } + + # Retrieve Server version try: _url = URL(url) / "version" _response = sv_get(f"{_url}", headers=headers, verify=verify) @@ -152,6 +161,22 @@ def _check_server( f"Exception retrieving server version:\n {err!s}", ) from err + _nosim_version_str: str = "" + _nosim_version: semver.Version | None = None + + # Retrieve noSim version if applicable + with contextlib.suppress(Exception): + _url = URL(url) / "nosim" / "version" + _response = sv_get(f"{_url}", headers=headers, verify=verify) + + if _response.status_code == http.HTTPStatus.UNAUTHORIZED: + raise AssertionError("Unauthorised token") + + if _response.status_code == http.HTTPStatus.OK and ( + _nosim_version_str := _response.json().get("version") + ): + _nosim_version = semver.Version.parse(_nosim_version_str) + _version = semver.Version.parse(_version_str) if ( @@ -159,16 +184,18 @@ def _check_server( and _version >= SIMVUE_SERVER_UPPER_CONSTRAINT ): raise AssertionError( - f"Python API v{_version_str} is not compatible " - "with Simvue server versions " - f">= {SIMVUE_SERVER_UPPER_CONSTRAINT}", + f"Python API v{__version__} is not compatible " + "with the current Simvue server version: " + f"{_version_str} >= {SIMVUE_SERVER_UPPER_CONSTRAINT}", ) if SIMVUE_SERVER_LOWER_CONSTRAINT and _version < SIMVUE_SERVER_LOWER_CONSTRAINT: raise AssertionError( - f"Python API v{_version_str} is not compatible with Simvue " - f"server versions < {SIMVUE_SERVER_LOWER_CONSTRAINT}", + f"Python API v{__version__} is not compatible " + "with the current Simvue server version: " + f"{_version_str} < {SIMVUE_SERVER_LOWER_CONSTRAINT}", ) - return _version + + return _version, _nosim_version @pydantic.validate_call def write(self, out_directory: pydantic.DirectoryPath) -> None: @@ -183,7 +210,7 @@ def check_valid_server(self) -> Self: if not self.server.token: raise ValueError("No token provided.") - self._server_version = self._check_server( + self._server_version, self._nosim_version = self._check_server( token=self.server.token.get_secret_value(), url=self.server.url, verify=self.server_verify, diff --git a/tests/functional/test_run_class.py b/tests/functional/test_run_class.py index a6d6f04b..0d7c7842 100644 --- a/tests/functional/test_run_class.py +++ b/tests/functional/test_run_class.py @@ -814,6 +814,9 @@ def test_set_folder_details(request: pytest.FixtureRequest) -> None: with sv_run.Run() as run: folder_name: str = f"/simvue_unit_testing/{_uuid}" description: str = "test description" + metadata: dict[str, str] = { + "test_name": "test_set_folder_details" + } tags: list[str] = [ "simvue_client_unit_tests", "test_set_folder_details" @@ -824,7 +827,7 @@ def test_set_folder_details(request: pytest.FixtureRequest) -> None: visibility="tenant" if os.environ.get("CI") else None, retention_period=os.environ.get("SIMVUE_TESTING_RETENTION_PERIOD", "2 mins"), ) - run.set_folder_details(tags=tags, description=description) + run.set_folder_details(tags=tags, description=description, metadata=metadata) client = sv_cl.Client() _folder = client.get_folder(folder_path=folder_name) diff --git a/uv.lock b/uv.lock index 9a8c5877..1004b286 100644 --- a/uv.lock +++ b/uv.lock @@ -1847,7 +1847,7 @@ wheels = [ [[package]] name = "simvue" -version = "2.5.5" +version = "2.5.7" source = { editable = "." } dependencies = [ { name = "click" },