ansys-pyensight-core 0.11.0__py3-none-any.whl

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.
Files changed (37) hide show
  1. ansys/pyensight/core/__init__.py +41 -0
  2. ansys/pyensight/core/common.py +341 -0
  3. ansys/pyensight/core/deep_pixel_view.html +98 -0
  4. ansys/pyensight/core/dockerlauncher.py +1124 -0
  5. ansys/pyensight/core/dvs.py +872 -0
  6. ansys/pyensight/core/enscontext.py +345 -0
  7. ansys/pyensight/core/enshell_grpc.py +641 -0
  8. ansys/pyensight/core/ensight_grpc.py +874 -0
  9. ansys/pyensight/core/ensobj.py +515 -0
  10. ansys/pyensight/core/launch_ensight.py +296 -0
  11. ansys/pyensight/core/launcher.py +388 -0
  12. ansys/pyensight/core/libuserd.py +2110 -0
  13. ansys/pyensight/core/listobj.py +280 -0
  14. ansys/pyensight/core/locallauncher.py +579 -0
  15. ansys/pyensight/core/py.typed +0 -0
  16. ansys/pyensight/core/renderable.py +880 -0
  17. ansys/pyensight/core/session.py +1923 -0
  18. ansys/pyensight/core/sgeo_poll.html +24 -0
  19. ansys/pyensight/core/utils/__init__.py +21 -0
  20. ansys/pyensight/core/utils/adr.py +111 -0
  21. ansys/pyensight/core/utils/dsg_server.py +1220 -0
  22. ansys/pyensight/core/utils/export.py +606 -0
  23. ansys/pyensight/core/utils/omniverse.py +769 -0
  24. ansys/pyensight/core/utils/omniverse_cli.py +614 -0
  25. ansys/pyensight/core/utils/omniverse_dsg_server.py +1196 -0
  26. ansys/pyensight/core/utils/omniverse_glb_server.py +848 -0
  27. ansys/pyensight/core/utils/parts.py +1221 -0
  28. ansys/pyensight/core/utils/query.py +487 -0
  29. ansys/pyensight/core/utils/readers.py +300 -0
  30. ansys/pyensight/core/utils/resources/Materials/000_sky.exr +0 -0
  31. ansys/pyensight/core/utils/support.py +128 -0
  32. ansys/pyensight/core/utils/variables.py +2019 -0
  33. ansys/pyensight/core/utils/views.py +674 -0
  34. ansys_pyensight_core-0.11.0.dist-info/METADATA +309 -0
  35. ansys_pyensight_core-0.11.0.dist-info/RECORD +37 -0
  36. ansys_pyensight_core-0.11.0.dist-info/WHEEL +4 -0
  37. ansys_pyensight_core-0.11.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,641 @@
1
+ # Copyright (C) 2022 - 2026 ANSYS, Inc. and/or its affiliates.
2
+ # SPDX-License-Identifier: MIT
3
+ #
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ """
24
+ Python wrapper for the core enshellservice
25
+
26
+ This package defines the EnShellGRPC class which provides a simpler
27
+ interface to the EnShell gRPC interface.
28
+
29
+ Python binding for the EnShell gRPC API
30
+
31
+ This class provides an asynchronous interface to the EnShell
32
+ core gRPC interface.
33
+ """
34
+ import logging
35
+ import os
36
+ import random
37
+ import re
38
+ import subprocess
39
+ import sys
40
+ from typing import TYPE_CHECKING, Optional
41
+
42
+ from ansys.api.pyensight.v0 import enshell_pb2, enshell_pb2_grpc
43
+ from ansys.pyensight.core import DEFAULT_ANSYS_VERSION # pylint: disable=import-outside-toplevel
44
+ from ansys.tools.common.cyberchannel import create_channel
45
+ import grpc
46
+
47
+ if TYPE_CHECKING:
48
+ from ansys.pyensight.core import Session
49
+
50
+
51
+ class EnShellGRPC(object):
52
+ """Create an instance of the EnShell gRPC interface wrapper.
53
+
54
+ The default is to make a connection to an EnShell gRPC server
55
+ on port 12345 on the loopback host. If requested to launch
56
+ the server, it will be the current version.
57
+
58
+ Parameters
59
+ ----------
60
+ port: int, optional
61
+ The port number of the EnShell gRPC server
62
+ host:
63
+ The hostname of the EnShell gRPC server
64
+ version:
65
+ A specific EnShell version number to run (e.g. '232' for 2023R2)
66
+ secret_key: str, optional
67
+ Connection secret key
68
+ grpc_use_tcp_sockets :
69
+ If using gRPC, and if True, then allow TCP Socket based connections
70
+ instead of only local connections.
71
+ grpc_allow_network_connections :
72
+ If using gRPC and using TCP Socket based connections, listen on all networks.
73
+ grpc_disable_tls :
74
+ If using gRPC and using TCP Socket based connections, disable TLS.
75
+ grpc_uds_pathname :
76
+ If using gRPC and using Unix Domain Socket based connections, explicitly
77
+ set the pathname to the shared UDS file instead of using the default.
78
+ disable_grpc_options: bool, optional
79
+ Whether to disable the gRPC options check, and allow to run older
80
+ versions of EnSight
81
+
82
+ WARNING:
83
+ Overriding the default values for these options: grpc_use_tcp_sockets, grpc_allow_network_connections,
84
+ and grpc_disable_tls
85
+ can possibly permit control of this computer and any data which resides on it.
86
+ Modification of this configuration is not recommended. Please see the
87
+ documentation for your installed product for additional information.
88
+ """
89
+
90
+ def __init__(
91
+ self,
92
+ port: int = 12345,
93
+ host: str = "127.0.0.1",
94
+ version: str = DEFAULT_ANSYS_VERSION,
95
+ secret_key: str = "",
96
+ grpc_use_tcp_sockets: bool = False,
97
+ grpc_allow_network_connections: bool = False,
98
+ grpc_disable_tls: bool = False,
99
+ grpc_uds_pathname: Optional[str] = None,
100
+ session: Optional["Session"] = None,
101
+ disable_grpc_options: bool = False,
102
+ ):
103
+ self._port = port
104
+ self._host = host
105
+ self._desired_version = version
106
+ #
107
+ self._pid = None
108
+ self._channel = None
109
+ self._stub = None
110
+ self._grpc_use_tcp_sockets = grpc_use_tcp_sockets
111
+ self._grpc_allow_network_connections = grpc_allow_network_connections
112
+ self._grpc_disable_tls = grpc_disable_tls
113
+ self._grpc_uds_pathname = grpc_uds_pathname
114
+ #
115
+ # self._security_token = str(random.randint(0, 1000000))
116
+ self._security_token: Optional[str] = None
117
+ if not secret_key and not disable_grpc_options:
118
+ self._security_token = str(random.randint(0, 1000000))
119
+ else:
120
+ self._security_token = secret_key
121
+ # self._security_token: Optional[int] = None
122
+ #
123
+ # values found from EnShell in the Container
124
+ self._cei_home = None
125
+ self._ansys_version = None
126
+ self._pyensight_session = session
127
+ self._disable_grpc_options = disable_grpc_options
128
+
129
+ def __del__(self):
130
+ self.shutdown()
131
+
132
+ def host(self):
133
+ """Get the hostname for this connection.
134
+
135
+ Returns
136
+ -------
137
+ str
138
+ the current connection hostname.
139
+ """
140
+ return self._host
141
+
142
+ def port(self):
143
+ """Get the port number for this connection.
144
+
145
+ Returns
146
+ -------
147
+ int
148
+ The current connection port number.
149
+ """
150
+ return self._port
151
+
152
+ @property
153
+ def security_token(self):
154
+ """Return the security token for the gRPC connection.
155
+
156
+ Returns
157
+ -------
158
+ str
159
+ Returns the current connection security token
160
+ """
161
+ return self._security_token
162
+
163
+ @security_token.setter
164
+ def security_token(self, n: str):
165
+ """set the security token for the gRPC connection.
166
+
167
+ EnShell supports a security token in either numeric (-security {int}) or
168
+ string (ENSIGHT_SECURITY_TOKEN environmental variable) form. If EnShell
169
+ is using a security token, all gRPC calls must include this token. This
170
+ call sets the token for all rGPC calls made by this class.
171
+ Note: for this module, the security token must be a in bytes() format.
172
+ For example: str(1000).encode("utf-8")
173
+
174
+ Parameters
175
+ ----------
176
+ n : Optional[int], optional
177
+ An string to be used as the security token, by default None
178
+ """
179
+ self._security_token = n # pragma: no cover
180
+
181
+ @property
182
+ def grpc_use_tcp_sockets(self):
183
+ """Get whether to use Unix Domain Sockets or TCP Sockets for gRPC"""
184
+ return self._grpc_use_tcp_sockets
185
+
186
+ @grpc_use_tcp_sockets.setter
187
+ def grpc_use_tcp_sockets(self, use_sockets: bool):
188
+ """Set whether to use Unix Domain Sockets or TCP Sockets for gRPC"""
189
+ self._grpc_use_tcp_sockets = use_sockets
190
+
191
+ @property
192
+ def grpc_allow_network_connections(self):
193
+ """Get whether to allow listening on all networks if using TCP Sockets for gRPC"""
194
+ return self._grpc_allow_network_connections
195
+
196
+ @grpc_allow_network_connections.setter
197
+ def grpc_allow_network_connections(self, allow: bool):
198
+ """Set whether to allow listening on all networks if using TCP Sockets for gRPC"""
199
+ self._grpc_allow_network_connections = allow
200
+
201
+ @property
202
+ def grpc_disable_tls(self):
203
+ """Get whether to use TLS for TCP Sockets for gRPC"""
204
+ return self._grpc_disable_tls
205
+
206
+ @grpc_disable_tls.setter
207
+ def grpc_disable_tls(self, disable_tls: bool):
208
+ """Set whether to use TLS for TCP Sockets for gRPC"""
209
+ self._grpc_disable_tls = disable_tls
210
+
211
+ @property
212
+ def grpc_uds_pathname(self):
213
+ """Get the pathname for the UDS file if not using the default for gRPC"""
214
+ return self._grpc_uds_pathname
215
+
216
+ @grpc_uds_pathname.setter
217
+ def grpc_uds_pathname(self, uds_pathname: str):
218
+ """Set the pathname for the UDS file if not using the default for gRPC"""
219
+ self._grpc_uds_pathname = uds_pathname
220
+
221
+ def set_random_security_token(self):
222
+ """Set a random security token for the gRPC connection."""
223
+ self._security_token = str(random.randint(0, 1000000)) # pragma: no cover
224
+
225
+ def shutdown(self):
226
+ """shut down all gRPC connections.
227
+
228
+ If this class launched the EnShell client instance, it will
229
+ send the gRPC exit() call and then shut down all connections.
230
+ """
231
+ # if we launched EnShell, shut it down.
232
+ if self._pid is not None: # pragma: no cover
233
+ _ = self.stop_server() # pragma: no cover
234
+
235
+ def start_server(self): # pragma: no cover
236
+ """Start an EnShell gRPC server instance.
237
+
238
+ If the host application wishes to launch an EnShell instance, start_server()
239
+ will launch a batch mode EnShell application with the security token and
240
+ a gRPC server started on the port passed in the constructor.
241
+ """
242
+ if self._pid is not None:
243
+ return self._pid
244
+
245
+ my_env = os.environ.copy()
246
+ if self._desired_version != "":
247
+ exe = f"enshell{self._desired_version}"
248
+ else:
249
+ exe = "enshell"
250
+ cmd = [exe, "-app", "-grpc_server", str(self._port)]
251
+ if self._security_token:
252
+ cmd.append("-security")
253
+ cmd.append(self._security_token)
254
+ if self._grpc_use_tcp_sockets:
255
+ cmd.append("-grpc_use_tcp_sockets")
256
+ if self._grpc_allow_network_connections:
257
+ cmd.append("-grpc_allow_network_connections")
258
+ if self._grpc_disable_tls:
259
+ cmd.append("-grpc_disable_tls")
260
+ if self._grpc_uds_pathname:
261
+ cmd.append("-grpc_uds_pathname")
262
+ cmd.append(self._grpc_uds_pathname)
263
+ if sys.platform in ("win32", "cygwin"):
264
+ cmd[0] += ".bat"
265
+ # cmd.append("-minimize_console")
266
+ # si = subprocess.STARTUPINFO()
267
+ # si.dwFlags = subprocess.STARTF_USESHOWWINDOW | subprocess.CREATE_NEW_CONSOLE
268
+ # si.wShowWindow = subprocess.SW_HIDE
269
+ # f = subprocess.DETACHED_PROCESS
270
+ # DETACHED_PROCESS = 0x00000008
271
+ # self._pid = subprocess.Popen(cmd, creationflags=f, close_fds=True, env=my_env).pid
272
+ # self._pid = subprocess.Popen(cmd, startupinfo=si, close_fds=True, env=my_env).pid
273
+ logging.debug(f"command: {cmd}\n\n")
274
+ self._pid = subprocess.Popen(cmd, close_fds=True, env=my_env).pid
275
+ else:
276
+ self._pid = subprocess.Popen(cmd, close_fds=True, env=my_env).pid
277
+ return self._pid
278
+
279
+ def stop_server(self):
280
+ """Shut down any gPRC connection made by this class.
281
+
282
+ First, if this class launched the EnShell instance, via start_server(), the
283
+ exit_cleanly() gRPC command will be sent. Second, the local gRPC connection is
284
+ dropped
285
+ """
286
+ response = None
287
+ # if we are connected and we started the server, we will emit the 'exit' message
288
+ if self.is_connected(): # pragma: no cover
289
+ response = self._stub.exit_cleanly(
290
+ enshell_pb2.google_dot_protobuf_dot_empty__pb2.Empty(), metadata=self.metadata()
291
+ )
292
+ self._stub = None
293
+ self._dsg_stub = None
294
+ if self._channel: # pragma: no cover
295
+ self._channel.close()
296
+ self._channel = None
297
+ self._pid = None
298
+ return response
299
+
300
+ def is_connected(self):
301
+ """Check if a gRPC connection has been established.
302
+
303
+ Returns
304
+ -------
305
+ bool
306
+ True if a previous connect() call made a valid gRPC connection.
307
+ """
308
+ if not self._channel:
309
+ return False
310
+ return self._channel is not None
311
+
312
+ def connect(self, timeout: Optional[float] = 15.0):
313
+ """Establish a connection to an EnShell gRPC server.
314
+
315
+ Attempt to connect to an EnShell gRPC server using the host and port
316
+ established by the constructor. Note on failure, this function just
317
+ returns, but is_connected() will return False.
318
+
319
+ Parameters
320
+ ----------
321
+ timeout : Optional[float], optional
322
+ timeout how long to wait for the connection to timeout., by default 15.0
323
+ """
324
+ if self._channel is not None:
325
+ return
326
+ transport_mode = None
327
+ host = None
328
+ port = None
329
+ uds_service = None
330
+ uds_dir = None
331
+ options = [
332
+ ("grpc.max_receive_message_length", -1),
333
+ ("grpc.max_send_message_length", -1),
334
+ ("grpc.testing.fixed_reconnect_backoff_ms", 1100),
335
+ ]
336
+ if self._grpc_use_tcp_sockets:
337
+ host = self._host
338
+ transport_mode = "mtls"
339
+ if self._grpc_disable_tls:
340
+ transport_mode = "insecure"
341
+ port = self._port
342
+ else:
343
+ host = "127.0.0.1"
344
+ if sys.platform == "win32":
345
+ transport_mode = "wnua"
346
+ port = self._port
347
+ else:
348
+ transport_mode = "uds"
349
+ uds_service = "pyensight" if self._grpc_uds_pathname else "greeter"
350
+ if not self._grpc_uds_pathname:
351
+ uds_dir = "/tmp"
352
+ else:
353
+ uds_dir = os.path.dirname(self._grpc_uds_pathname)
354
+ # Ignore the security options if the version of EnSight cannot handle them
355
+ if self._disable_grpc_options:
356
+ transport_mode = "insecure"
357
+ host = self._host
358
+ port = self._port
359
+ self._channel = create_channel(
360
+ host=host,
361
+ port=port,
362
+ transport_mode=transport_mode,
363
+ uds_dir=uds_dir,
364
+ uds_service=uds_service,
365
+ grpc_options=options,
366
+ )
367
+ try:
368
+ grpc.channel_ready_future(self._channel).result(timeout=timeout)
369
+ except grpc.FutureTimeoutError: # pragma: no cover
370
+ self._channel = None # pragma: no cover
371
+ return # pragma: no cover
372
+ self._stub = enshell_pb2_grpc.EnShellServiceStub(self._channel)
373
+
374
+ def connect_existing_channel(self, channel: grpc.Channel): # pragma: no cover
375
+ """Establish a connection to an EnShell gRPC server.
376
+
377
+ Attempt to connect to an EnShell gRPC server using the host and port
378
+ established by the constructor. Note on failure, this function just
379
+ returns, but is_connected() will return False.
380
+
381
+ Parameters
382
+ ----------
383
+ channel : grpc.Channel
384
+ Timeout how long to wait for the connection to timeout.
385
+ """
386
+ if self._channel is not None:
387
+ raise RuntimeError("connect_existing_channel: channel already connected.")
388
+
389
+ if channel is None:
390
+ raise RuntimeError("connect_existing_channel: bad channel passed in.")
391
+
392
+ self._channel = channel
393
+ self._stub = enshell_pb2_grpc.EnShellServiceStub(self._channel)
394
+
395
+ def metadata(self): # pragma: no cover
396
+ """Compute internal gRPC stream metadata."""
397
+ ret = list()
398
+ if self._security_token is not None:
399
+ s = self._security_token
400
+ if type(s) == str:
401
+ s = s.encode("utf-8")
402
+ ret.append((b"shared_secret", s))
403
+ return ret
404
+
405
+ def run_command(self, command_string: str):
406
+ """send an EnShell command string to be executed in EnShell.
407
+
408
+ The string will be sent to EnShell via the EnShellService::run_command()
409
+ gRPC call. An IOError exception may be thrown
410
+ if there's a gRPC communication problem. The response
411
+ is the tuple of the EnShell return code and return string.
412
+
413
+ Parameters
414
+ ----------
415
+ command_string : str
416
+ Command_string the EnShell string to be executed.
417
+
418
+ Returns
419
+ -------
420
+ tuple
421
+ A tuple of (int, string) for (returnCode, returnString)
422
+ """
423
+ self.connect()
424
+ if not self._stub: # pragma: no cover
425
+ return (0, "") # pragma: no cover
426
+ try:
427
+ response = self._stub.run_command(
428
+ enshell_pb2.EnShellCommandLine(command_line=command_string),
429
+ metadata=self.metadata(),
430
+ )
431
+ except Exception: # pragma: no cover
432
+ raise IOError("gRPC connection dropped") # pragma: no cover
433
+
434
+ return (response.ret, response.response)
435
+
436
+ def run_command_with_env(self, command_string: str, env_string: str):
437
+ """send an EnShell command string and env var string to be executed in EnShell
438
+
439
+ The string will be sent to EnShell via the EnShellService::run_command()
440
+ gRPC call. An IOError exception may be thrown
441
+ if there's a gRPC communication problem. The response
442
+ is the tuple of the EnShell return code and return string.
443
+ Parameters
444
+ ----------
445
+ command_string : str
446
+ the EnShell string to be executed.
447
+ env_string : str
448
+ String of the environment.
449
+
450
+ Returns
451
+ -------
452
+ Tuple
453
+ A tuple of (int, string) for (returnCode, returnString)
454
+ """
455
+ self.connect()
456
+ if not self._stub: # pragma: no cover
457
+ return (0, "") # pragma: no cover
458
+ try:
459
+ response = self._stub.run_command_with_env(
460
+ enshell_pb2.EnShellCommandWithEnvLine(
461
+ command_line=command_string, env_line=env_string
462
+ ),
463
+ metadata=self.metadata(),
464
+ )
465
+ except Exception: # pragma: no cover
466
+ raise IOError("gRPC connection dropped") # pragma: no cover
467
+
468
+ return (response.ret, response.response)
469
+
470
+ # @brief Tell EnShell to start EnSight
471
+ #
472
+ # The string will be sent to EnShell via the EnShellService::run_command()
473
+ # gRPC call. An IOError exception may be thrown
474
+ # if there's a gRPC communication problem. The response
475
+ # is the tuple of the EnShell return code and return string.
476
+ # If ensight_env is used, the format is a single string of
477
+ # environment variable name=value pairs with multiple pairs
478
+ # separated by '\n' characters.
479
+ # @param ensight_args arguments for the ensight command line
480
+ # @param ensight_env optional environment variables to set before running EnSight
481
+ # @return A tuple of (int, string) for (returnCode, returnString)
482
+ def start_ensight(self, ensight_args: Optional[str] = None, ensight_env: Optional[str] = None):
483
+ """Tell EnShell to start EnSight.
484
+
485
+ The string will be sent to EnShell via the EnShellService::run_command()
486
+ gRPC call. An IOError exception may be thrown
487
+ if there's a gRPC communication problem. The response
488
+ is the tuple of the EnShell return code and return string.
489
+
490
+ Parameters
491
+ ----------
492
+ ensight_args : Optional[str], optional
493
+ ensight_args arguments for the ensight command line, by default None
494
+
495
+ Returns
496
+ -------
497
+ Tuple
498
+ A tuple of (int, string) for (returnCode, returnString)
499
+ """
500
+ self.connect()
501
+
502
+ command_string = "start_app CLIENT -c 127.0.0.1 -enshell"
503
+ if self._security_token:
504
+ command_string += " -security "
505
+ command_string += str(self._security_token)
506
+ if self._grpc_use_tcp_sockets:
507
+ command_string += " -grpc_use_tcp_sockets"
508
+ if self._grpc_allow_network_connections:
509
+ command_string += " -grpc_allow_network_connections"
510
+ if self._grpc_disable_tls:
511
+ command_string += " -grpc_disable_tls"
512
+ # does not make sense to forward this option along
513
+ # if self._grpc_uds_pathname:
514
+ # command_string += " -grpc_uds_pathname "+self._grpc_uds_pathname
515
+ if ensight_args and (ensight_args != ""):
516
+ command_string += " " + ensight_args
517
+
518
+ if ensight_env is None or ensight_env == "": # pragma: no cover
519
+ return self.run_command(command_string)
520
+ else:
521
+ return self.run_command_with_env(command_string, ensight_env) # pragma: no cover
522
+
523
+ def start_ensight_server(
524
+ self, ensight_args: Optional[str] = None, ensight_env: Optional[str] = None
525
+ ):
526
+ """Tell EnShell to start the EnSight server.
527
+
528
+ The string will be sent to EnShell via the EnShellService::run_command()
529
+ gRPC call. An IOError exception may be thrown
530
+ if there's a gRPC communication problem. The response
531
+ is the tuple of the EnShell return code and return string.
532
+
533
+ Parameters
534
+ ----------
535
+ ensight_args : Optional[str], optional
536
+ ensight_args arguments for the ensight command line, by default None
537
+
538
+ Returns
539
+ -------
540
+ Tuple
541
+ A tuple of (int, string) for (returnCode, returnString)
542
+ """
543
+ self.connect()
544
+ command_string = (
545
+ f"start_app OTHER /ansys_inc/v{self.ansys_version()}/CEI/bin/ensight_server"
546
+ )
547
+ if self._security_token:
548
+ command_string += " -security "
549
+ command_string += str(self._security_token)
550
+ if self._grpc_use_tcp_sockets:
551
+ command_string += " -grpc_use_tcp_sockets"
552
+ if self._grpc_allow_network_connections:
553
+ command_string += " -grpc_allow_network_connections"
554
+ if self._grpc_disable_tls:
555
+ command_string += " -grpc_disable_tls"
556
+ # does not make sense to forward this option along
557
+ # if self._grpc_uds_pathname:
558
+ # command_string += " -grpc_uds_pathname "+self._grpc_uds_pathname
559
+ if ensight_args and (ensight_args != ""):
560
+ command_string += " " + ensight_args
561
+
562
+ if ensight_env is None or ensight_env == "": # pragma: no cover
563
+ return self.run_command(command_string)
564
+ else:
565
+ return self.run_command_with_env(command_string, ensight_env) # pragma: no cover
566
+
567
+ # @brief
568
+ #
569
+ # @param cmd The command line
570
+ # @return A tuple of (int, string) for (returnCode, returnString)
571
+ def start_other(self, cmd: str, extra_env: Optional[str] = None):
572
+ """Tell EnShell to start a non-EnShell aware command.
573
+
574
+ The string will be sent to EnShell via the EnShellService::run_command()
575
+ gRPC call. An IOError exception may be thrown
576
+ if there's a gRPC communication problem. The response
577
+ is the tuple of the EnShell return code and return string.
578
+
579
+ Parameters
580
+ ----------
581
+ cmd : str
582
+ _description_
583
+
584
+ Returns
585
+ -------
586
+ _type_
587
+ _description_
588
+ """
589
+ self.connect()
590
+ command_string = "start_app OTHER " + cmd
591
+
592
+ if extra_env is None or extra_env == "": # pragma: no cover
593
+ return self.run_command(command_string)
594
+ else:
595
+ return self.run_command_with_env(command_string, extra_env) # pragma: no cover
596
+
597
+ def cei_home(self):
598
+ """Get the value of CEI_HOME from EnShell."""
599
+ self._get_cei_home()
600
+ return self._cei_home
601
+
602
+ def ansys_version(self):
603
+ """Get the Ansys version from EnShell (e.g. 232)"""
604
+ self._get_cei_home()
605
+ return self._ansys_version
606
+
607
+ def _get_cei_home(self):
608
+ if self._cei_home is not None:
609
+ return
610
+
611
+ self.connect()
612
+ command_string = "show_ceihome"
613
+ ret = self.run_command(command_string)
614
+ # logging.debug(f"{command_string} :: ret = {ret}\n")
615
+ if ret[0] != 0: # pragma: no cover
616
+ self._cei_home = None # pragma: no cover
617
+ raise RuntimeError("Error getting printenv from EnShell") # pragma: no cover
618
+
619
+ # split the newline delimited string into a list of strings
620
+ env_vars = ret[1].strip().split("\n")
621
+ # find the string containing CEI_HOME
622
+ cei_home_line = [x for x in env_vars if "CEI_HOME" in x][0]
623
+ if cei_home_line is None: # pragma: no cover
624
+ raise RuntimeError(
625
+ "Error getting CEI_HOME env var from the Docker container.\n{ret}\n"
626
+ ) # pragma: no cover
627
+
628
+ # CEI_HOME is everything after the equal sign
629
+ equal_sign_loc = cei_home_line.find("=")
630
+ if equal_sign_loc < 0: # pragma: no cover
631
+ raise RuntimeError(
632
+ "Error getting CEI_HOME env var from the Docker container.\n{ret}\n"
633
+ ) # pragma: no cover
634
+ self._cei_home = cei_home_line[equal_sign_loc + 1 :]
635
+ m = re.search(r"/v(\d\d\d)/", self._cei_home)
636
+ if not m: # pragma: no cover
637
+ self.stop_server() # pragma: no cover
638
+ raise RuntimeError(
639
+ "Can't find version from cei_home in the Docker container.\n{ret}\n"
640
+ ) # pragma: no cover
641
+ self._ansys_version = m.group(1)