Skip to content

Commit ba91f28

Browse files
support variables in script; change argument release to version (#143)
Co-authored-by: pyansys-ci-bot <[email protected]>
1 parent a6a4e7e commit ba91f28

File tree

8 files changed

+57
-34
lines changed

8 files changed

+57
-34
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
support variables in script; change argument release to version

doc/source/getting-started.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Getting started
22
###############
33

44
To run PyWorkbench, you must have a licensed copy of `Workbench
5-
<https://www.ansys.com/products/ansys-workbench>`_ of release 24.2 or above.
5+
<https://www.ansys.com/products/ansys-workbench>`_ of version 24.2 or later.
66

77
.. grid:: 2
88

doc/source/user-guide.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ This code launches a server on a remote Windows machine with valid user credenti
5858
wb = launch_workbench(host=host, username=username, password=password)
5959
6060
Other options for the ``launch_workbench()`` function include specifying a particular
61-
Workbench release to launch, whether to launch in UI mode, and specifying working directories
61+
Workbench version to launch, whether to launch in UI mode, and specifying working directories
6262
on the server and/or the client instead of using the default directories:
6363

6464
.. code-block:: python
@@ -67,7 +67,7 @@ on the server and/or the client instead of using the default directories:
6767
6868
wb = launch_workbench(
6969
show_gui=False,
70-
release="242",
70+
version="251",
7171
server_workdir="path_to_a_dir_on_server",
7272
client_workdir="path_to_a_dir_on_client",
7373
)
@@ -153,7 +153,7 @@ This client script downloads all files with ``.out`` extensions from the server'
153153
154154
There is a special client method to upload a data file from the Ansys
155155
`example-data <https://github.com/ansys/example-data/raw/master/pyworkbench>`_ repository
156-
directly to the Workbench server. You should specify the file path relative to the
156+
directly to the Workbench server. You should specify the path relative to the
157157
``pyworkbench`` folder in the ``example-data`` repository:
158158

159159
.. code-block:: python

doc/styles/config/vocabularies/ANSYS/accept.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
Workbench
77
PyMechanical
88
PyFluent
9+
PySherlock

src/ansys/workbench/core/public_api.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ class LaunchWorkbench(ClientWrapper):
7474
----------
7575
show_gui : bool, default: True
7676
Weather to launch Workbench in UI mode.
77-
release : str, default: "242"
78-
Workbench release to launch.
77+
version : str, default: None
78+
Workbench version to launch. It must be a 3-digit version that is "242" or later.
7979
client_workdir : str, default: None
8080
Path to a writable directory on the client computer. The default is ``None``,
8181
in which case the system temp directory is used.
@@ -95,7 +95,7 @@ class LaunchWorkbench(ClientWrapper):
9595
Raises
9696
------
9797
Exception
98-
If the Ansys release number is invalid.
98+
If the Ansys version number is invalid.
9999
100100
Examples
101101
--------
@@ -108,7 +108,7 @@ class LaunchWorkbench(ClientWrapper):
108108
def __init__(
109109
self,
110110
show_gui=True,
111-
release="242",
111+
version="242",
112112
client_workdir=None,
113113
server_workdir=None,
114114
host=None,
@@ -119,18 +119,18 @@ def __init__(
119119
self._process_id = -1
120120

121121
if (
122-
len(release) != 3
123-
or not release.isdigit()
124-
or release[0] not in ["2", "3"]
125-
or release[2] not in ["1", "2"]
122+
len(version) != 3
123+
or not version.isdigit()
124+
or version[0] not in ["2", "3"]
125+
or version[2] not in ["1", "2"]
126126
):
127-
raise Exception("Invalid ANSYS release: " + release)
128-
port = self.__launch_server(show_gui, host, release, server_workdir, username, password)
127+
raise Exception("Invalid ANSYS version: " + version)
128+
port = self.__launch_server(show_gui, host, version, server_workdir, username, password)
129129
if port is None or port <= 0:
130130
raise Exception("Filed to launch Ansys Workbench service.")
131131
super().__init__(port, client_workdir, host)
132132

133-
def __launch_server(self, show_gui, host, release, server_workdir, username, password):
133+
def __launch_server(self, show_gui, host, version, server_workdir, username, password):
134134
"""Launch a Workbench server on the local or a remote Windows machine."""
135135
try:
136136
if host is None:
@@ -146,11 +146,11 @@ def __launch_server(self, show_gui, host, release, server_workdir, username, pas
146146

147147
install_path = None
148148
for ev in self._wmi_connection.Win32_Environment():
149-
if ev.Name == "AWP_ROOT" + release:
149+
if ev.Name == "AWP_ROOT" + version:
150150
install_path = ev.VariableValue
151151
break
152152
if install_path is None:
153-
install_path = "C:/Program Files/Ansys Inc/v" + release
153+
install_path = "C:/Program Files/Ansys Inc/v" + version
154154
logging.warning(
155155
"Ansys installation is not found. Assume the default location: " + install_path
156156
)
@@ -260,7 +260,7 @@ def exit(self):
260260

261261
def launch_workbench(
262262
show_gui=True,
263-
release="242",
263+
version=None,
264264
client_workdir=None,
265265
server_workdir=None,
266266
host=None,
@@ -276,8 +276,8 @@ def launch_workbench(
276276
----------
277277
show_gui : bool, default: True
278278
Weather to launch Workbench in UI mode.
279-
release : str, default: "251"
280-
Workbench release to launch.
279+
version : str, default: None
280+
Workbench version to launch. It must be a 3-digit version that is "242" or later.
281281
client_workdir : str, default: None
282282
Path to a writable directory on the client computer. The default is ``None``,
283283
in which case the system temp directory is used.
@@ -308,7 +308,7 @@ def launch_workbench(
308308
309309
"""
310310
return LaunchWorkbench(
311-
show_gui, release, client_workdir, server_workdir, host, username, password
311+
show_gui, version, client_workdir, server_workdir, host, username, password
312312
)
313313

314314

src/ansys/workbench/core/workbench_client.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import logging.handlers
2929
from logging.handlers import WatchedFileHandler
3030
import os
31+
import re
3132

3233
import grpc
3334
import tqdm
@@ -102,7 +103,7 @@ def set_console_log_level(self, log_level):
102103
Parameters
103104
----------
104105
log_level : str, default: "error"
105-
Level of logging. Options are "critical" "debug", "error", "info", and "warning".
106+
Level of logging. Options are "critical", "debug", "error", "info", and "warning".
106107
"""
107108
self.__log_console_handler.setLevel(WorkbenchClient.__to_python_log_level(log_level))
108109

@@ -135,15 +136,18 @@ def reset_log_file(self):
135136
__log_file_handler = None
136137
__log_console_handler = None
137138

138-
def run_script_string(self, script_string, log_level="error"):
139+
def run_script_string(self, script_string, args=None, log_level="error"):
139140
"""Run a script as given in the input string on the server.
140141
141142
Parameters
142143
----------
143144
script_string : str
144145
String containing the content of the script to run.
146+
args : dictionary of script variable names and values
147+
Variables in the script specified as $$varname%%50%% will be converted to variable
148+
values or use the default value - 50 in the example.
145149
log_level : str, default: "error"
146-
Level of logging. Options are "critical" "debug", "error", "info", and "warning".
150+
Level of logging. Options are "critical", "debug", "error", "info", and "warning".
147151
148152
Returns
149153
-------
@@ -162,8 +166,22 @@ def run_script_string(self, script_string, log_level="error"):
162166
"""
163167
if not self._is_connected():
164168
logging.error("Workbench client is not yet connected to a server.")
169+
return None
170+
updated_script_string = script_string
171+
if args and len(args) > 0:
172+
if any(not re.match(r"^\w+$", arg) for arg in args.keys()):
173+
logging.error("script argument name contains illegal character.")
174+
return None
175+
for arg_name in args:
176+
updated_script_string = re.sub(
177+
r"\$\$" + arg_name + r"%%((?!%%).)*%%",
178+
str(args[arg_name]),
179+
updated_script_string,
180+
)
181+
updated_script_string = re.sub(r"\$\$\w+%%(((?!%%).)*)%%", r"\1", updated_script_string)
165182
request = wb.RunScriptRequest(
166-
content=script_string, log_level=WorkbenchClient.__to_server_log_level(log_level)
183+
content=updated_script_string,
184+
log_level=WorkbenchClient.__to_server_log_level(log_level),
167185
)
168186
for response in self.stub.RunScript(request):
169187
if response.log and response.log.messages and len(response.log.messages) > 0:
@@ -177,16 +195,19 @@ def run_script_string(self, script_string, log_level="error"):
177195
logging.info("The script has finisished.")
178196
return json.loads(response.result.result)
179197

180-
def run_script_file(self, script_file_name, log_level="error"):
198+
def run_script_file(self, script_file_name, args=None, log_level="error"):
181199
"""Run a script file on the server.
182200
183201
Parameters
184202
----------
185203
script_file_name : str
186204
Name of the script file to run. The script file should be located in the client
187205
working directory
206+
args : dictionary of script variable names and values
207+
Variables in the script specified as $$varname%%50%% will be converted to variable
208+
values or use the default value - 50 in the example.
188209
log_level : str, default: "error"
189-
Level of logging. Options are "critical" "debug", "error", "info", and "warning".
210+
Level of logging. Options are "critical", "debug", "error", "info", and "warning".
190211
191212
Returns
192213
-------
@@ -195,10 +216,11 @@ def run_script_file(self, script_file_name, log_level="error"):
195216
"""
196217
if not self._is_connected():
197218
logging.error("Workbench client is not yet connected to a server")
219+
return None
198220
script_path = os.path.join(self.workdir, script_file_name)
199221
with open(script_path, encoding="utf-8-sig") as sf:
200222
script_string = sf.read()
201-
return self.run_script_string(script_string, log_level)
223+
return self.run_script_string(script_string, args, log_level)
202224

203225
def upload_file(self, *file_list, show_progress=True):
204226
"""Upload one or more files from the client to the server.
@@ -218,6 +240,7 @@ def upload_file(self, *file_list, show_progress=True):
218240
"""
219241
if not self._is_connected():
220242
logging.error("Workbench client is not yet connected to a server.")
243+
return
221244
requested = []
222245
for file_pattern in file_list:
223246
if "*" in file_pattern or "?" in file_pattern:
@@ -289,6 +312,7 @@ def upload_file_from_example_repo(self, relative_file_path, show_progress=True):
289312
"""
290313
if not self._is_connected():
291314
logging.error("Workbench client is not yet connected to a server.")
315+
return
292316
downloaded = ExampleData.download(relative_file_path, self.workdir)
293317
self.upload_file(downloaded, show_progress=show_progress)
294318

@@ -315,6 +339,7 @@ def download_file(self, file_name, show_progress=True, target_dir=None):
315339
"""
316340
if not self._is_connected():
317341
logging.error("Workbench client is not yet connected to a server.")
342+
return None
318343
request = wb.DownloadFileRequest(file_name=file_name)
319344
file_name = file_name.replace("*", "_").replace("?", "_")
320345
td = target_dir
@@ -406,7 +431,7 @@ def __to_server_log_level(log_level):
406431
Parameters
407432
----------
408433
log_level : str
409-
Level of logging. Options are "critical" "debug", "error", "info", and "warning".
434+
Level of logging. Options are "critical", "debug", "error", "info", and "warning".
410435
411436
Returns
412437
-------

tests/test_launch_workbench.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def workbench():
3434
"""Launch workbench."""
3535
workdir = pathlib.Path(__file__).parent
3636
wb = launch_workbench(
37-
release="241",
37+
version="241",
3838
server_workdir=str(workdir.absolute()),
3939
client_workdir=str(workdir.absolute()),
4040
)

tests/test_workbench_client.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,6 @@ def test_run_script_file(mock_workbench_service_stub):
156156
assert mock_stub.RunScript.call_count == 1
157157
assert mock_response.result.result == "{'result': 'success'}"
158158

159-
client._disconnect()
160-
with pytest.raises(Exception):
161-
client.run_script_file(script_dir / "cooled_turbine_blade.py")
162-
163159

164160
def test_upload_file(mock_workbench_service_stub):
165161
"""Test the upload_file method."""

0 commit comments

Comments
 (0)