From 72099da7c5f7c5f53043ff026dbaad462c71e63a Mon Sep 17 00:00:00 2001 From: Federico Negri Date: Fri, 17 May 2024 09:53:20 +0200 Subject: [PATCH 1/2] list default exec scripts --- src/ansys/hps/client/jms/api/jms_api.py | 29 ++++++++++++++++++++- src/ansys/hps/client/jms/api/project_api.py | 20 +++++++++----- tests/jms/test_jms_api.py | 23 ++++++++++++++++ tests/jms/test_projects.py | 4 +++ 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/ansys/hps/client/jms/api/jms_api.py b/src/ansys/hps/client/jms/api/jms_api.py index 4691aa42..fa233c35 100644 --- a/src/ansys/hps/client/jms/api/jms_api.py +++ b/src/ansys/hps/client/jms/api/jms_api.py @@ -68,6 +68,7 @@ def __init__(self, client: Client): """Initialize JMS API.""" self.client = client self._fs_url = None + self._api_info = None @property def url(self) -> str: @@ -81,7 +82,7 @@ def fs_url(self) -> str: self._fs_url = _find_available_fs_url(self.get_storage()) return self._fs_url - def get_api_info(self): + def get_api_info(self) -> dict: """Get information of the JMS API that the client is connected to. Information includes the version and build date. @@ -89,6 +90,18 @@ def get_api_info(self): r = self.client.session.get(self.url) return r.json() + @property + def api_info(self) -> dict: + """Information of the JMS API that the client is connected to.""" + if self._api_info is None: + self._api_info = self.get_api_info() + return self._api_info + + @property + def execution_script_default_bucket(self) -> str: + """Default bucket for execution scripts.""" + return self.api_info["settings"]["execution_script_default_bucket"] + ################################################################ # Projects def get_projects(self, as_objects=True, **query_params) -> List[Project]: @@ -245,6 +258,20 @@ def update_task_definition_template_permissions( as_objects, ) + # Execution Scripts + def list_default_execution_scripts(self) -> list[str]: + """List default execution scripts. + + Returns a list of available default execution scripts that can be passed + as input to the :meth:`ProjectApi.copy_default_execution_script` method. + """ + r = self.client.session.get(f"{self.fs_url}/list/{self.execution_script_default_bucket}") + file_list = [ + f.replace(f"ansfs://{self.execution_script_default_bucket}/", "") + for f in r.json()["file_list"] + ] + return file_list + ################################################################ # Operations def get_operations(self, as_objects=True, **query_params) -> List[Operation]: diff --git a/src/ansys/hps/client/jms/api/project_api.py b/src/ansys/hps/client/jms/api/project_api.py index f74fd790..02169bca 100644 --- a/src/ansys/hps/client/jms/api/project_api.py +++ b/src/ansys/hps/client/jms/api/project_api.py @@ -104,12 +104,20 @@ def __init__(self, client: Client, project_id: str): self.project_id = project_id self._fs_url = None self._fs_project_id = None + self._jms_api = None @property def jms_api_url(self) -> str: """Get the JMS API URL.""" return f"{self.client.url}/jms/api/v1" + @property + def jms_api(self) -> JmsApi: + """Get the JMS API object.""" + if self._jms_api is None: + self._jms_api = JmsApi(self.client) + return self._jms_api + @property def url(self) -> str: """URL of the API.""" @@ -119,7 +127,7 @@ def url(self) -> str: def fs_url(self) -> str: """URL of the file storage gateway.""" if self._fs_url is None: - self._fs_url = JmsApi(self.client).fs_url + self._fs_url = self.jms_api.fs_url return self._fs_url @property @@ -593,7 +601,7 @@ def delete_license_contexts(self): """Delete license contexts.""" rest_name = LicenseContext.Meta.rest_name url = f"{self.jms_api_url}/projects/{self.id}/{rest_name}" - r = self.client.session.delete(url) + _ = self.client.session.delete(url) ################################################################ def copy_default_execution_script(self, filename: str) -> File: @@ -601,8 +609,10 @@ def copy_default_execution_script(self, filename: str) -> File: Example: - >>> file = project_api.copy_default_execution_script("exec_mapdl.py") + >>> file = project_api.copy_default_execution_script("mapdl-v241-exec_mapdl.py") + You can use the :meth:`JmsApi.list_default_execution_scripts` to query + the list of available default execution scripts. """ # create file resource @@ -611,9 +621,7 @@ def copy_default_execution_script(self, filename: str) -> File: file = self.create_files([file])[0] # query location of default execution scripts from server - jms_api = JmsApi(self.client) - info = jms_api.get_api_info() - execution_script_default_bucket = info["settings"]["execution_script_default_bucket"] + execution_script_default_bucket = self.jms_api.execution_script_default_bucket # server side copy of the file to project bucket checksum = _fs_copy_file( diff --git a/tests/jms/test_jms_api.py b/tests/jms/test_jms_api.py index 4647fe6e..961fb801 100644 --- a/tests/jms/test_jms_api.py +++ b/tests/jms/test_jms_api.py @@ -27,6 +27,7 @@ import pytest from ansys.hps.client import Client, ClientError, HPSError +from ansys.hps.client import __ansys_apps_version__ as ansys_version from ansys.hps.client.jms import JmsApi, ProjectApi from ansys.hps.client.jms.api.jms_api import _find_available_fs_url from ansys.hps.client.jms.resource import ( @@ -53,6 +54,10 @@ def test_jms_api_info(client): assert "settings" in info assert "time" in info + assert jms_api._api_info is None + _ = jms_api.execution_script_default_bucket + assert jms_api._api_info is not None + def test_unavailable_fs_url(client): @@ -233,3 +238,21 @@ def test_objects_type_check(client): ) JmsApi(client).delete_project(proj) + + +def test_list_default_execution_scripts(client): + + jms_api = JmsApi(client) + file_names = jms_api.list_default_execution_scripts() + assert len(file_names) > 0 + for fn in file_names: + assert isinstance(fn, str) + assert len(fn) > 0 + + ansys_short_version = f"v{ansys_version[2:4]}{ansys_version[6]}" + for product_name in ["mapdl", "lsdyna", "fluent"]: + script_name = f"{product_name}-{ansys_short_version}-exec_{product_name}.py" + assert script_name in file_names + + assert "mechanical-exec_mechanical.py" in file_names + assert "web-sample_execution_script.py" in file_names diff --git a/tests/jms/test_projects.py b/tests/jms/test_projects.py index 6d28e88e..27986ed3 100644 --- a/tests/jms/test_projects.py +++ b/tests/jms/test_projects.py @@ -282,6 +282,8 @@ def test_copy_exec_script(client): proj = jms_api.create_project(proj) project_api = ProjectApi(client, proj.id) + assert project_api._jms_api is None + ansys_short_version = f"v{ansys_version[2:4]}{ansys_version[6]}" script_name = f"mapdl-{ansys_short_version}-exec_mapdl" file = project_api.copy_default_execution_script(f"{script_name}.py") @@ -290,4 +292,6 @@ def test_copy_exec_script(client): assert file.hash is not None assert file.storage_id is not None + assert project_api._jms_api is not None + jms_api.delete_project(proj) From e8ec1929c925977f0dbf0cada9dff2516c2d5f97 Mon Sep 17 00:00:00 2001 From: Federico Negri Date: Fri, 17 May 2024 09:56:05 +0200 Subject: [PATCH 2/2] adjust docstring --- src/ansys/hps/client/jms/api/project_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/hps/client/jms/api/project_api.py b/src/ansys/hps/client/jms/api/project_api.py index 02169bca..0bcfcc4c 100644 --- a/src/ansys/hps/client/jms/api/project_api.py +++ b/src/ansys/hps/client/jms/api/project_api.py @@ -611,7 +611,7 @@ def copy_default_execution_script(self, filename: str) -> File: >>> file = project_api.copy_default_execution_script("mapdl-v241-exec_mapdl.py") - You can use the :meth:`JmsApi.list_default_execution_scripts` to query + You can use the method :meth:`JmsApi.list_default_execution_scripts` to query the list of available default execution scripts. """