diff --git a/src/ansys/optislang/core/nodes.py b/src/ansys/optislang/core/nodes.py index c44758b59..5bfe63cdd 100644 --- a/src/ansys/optislang/core/nodes.py +++ b/src/ansys/optislang/core/nodes.py @@ -27,6 +27,8 @@ from enum import Enum from typing import TYPE_CHECKING, Any, Optional, Tuple, Union +from deprecated.sphinx import deprecated + from ansys.optislang.core.io import File, FileOutputFormat, RegisteredFile from ansys.optislang.core.utils import enum_from_str @@ -1366,7 +1368,80 @@ def get_omdb_files(self) -> Tuple[File]: # pragma: no cover """ pass + def save_designs_as_json( + self, hid: str, file_path: Union[Path, str] + ) -> File: # pragma: no cover + """Save designs for a given state to JSON file. + + Parameters + ---------- + hid : str + Actor's state. + file_path : Union[Path, str] + Path to the file. + + Returns + ------- + File + Object representing saved file. + + Raises + ------ + OslCommunicationError + Raised when an error occurs while communicating with the server. + OslCommandError + Raised when a command or query fails. + TimeoutError + Raised when the timeout float value expires. + TypeError + Raised when the `hid` is `None` + -or- + `file_path` is `None` or unsupported type. + ValueError + Raised when ``hid`` does not exist. + """ + pass + + def save_designs_as_csv( + self, hid: str, file_path: Union[Path, str] + ) -> File: # pragma: no cover + """Save designs for a given state to CSV file. + + Parameters + ---------- + hid : str + Actor's state. + file_path : Union[Path, str] + Path to the file. + + Returns + ------- + File + Object representing saved file. + + Raises + ------ + OslCommunicationError + Raised when an error occurs while communicating with the server. + OslCommandError + Raised when a command or query fails. + TimeoutError + Raised when the timeout float value expires. + TypeError + Raised when the `hid` is `None` + -or- + `file_path` is `None` or unsupported type. + ValueError + Raised when ``hid`` does not exist. + """ + pass + @abstractmethod + @deprecated( + version="0.9.0", + reason="Use :py:meth:`ParametricSystem.save_designs_as_json` or " + ":py:meth:`ParametricSystem.save_designs_as_csv` instead.", + ) def save_designs_as( self, hid: str, diff --git a/src/ansys/optislang/core/tcp/nodes.py b/src/ansys/optislang/core/tcp/nodes.py index ec096d868..cbf6aceb3 100644 --- a/src/ansys/optislang/core/tcp/nodes.py +++ b/src/ansys/optislang/core/tcp/nodes.py @@ -2171,6 +2171,138 @@ def get_omdb_files(self) -> Tuple[File]: omdb_files.extend([File(path) for path in wdir.glob("*.omdb")]) return tuple(omdb_files) + def save_designs_as_json(self, hid: str, file_path: Union[Path, str]) -> File: + """Save designs for a given state to JSON file. + + Parameters + ---------- + hid : str + Actor's state. + file_path : Union[Path, str] + Path to the file. + + Returns + ------- + File + Object representing saved file. + + Raises + ------ + OslCommunicationError + Raised when an error occurs while communicating with the server. + OslCommandError + Raised when a command or query fails. + TimeoutError + Raised when the timeout float value expires. + TypeError + Raised when the `hid` is `None` + -or- + `file_path` is `None` or unsupported type. + ValueError + Raised when ``hid`` does not exist. + """ + self.__save_designs_as(hid, file_path, FileOutputFormat.JSON) + + def save_designs_as_csv(self, hid: str, file_path: Union[Path, str]) -> File: + """Save designs for a given state to CSV file. + + Parameters + ---------- + hid : str + Actor's state. + file_path : Union[Path, str] + Path to the file. + + Returns + ------- + File + Object representing saved file. + + Raises + ------ + OslCommunicationError + Raised when an error occurs while communicating with the server. + OslCommandError + Raised when a command or query fails. + TimeoutError + Raised when the timeout float value expires. + TypeError + Raised when the `hid` is `None` + -or- + `file_path` is `None` or unsupported type. + ValueError + Raised when ``hid`` does not exist. + """ + self.__save_designs_as(hid, file_path, FileOutputFormat.CSV) + + def __save_designs_as(self, hid: str, file_path: Union[Path, str], format: FileOutputFormat): + """Save designs for a given state. + + Parameters + ---------- + hid : str + Actor's state. + file_path : Union[Path, str] + Path to the file. + format : FileOutputFormat + Format of the file. + + Returns + ------- + File + Object representing saved file. + + Raises + ------ + OslCommunicationError + Raised when an error occurs while communicating with the server. + OslCommandError + Raised when a command or query fails. + TimeoutError + Raised when the timeout float value expires. + TypeError + Raised when the `hid` is `None` + -or- + `file_path` is `None` or unsupported type. + ValueError + Raised when ``format`` is not unsupported + -or- + ``hid`` does not exist. + """ + if hid is None: + raise TypeError("Actor's state cannot be `None`.") + if file_path is None: + raise TypeError("Path to the file cannot be `None`.") + if isinstance(file_path, str): + file_path = Path(file_path) + if not isinstance(file_path, Path): + raise TypeError( + "Type of the `file_path` argument is not supported: `file_path` = " + f"`{type(file_path)}`." + ) + + designs = self._get_designs_dicts() + if not designs.get(hid): + raise ValueError(f"Design for given `hid` argument not available: `hid` = `{hid}.") + + if format == FileOutputFormat.JSON: + file_output = json.dumps(designs[hid]) + newline = None + elif format == FileOutputFormat.CSV: + file_output = self.__convert_design_dict_to_csv(designs[hid]) + newline = "" + else: + raise ValueError(f"Output file format `{format}` is not supported.") + + with open(file_path, "w", newline=newline) as f: + f.write(file_output) + return File(file_path) + + @deprecated( + version="0.9.0", + reason="Use :py:meth:`TcpParametricSystemProxy.save_designs_as_json` or " + ":py:meth:`TcpParametricSystemProxy.save_designs_as_csv` instead.", + ) def save_designs_as( self, hid: str, diff --git a/tests/tcp/test_tcp_nodes.py b/tests/tcp/test_tcp_nodes.py index 399c81ece..3c49c3524 100644 --- a/tests/tcp/test_tcp_nodes.py +++ b/tests/tcp/test_tcp_nodes.py @@ -25,7 +25,7 @@ import pytest from ansys.optislang.core import Optislang -from ansys.optislang.core.io import File, FileOutputFormat, RegisteredFile +from ansys.optislang.core.io import File, RegisteredFile from ansys.optislang.core.node_types import AddinType, NodeType, Sensitivity, optislang_node from ansys.optislang.core.osl_server import OslVersion from ansys.optislang.core.tcp.managers import CriteriaManager, ParameterManager, ResponseManager @@ -447,32 +447,39 @@ def test_get_omdb_files(optislang: Optislang, tmp_example_project): def test_save_designs_as(tmp_path: Path, tmp_example_project): - """Test `save_designs_as` method.""" - optislang = Optislang(project_path=tmp_example_project("omdb_files")) - optislang.timeout = 60 - optislang.application.project.reset() - optislang.application.project.start() + """Test `save_designs_as_json` and `save_designs_as_csv` methods.""" + with Optislang(project_path=tmp_example_project("omdb_files")) as osl: + osl.timeout = 60 + osl.application.project.reset() + osl.application.project.start() - project = optislang.project - root_system = project.root_system + project = osl.project + root_system = project.root_system + + __test_save_designs_as_json(tmp_path, root_system) + __test_save_designs_as_csv(tmp_path, root_system) + +def __test_save_designs_as_json(tmp_path: Path, root_system: TcpRootSystemProxy): + """Test `save_designs_as_json` method.""" sensitivity: TcpParametricSystemProxy = root_system.find_nodes_by_name("Sensitivity")[0] s_hids = sensitivity.get_states_ids() - s_file = sensitivity.save_designs_as(s_hids[0], "FirstDesign", FileOutputFormat.CSV, tmp_path) - assert isinstance(s_file, File) - assert s_file.exists - assert s_file.path.suffix == ".csv" + csv_file_path = tmp_path / "FirstDesign.csv" + csv_file = sensitivity.save_designs_as_csv(s_hids[0], csv_file_path) + assert isinstance(csv_file, File) + assert csv_file.exists + +def __test_save_designs_as_csv(tmp_path: Path, root_system: TcpRootSystemProxy): + """Test `save_designs_as_csv` method.""" most_inner_sensitivity: TcpParametricSystemProxy = root_system.find_nodes_by_name( "MostInnerSensitivity", 3 )[0] mis_hids = most_inner_sensitivity.get_states_ids() - mis_file = most_inner_sensitivity.save_designs_as(mis_hids[0], "InnerDesign") - assert isinstance(mis_file, File) - assert mis_file.exists - assert mis_file.path.suffix == ".json" - mis_file.path.unlink() - assert not mis_file.exists + json_file_path = tmp_path / "InnerDesign.json" + json_file = most_inner_sensitivity.save_designs_as_json(mis_hids[0], json_file_path) + assert isinstance(json_file, File) + assert json_file.exists # endregion