ansys-pyensight-core 0.6.1__py3-none-any.whl → 0.7.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.

Potentially problematic release.


This version of ansys-pyensight-core might be problematic. Click here for more details.

@@ -1,12 +1,12 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
- <link rel="stylesheet" type="text/css" href="/bootstrap.min.css"/>
4
+ <link rel="stylesheet" type="text/css" href="/bootstrap.min.cssOPTIONAL_QUERY"/>
5
5
 
6
- <script src='/jquery-3.4.1.min.js'></script>
7
- <script src='/geotiff.js'></script>
8
- <script src='/geotiff_nexus.js'></script>
9
- <script src="/bootstrap.min.js"></script>
6
+ <script src='/jquery-3.4.1.min.jsOPTIONAL_QUERY'></script>
7
+ <script src='/geotiff.jsOPTIONAL_QUERY'></script>
8
+ <script src='/geotiff_nexus.jsOPTIONAL_QUERY'></script>
9
+ <script src="/bootstrap.min.jsOPTIONAL_QUERY"></script>
10
10
 
11
11
  <script>
12
12
  function updatepick_ITEMID(e) {
@@ -16,6 +16,7 @@ Examples:
16
16
  """
17
17
  import logging
18
18
  import os.path
19
+ import re
19
20
  import subprocess
20
21
  import time
21
22
  from typing import Any, Dict, Optional
@@ -160,6 +161,11 @@ class DockerLauncher(Launcher):
160
161
  self._service_host_port["grpc"] = ("127.0.0.1", -1)
161
162
  # attach to the file service if available
162
163
  self._get_file_service()
164
+ # if using PIM, we have a query parameter to append to http requests
165
+ if self._pim_instance is not None:
166
+ d = {"instance_name": self._pim_instance.name}
167
+ self._add_query_parameters(d)
168
+ #
163
169
  return
164
170
 
165
171
  # EnShell gRPC port, EnSight gRPC port, HTTP port, WSS port
@@ -187,7 +193,7 @@ class DockerLauncher(Launcher):
187
193
 
188
194
  self._docker_client = docker.from_env()
189
195
  except ModuleNotFoundError:
190
- raise RuntimeError("The pyansys-docker module must be installed for DockerLauncher")
196
+ raise RuntimeError("The docker module must be installed for DockerLauncher")
191
197
  except Exception:
192
198
  raise RuntimeError("Cannot initialize Docker")
193
199
 
@@ -217,6 +223,31 @@ class DockerLauncher(Launcher):
217
223
  except Exception:
218
224
  raise RuntimeError(f"Can't pull Docker image: {self._image_name}")
219
225
 
226
+ def _get_container_env(self) -> Dict:
227
+ # Create the environmental variables
228
+ # Environment to pass into the container
229
+ container_env = {
230
+ "ENSIGHT_SECURITY_TOKEN": self._secret_key,
231
+ "WEBSOCKETSERVER_SECURITY_TOKEN": self._secret_key,
232
+ "ENSIGHT_SESSION_TEMPDIR": self._session_directory,
233
+ }
234
+
235
+ # If for some reason, the ENSIGHT_ANSYS_LAUNCH is set previously,
236
+ # honor that value, otherwise set it to "pyensight". This allows
237
+ # for an environmental setup to set the value to something else
238
+ # (e.g. their "app").
239
+ if "ENSIGHT_ANSYS_LAUNCH" not in os.environ:
240
+ container_env["ENSIGHT_ANSYS_LAUNCH"] = "container"
241
+ else:
242
+ container_env["ENSIGHT_ANSYS_LAUNCH"] = os.environ["ENSIGHT_ANSYS_LAUNCH"]
243
+
244
+ if self._pim_instance is None:
245
+ container_env["ANSYSLMD_LICENSE_FILE"] = os.environ["ANSYSLMD_LICENSE_FILE"]
246
+ if "ENSIGHT_ANSYS_APIP_CONFIG" in os.environ:
247
+ container_env["ENSIGHT_ANSYS_APIP_CONFIG"] = os.environ["ENSIGHT_ANSYS_APIP_CONFIG"]
248
+
249
+ return container_env
250
+
220
251
  def start(self) -> "Session":
221
252
  """Start EnShell by running a local Docker EnSight image.
222
253
 
@@ -245,27 +276,8 @@ class DockerLauncher(Launcher):
245
276
  # initially running EnShell over the first gRPC port. Then launch EnSight
246
277
  # and other apps.
247
278
 
248
- # Create the environmental variables
249
- local_env = os.environ.copy()
250
- local_env["ENSIGHT_SECURITY_TOKEN"] = self._secret_key
251
- local_env["WEBSOCKETSERVER_SECURITY_TOKEN"] = self._secret_key
252
- # If for some reason, the ENSIGHT_ANSYS_LAUNCH is set previously,
253
- # honor that value, otherwise set it to "pyensight". This allows
254
- # for an environmental setup to set the value to something else
255
- # (e.g. their "app").
256
- if "ENSIGHT_ANSYS_LAUNCH" not in local_env:
257
- local_env["ENSIGHT_ANSYS_LAUNCH"] = "container"
258
-
259
- # Environment to pass into the container
260
- container_env = {
261
- "ENSIGHT_SECURITY_TOKEN": self._secret_key,
262
- "WEBSOCKETSERVER_SECURITY_TOKEN": self._secret_key,
263
- "ENSIGHT_SESSION_TEMPDIR": self._session_directory,
264
- "ANSYSLMD_LICENSE_FILE": os.environ["ANSYSLMD_LICENSE_FILE"],
265
- "ENSIGHT_ANSYS_LAUNCH": local_env["ENSIGHT_ANSYS_LAUNCH"],
266
- }
267
- if "ENSIGHT_ANSYS_APIP_CONFIG" in local_env:
268
- container_env["ENSIGHT_ANSYS_APIP_CONFIG"] = local_env["ENSIGHT_ANSYS_APIP_CONFIG"]
279
+ # get the environment to pass to the container
280
+ container_env = self._get_container_env()
269
281
 
270
282
  # Ports to map between the host and the container
271
283
  # If we're here in the code, then we're not using PIM
@@ -296,7 +308,7 @@ class DockerLauncher(Launcher):
296
308
  try:
297
309
  import docker
298
310
  except ModuleNotFoundError: # pragma: no cover
299
- raise RuntimeError("The pyansys-docker module must be installed for DockerLauncher")
311
+ raise RuntimeError("The docker module must be installed for DockerLauncher")
300
312
  except Exception: # pragma: no cover
301
313
  raise RuntimeError("Cannot initialize Docker")
302
314
 
@@ -452,10 +464,27 @@ class DockerLauncher(Launcher):
452
464
 
453
465
  use_egl = self._use_egl()
454
466
 
467
+ # get the environment to pass to the container
468
+ container_env_str = ""
469
+ if self._pim_instance is not None:
470
+ container_env = self._get_container_env()
471
+ for i in container_env.items():
472
+ container_env_str += f"{i[0]}={i[1]}\n"
473
+
455
474
  # Run EnSight
456
475
  ensight_env_vars = None
476
+ if container_env_str != "":
477
+ ensight_env_vars = container_env_str
478
+
457
479
  if use_egl:
458
- ensight_env_vars = "LD_PRELOAD=/usr/local/lib64/libGL.so.1:/usr/local/lib64/libEGL.so.1"
480
+ if ensight_env_vars is None:
481
+ ensight_env_vars = (
482
+ "LD_PRELOAD=/usr/local/lib64/libGL.so.1:/usr/local/lib64/libEGL.so.1"
483
+ )
484
+ else:
485
+ ensight_env_vars += (
486
+ "LD_PRELOAD=/usr/local/lib64/libGL.so.1:/usr/local/lib64/libEGL.so.1"
487
+ )
459
488
 
460
489
  ensight_args = "-batch -v 3"
461
490
 
@@ -481,23 +510,35 @@ class DockerLauncher(Launcher):
481
510
  # Run websocketserver
482
511
  wss_cmd = "cpython /ansys_inc/v" + self._ansys_version + "/CEI/nexus"
483
512
  wss_cmd += self._ansys_version + "/nexus_launcher/websocketserver.py"
513
+ # websocket port - this needs to come first since we now have
514
+ # --add_header as a optional arg that can take an arbitrary
515
+ # number of optional headers.
516
+ wss_cmd += " " + str(self._service_host_port["ws"][1])
517
+ #
484
518
  wss_cmd += " --http_directory " + self._session_directory
485
519
  # http port
486
520
  wss_cmd += " --http_port " + str(self._service_host_port["http"][1])
487
521
  # vnc port
488
522
  wss_cmd += " --client_port 1999"
489
-
523
+ # optional PIM instance header
524
+ if self._pim_instance is not None:
525
+ # Add the PIM instance header. wss needs to return this optional
526
+ # header in each http response. It's how the Ansys Lab proxy
527
+ # knows how to map back to this particular container's IP and port.
528
+ wss_cmd += " --add_header instance_name=" + self._pim_instance.name
529
+ # EnSight REST API
490
530
  if self._enable_rest_api:
491
531
  # grpc port
492
532
  wss_cmd += " --grpc_port " + str(self._service_host_port["grpc_private"][1])
493
-
494
533
  # EnVision sessions
495
534
  wss_cmd += " --local_session envision 5"
496
- # websocket port
497
- wss_cmd += " " + str(self._service_host_port["ws"][1])
535
+
536
+ wss_env_vars = None
537
+ if container_env_str != "":
538
+ wss_env_vars = container_env_str
498
539
 
499
540
  logging.debug(f"Starting WSS: {wss_cmd}\n")
500
- ret = self._enshell.start_other(wss_cmd)
541
+ ret = self._enshell.start_other(wss_cmd, extra_env=wss_env_vars)
501
542
  if ret[0] != 0:
502
543
  self.stop()
503
544
  raise RuntimeError(f"Error starting WSS: {wss_cmd}\n")
@@ -511,11 +552,16 @@ class DockerLauncher(Launcher):
511
552
  use_sos = False
512
553
  if self._use_sos:
513
554
  use_sos = True
555
+ if self._pim_instance is None:
556
+ ws_port = self._service_host_port["ws"][1]
557
+ else:
558
+ ws_port = self._service_host_port["http"][1]
514
559
  session = ansys.pyensight.core.session.Session(
515
560
  host=self._service_host_port["grpc_private"][0],
516
561
  grpc_port=self._service_host_port["grpc_private"][1],
562
+ html_hostname=self._service_host_port["http"][0],
517
563
  html_port=self._service_host_port["http"][1],
518
- ws_port=self._service_host_port["ws"][1],
564
+ ws_port=ws_port,
519
565
  install_path=None,
520
566
  secret_key=self._secret_key,
521
567
  timeout=self._timeout,
@@ -578,7 +624,12 @@ class DockerLauncher(Launcher):
578
624
 
579
625
  def _get_host_port(self, uri: str) -> tuple:
580
626
  parse_results = urllib3.util.parse_url(uri)
581
- return (parse_results.host, parse_results.port)
627
+ port = (
628
+ parse_results.port
629
+ if parse_results.port
630
+ else (443 if re.search("^https|wss$", parse_results.scheme) else None)
631
+ )
632
+ return (parse_results.host, port)
582
633
 
583
634
  def _is_system_egl_capable(self) -> bool:
584
635
  """Check if the system is EGL capable.
@@ -357,10 +357,9 @@ class EnShellGRPC(object):
357
357
 
358
358
  # @brief
359
359
  #
360
-
361
360
  # @param cmd The command line
362
361
  # @return A tuple of (int, string) for (returnCode, returnString)
363
- def start_other(self, cmd: str):
362
+ def start_other(self, cmd: str, extra_env: Optional[str] = None):
364
363
  """Tell EnShell to start a non-EnShell aware command.
365
364
 
366
365
  The string will be sent to EnShell via the EnShellService::run_command()
@@ -381,7 +380,10 @@ class EnShellGRPC(object):
381
380
  self.connect()
382
381
  command_string = "start_app OTHER " + cmd
383
382
 
384
- return self.run_command(command_string)
383
+ if extra_env is None or extra_env == "":
384
+ return self.run_command(command_string)
385
+ else:
386
+ return self.run_command_with_env(command_string, extra_env)
385
387
 
386
388
  def cei_home(self):
387
389
  """Get the value of CEI_HOME from EnShell."""
@@ -78,10 +78,7 @@ if pim_is_available:
78
78
  ]
79
79
  )
80
80
 
81
- launcher = DockerLauncher(
82
- channel=channel,
83
- pim_instance=instance,
84
- )
81
+ launcher = DockerLauncher(channel=channel, pim_instance=instance, **kwargs)
85
82
  return launcher.connect()
86
83
 
87
84
 
@@ -14,7 +14,7 @@ Examples:
14
14
  import os.path
15
15
  import platform
16
16
  import socket
17
- from typing import TYPE_CHECKING, List, Optional
17
+ from typing import TYPE_CHECKING, Dict, List, Optional
18
18
  import warnings
19
19
 
20
20
  import requests
@@ -82,6 +82,8 @@ class Launcher:
82
82
  self._egl_env_val = True
83
83
  else:
84
84
  self._egl_env_val = False
85
+ # a dict of any optional launcher specific query parameters for URLs
86
+ self._query_parameters: Dict[str, str] = {}
85
87
 
86
88
  @property
87
89
  def session_directory(self) -> str:
@@ -266,3 +268,44 @@ class Launcher:
266
268
 
267
269
  """
268
270
  return platform.system() == "Windows"
271
+
272
+ def _get_query_parameters(self) -> Dict[str, str]:
273
+ """Return optional http query parameters as a dict.
274
+ It may be empty if there are None.
275
+ If query parameters exist, they should be added to any
276
+ http/https URL intended for the WSS web server.
277
+ This is used by things such as Ansys Lab.
278
+
279
+ Returns
280
+ -------
281
+ dict
282
+ query parameters that should be appended to any queries
283
+ """
284
+ return self._query_parameters
285
+
286
+ def _add_query_parameters(self, params: Dict[str, str]) -> None:
287
+ """Add query parameters supplied by params to the
288
+ overall dict of query parameters.
289
+
290
+ Parameters
291
+ ----------
292
+ params: dict :
293
+ query parameters to add to overall dict
294
+ """
295
+ for item, value in params.items():
296
+ self._query_parameters[item] = value
297
+
298
+ def _delete_query_parameters(self, params: List[str]) -> None:
299
+ """Delete query parameters supplied by params from the
300
+ overall dict of query parameters.
301
+
302
+ Parameters
303
+ ----------
304
+ params: list :
305
+ query parameters to delete from the overall dict
306
+ """
307
+ for item in params:
308
+ try:
309
+ del self._query_parameters[item]
310
+ except Exception:
311
+ pass
@@ -5,7 +5,7 @@ that can be displayed via HTML over the websocket server interface.
5
5
  """
6
6
  import os
7
7
  import shutil
8
- from typing import TYPE_CHECKING, Any, List, Optional, Tuple, no_type_check
8
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, no_type_check
9
9
  import uuid
10
10
  import webbrowser
11
11
 
@@ -80,6 +80,17 @@ class Renderable:
80
80
  self._aa: int = aa
81
81
  self._fps: float = fps
82
82
  self._num_frames: Optional[int] = num_frames
83
+ #
84
+ self._using_proxy = False
85
+ # if we're talking directly to WS, then use 'http' otherwise 'https' for the proxy
86
+ self._http_protocol = "http"
87
+ try:
88
+ if self._session.launcher._pim_instance is not None:
89
+ self._using_proxy = True
90
+ self._http_protocol = "https"
91
+ except Exception:
92
+ # the launcher may not be PIM aware; that's ok
93
+ pass
83
94
 
84
95
  def __repr__(self) -> str:
85
96
  name = self.__class__.__name__
@@ -100,6 +111,27 @@ class Renderable:
100
111
  name = self.__class__.__name__
101
112
  p.text(f"{name}( url='{self._url}' )")
102
113
 
114
+ def _get_query_parameters_str(self, params: Optional[Dict[str, str]] = None) -> str:
115
+ """Generate any optional http query parameters.
116
+ Return a string formatted as a URL query to tack on to the
117
+ beginning part of the URL. The string may be empty if there
118
+ aren't any parameters. The method takes a dict
119
+ of parameters, possibly empty or None, and combines it with the
120
+ parameters from the launcher, which also may be empty.
121
+ """
122
+ qp_dict = self._session.launcher._get_query_parameters()
123
+ if qp_dict is None:
124
+ # just in case
125
+ qp_dict = {}
126
+ if params:
127
+ qp_dict.update(params)
128
+ query_parameter_str = ""
129
+ symbol = "?"
130
+ for p in qp_dict.items():
131
+ query_parameter_str += f"{symbol}{p[0]}={p[1]}"
132
+ symbol = "&"
133
+ return query_parameter_str
134
+
103
135
  def _generate_filename(self, suffix: str) -> Tuple[str, str]:
104
136
  """Create session-specific files and URLs.
105
137
 
@@ -134,6 +166,8 @@ class Renderable:
134
166
  The URL to the file (through the session HTTP server) is
135
167
  ``http://{system}:{websocketserverhtmlport}/{session}_{guid}_{index}_{type}.html``.
136
168
 
169
+ Note that there may be optional http query parameters at the end of the URL.
170
+
137
171
  After this call, ``_url`` and ``_url_remote_pathname`` reflect these names.
138
172
 
139
173
  """
@@ -141,8 +175,8 @@ class Renderable:
141
175
  filename_index = self._filename_index
142
176
  remote_pathname, _ = self._generate_filename(suffix)
143
177
  simple_filename = f"{self._session.secret_key}_{self._guid}_{filename_index}{suffix}"
144
- url = f"http://{self._session.hostname}:{self._session.html_port}/{simple_filename}"
145
- self._url = url
178
+ url = f"{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}"
179
+ self._url = f"{url}/{simple_filename}{self._get_query_parameters_str()}"
146
180
  self._url_remote_pathname = remote_pathname
147
181
 
148
182
  def _save_remote_html_page(self, html: str) -> None:
@@ -265,7 +299,7 @@ class Renderable:
265
299
 
266
300
  """
267
301
  for filename in self._download_names:
268
- url = f"http://{self._session.hostname}:{self._session.html_port}/{filename}"
302
+ url = f"{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}/{filename}{self._get_query_parameters_str()}"
269
303
  outpath = os.path.join(dirname, filename)
270
304
  with requests.get(url, stream=True) as r:
271
305
  with open(outpath, "wb") as f:
@@ -302,7 +336,7 @@ class RenderableImage(Renderable):
302
336
  self._session.cmd(cmd)
303
337
  # generate HTML page with file references local to the websocket server root
304
338
  html = '<body style="margin:0px;padding:0px;">\n'
305
- html += f'<img src="/{self._png_filename}">\n'
339
+ html += f'<img src="/{self._png_filename}{self._get_query_parameters_str()}">\n'
306
340
  html += "</body>\n"
307
341
  # refresh the remote HTML
308
342
  self._save_remote_html_page(html)
@@ -330,6 +364,9 @@ class RenderableDeepPixel(Renderable):
330
364
  an iframe reference.
331
365
  """
332
366
  # save the (deep) image file
367
+ # get the optional query parameters which may be an empty string
368
+ # needed for proxy servers like ansys lab
369
+ optional_query = self._get_query_parameters_str()
333
370
  w, h = self._default_size(1920, 1080)
334
371
  deep = f",num_samples={self._aa},enhanced=1"
335
372
  cmd = f'ensight.render({w},{h}{deep}).save(r"""{self._tif_pathname}""")'
@@ -347,10 +384,12 @@ class RenderableDeepPixel(Renderable):
347
384
  name += "'website', 'static', 'website', 'content', 'bootstrap.min.css')"
348
385
  cmd += f'shutil.copy({name}, r"""{self._session.launcher.session_directory}""")\n'
349
386
  self._session.cmd(cmd, do_eval=False)
387
+ url = f"{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}"
388
+ tiff_url = f"{url}/{self._tif_filename}{optional_query}"
350
389
  # replace some bits in the HTML
351
- tiff_url = f"http://{self._session.hostname}:{self._session.html_port}/{self._tif_filename}"
352
390
  html = html.replace("TIFF_URL", tiff_url)
353
391
  html = html.replace("ITEMID", self._guid)
392
+ html = html.replace("OPTIONAL_QUERY", optional_query)
354
393
  # refresh the remote HTML
355
394
  self._save_remote_html_page(html)
356
395
  super().update()
@@ -425,7 +464,7 @@ class RenderableMP4(Renderable):
425
464
  # generate HTML page with file references local to the websocket server root
426
465
  html = '<body style="margin:0px;padding:0px;">\n'
427
466
  html += f'<video width="{w}" height="{h}" controls>\n'
428
- html += f' <source src="/{self._mp4_filename}" type="video/mp4" />\n'
467
+ html += f' <source src="/{self._mp4_filename}{self._get_query_parameters_str()}" type="video/mp4" />\n'
429
468
  html += "</video>\n"
430
469
  html += "</body>\n"
431
470
 
@@ -471,8 +510,15 @@ class RenderableWebGL(Renderable):
471
510
  # Save the file
472
511
  self._session.ensight.savegeom.save_geometric_entities(self._avz_pathname)
473
512
  # generate HTML page with file references local to the websocket server root
474
- html = "<script src='/ansys/nexus/viewer-loader.js'></script>\n"
475
- html += f"<ansys-nexus-viewer src='/{self._avz_filename}'></ansys-nexus-viewer>\n"
513
+ if self._using_proxy:
514
+ # if using pim we get the static content from the front end and not
515
+ # where ensight is running, thus we use a specific URI host and not relative.
516
+ html = f"<script src='{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}/ansys/nexus/viewer-loader.js'></script>\n"
517
+ html += f"<ansys-nexus-viewer src='{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}/{self._avz_filename}"
518
+ html += f"{self._get_query_parameters_str()}'></ansys-nexus-viewer>\n"
519
+ else:
520
+ html = "<script src='/ansys/nexus/viewer-loader.js'></script>\n"
521
+ html += f"<ansys-nexus-viewer src='/{self._avz_filename}{self._get_query_parameters_str()}'></ansys-nexus-viewer>\n"
476
522
  # refresh the remote HTML
477
523
  self._save_remote_html_page(html)
478
524
  super().update()
@@ -483,6 +529,11 @@ class RenderableVNC(Renderable):
483
529
 
484
530
  def __init__(self, *args, **kwargs) -> None:
485
531
  super().__init__(*args, **kwargs)
532
+ self._query_params = {
533
+ "autoconnect": "true",
534
+ "host": self._session.html_hostname,
535
+ "port": self._session.ws_port,
536
+ }
486
537
  self._rendertype = "remote"
487
538
  self.update()
488
539
 
@@ -493,9 +544,9 @@ class RenderableVNC(Renderable):
493
544
  iframe reference.
494
545
 
495
546
  """
496
- url = f"http://{self._session.hostname}:{self._session.html_port}"
547
+ url = f"{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}"
497
548
  url += "/ansys/nexus/novnc/vnc_envision.html"
498
- url += f"?autoconnect=true&host={self._session.hostname}&port={self._session.ws_port}"
549
+ url += self._get_query_parameters_str(self._query_params)
499
550
  self._url = url
500
551
  super().update()
501
552
 
@@ -504,13 +555,19 @@ class RenderableVNC(Renderable):
504
555
  class RenderableVNCAngular(Renderable):
505
556
  def __init__(self, *args, **kwargs) -> None:
506
557
  super().__init__(*args, **kwargs)
558
+ self._query_params = {
559
+ "autoconnect": "true",
560
+ "host": self._session.hostname,
561
+ "port": self._session.ws_port,
562
+ "secretKey": self._session.secret_key,
563
+ }
507
564
  self._rendertype = "remote"
508
565
  self.update()
509
566
 
510
567
  def update(self):
511
- url = f"http://{self._session.hostname}:{self._session.html_port}"
568
+ url = f"{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}"
512
569
  url += "/ansys/nexus/angular/viewer_angular_pyensight.html"
513
- url += f"?autoconnect=true&host={self._session.hostname}&port={self._session.ws_port}&secretKey={self._session.secret_key}"
570
+ url += self._get_query_parameters_str(self._query_params)
514
571
  self._url = url
515
572
  super().update()
516
573
 
@@ -559,17 +616,33 @@ class RenderableEVSN(Renderable):
559
616
  self._session.ensight.file.save_scenario_fileslct(self._evsn_pathname)
560
617
 
561
618
  # generate HTML page with file references local to the websocketserver root
562
- html = "<script src='/ansys/nexus/viewer-loader.js'></script>\n"
563
- server = f"http://{self._session.hostname}:{self._session.html_port}"
564
- cleanname = self._evsn_pathname.replace("\\", "/")
619
+ optional_query = self._get_query_parameters_str()
620
+
621
+ html = f"<script src='/ansys/nexus/viewer-loader.js{optional_query}'></script>\n"
622
+ server = f"{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}"
623
+
624
+ # FIXME: This method doesn't work with Ansys Lab since the viewer seems to require
625
+ # a full pathname to the file being generated by EnSight on a shared file system.
626
+ # The following commented out line should replace the two after that, but that
627
+ # prevents running locally from working since it's not using the full pathname to
628
+ # the shared file. -MFK
629
+ cleanname = self._evsn_filename.replace("\\", "/")
565
630
  attributes = f"src='{cleanname}'"
566
- attributes += f" proxy_img='/{self._proxy_filename}'"
631
+ # attributes = f"src='{cleanname}{optional_query}'"
632
+
633
+ attributes += f" proxy_img='/{self._proxy_filename}{optional_query}'"
567
634
  attributes += " aspect_ratio='proxy'"
568
635
  attributes += " renderer='envnc'"
569
636
  http_uri = f'"http":"{server}"'
570
- ws_uri = f'"ws":"http://{self._session.hostname}:{self._session.ws_port}"'
637
+ ws_uri = (
638
+ f'"ws":"{self._http_protocol}://{self._session.html_hostname}:{self._session.ws_port}"'
639
+ )
571
640
  secrets = f'"security_token":"{self._session.secret_key}"'
572
- attributes += f"renderer_options='{{ {http_uri}, {ws_uri}, {secrets} }}'"
641
+ if not self._using_proxy or optional_query == "":
642
+ attributes += f" renderer_options='{{ {http_uri}, {ws_uri}, {secrets} }}'"
643
+ else:
644
+ query_args = f'"extra_query_args":"{optional_query[1:]}"'
645
+ attributes += f" renderer_options='{{ {http_uri}, {ws_uri}, {secrets}, {query_args} }}'"
573
646
  html += f"<ansys-nexus-viewer {attributes}></ansys-nexus-viewer>\n"
574
647
  # refresh the remote HTML
575
648
  self._save_remote_html_page(html)
@@ -622,12 +695,14 @@ class RenderableSGEO(Renderable): # pragma: no cover
622
695
  # If the first update, generate the HTML
623
696
  if self._revision == 0:
624
697
  # generate HTML page with file references local to the websocketserver root
625
- attributes = f"src='/{self._sgeo_base_filename}/geometry.sgeo'"
626
- attributes += f" proxy_img='/{self._sgeo_base_filename}/proxy.png'"
698
+ attributes = (
699
+ f"src='/{self._sgeo_base_filename}/geometry.sgeo{self._get_query_parameters_str()}'"
700
+ )
701
+ attributes += f" proxy_img='/{self._sgeo_base_filename}/proxy.png{self._get_query_parameters_str()}'"
627
702
  attributes += " aspect_ratio='proxy'"
628
703
  attributes += " renderer='sgeo'"
629
704
 
630
- html = "<script src='/ansys/nexus/viewer-loader.js'></script>\n"
705
+ html = f"<script src='/ansys/nexus/viewer-loader.js{self._get_query_parameters_str()}'></script>\n"
631
706
  html += f"<ansys-nexus-viewer id='{self._guid}' {attributes}></ansys-nexus-viewer>\n"
632
707
  html += self._periodic_script()
633
708
  # refresh the remote HTML
@@ -662,7 +737,7 @@ class RenderableSGEO(Renderable): # pragma: no cover
662
737
  html_source = os.path.join(os.path.dirname(__file__), "sgeo_poll.html")
663
738
  with open(html_source, "r") as fp:
664
739
  html = fp.read()
665
- revision_uri = f"/{self._sgeo_base_filename}/geometry.rev"
740
+ revision_uri = f"/{self._sgeo_base_filename}/geometry.rev{self._get_query_parameters_str()}"
666
741
  html = html.replace("REVURL_ITEMID", revision_uri)
667
742
  html = html.replace("ITEMID", self._guid)
668
743
  return html
@@ -77,6 +77,9 @@ class Session:
77
77
  The default is ``""``.
78
78
  grpc_port : int, optional
79
79
  Port number of the EnSight gRPC service. The default is ``12345``.
80
+ html_host : str, optional
81
+ Optional hostname for html connections if different than host
82
+ Used by Ansys Lab and reverse proxy servers
80
83
  html_port : int, optional
81
84
  Port number of the websocket server's HTTP server. The default is
82
85
  ``None``.
@@ -113,6 +116,7 @@ class Session:
113
116
  install_path: Optional[str] = None,
114
117
  secret_key: str = "",
115
118
  grpc_port: int = 12345,
119
+ html_hostname: Optional[str] = None,
116
120
  html_port: Optional[int] = None,
117
121
  ws_port: Optional[int] = None,
118
122
  session_directory: Optional[str] = None,
@@ -131,6 +135,11 @@ class Session:
131
135
  self._hostname = host
132
136
  self._install_path = install_path
133
137
  self._launcher = None
138
+ if html_hostname == "" or html_hostname is None:
139
+ # if we weren't given an html host, use the hostname
140
+ self._html_hostname = self._hostname
141
+ else:
142
+ self._html_hostname = html_hostname
134
143
  self._html_port = html_port
135
144
  self._ws_port = ws_port
136
145
  self._secret_key = secret_key
@@ -192,7 +201,8 @@ class Session:
192
201
  session_dir = self.launcher.session_directory
193
202
  s = f"Session(host='{self.hostname}', secret_key='{self.secret_key}', "
194
203
  s += f"sos={self.sos}, rest_api={self.rest_api}, "
195
- s += f"html_port={self.html_port}, grpc_port={self._grpc_port}, "
204
+ s += f"html_hostname={self.html_hostname}, html_port={self.html_port}, "
205
+ s += f"grpc_port={self._grpc_port}, "
196
206
  s += f"ws_port={self.ws_port}, session_directory=r'{session_dir}')"
197
207
  return s
198
208
 
@@ -227,7 +237,14 @@ class Session:
227
237
  """
228
238
  if not self.rest_api:
229
239
  return
230
- url = f"http://{self.hostname}:{self.html_port}/ensight/v1/session/exec"
240
+ #
241
+ #
242
+ # even when using PIM and a proxy server (Ansys Lab) this connects
243
+ # directly from the python running in the Notebook (the front-end)
244
+ # to the EnSight Docker Container and not the proxy server.
245
+ # Thus, here we use 'http', the private hostname, and the html port
246
+ # (which is the same on the proxy server).
247
+ url = f"http://{self._hostname}:{self.html_port}/ensight/v1/session/exec"
231
248
  time_start = time.time()
232
249
  while time.time() - time_start < self._timeout:
233
250
  try:
@@ -343,6 +360,11 @@ class Session:
343
360
  """Hostname of the system hosting the EnSight instance."""
344
361
  return self._hostname
345
362
 
363
+ @property
364
+ def html_hostname(self) -> str:
365
+ """Hostname of the system hosting the EnSight web server instance."""
366
+ return self._html_hostname
367
+
346
368
  @property
347
369
  def launcher(self) -> "Launcher":
348
370
  """Reference to the launcher instance if a launcher was used to instantiate the session."""
@@ -1091,6 +1113,55 @@ class Session:
1091
1113
  if self.cmd(cmd) != 0:
1092
1114
  raise RuntimeError("Unable to load the dataset.")
1093
1115
 
1116
+ def download_pyansys_example(
1117
+ self, filename: str, directory: Optional[str] = None, root: Optional[str] = None
1118
+ ) -> str:
1119
+ """Download an example dataset from the ansys/example-data repository.
1120
+ The dataset is downloaded local to the EnSight server location, so that it can
1121
+ be downloaded even if running from a container.
1122
+
1123
+ Parameters
1124
+ ----------
1125
+ filename: str
1126
+ The filename to download
1127
+ directory: str
1128
+ The directory to download the filename from
1129
+ root: str
1130
+ If set, the download will happen from another location
1131
+
1132
+ Returns
1133
+ -------
1134
+ pathname: str
1135
+ The download location, local to the EnSight server directory
1136
+
1137
+ Examples
1138
+ --------
1139
+ >>> from ansys.pyensight.core import DockerLauncher
1140
+ >>> session = DockerLauncher().start(data_directory="D:\\")
1141
+ >>> cas_file = session.download_pyansys_example("mixing_elbow.cas.h5","pyfluent/mixing_elbow")
1142
+ >>> dat_file = session.download_pyansys_example("mixing_elbow.dat.h5","pyfluent/mixing_elbow")
1143
+ >>> session.load_data(cas_file, result_file=dat_file)
1144
+ >>> remote = session.show("remote")
1145
+ >>> remote.browser()
1146
+ """
1147
+ base_uri = "https://github.com/ansys/example-data/raw/master"
1148
+ if root is not None:
1149
+ base_uri = root
1150
+ uri = f"{base_uri}/{filename}"
1151
+ if directory:
1152
+ uri = f"{base_uri}/{directory}/{filename}"
1153
+ pathname = f"{self.launcher.session_directory}/{filename}"
1154
+ script = "import requests\n"
1155
+ script += "import shutil\n"
1156
+ script += "import os\n"
1157
+ script += f'url = "{uri}"\n'
1158
+ script += f'outpath = r"""{pathname}"""\n'
1159
+ script += "with requests.get(url, stream=True) as r:\n"
1160
+ script += " with open(outpath, 'wb') as f:\n"
1161
+ script += " shutil.copyfileobj(r.raw, f)\n"
1162
+ self.cmd(script, do_eval=False)
1163
+ return pathname
1164
+
1094
1165
  def load_example(
1095
1166
  self, example_name: str, uncompress: bool = False, root: Optional[str] = None
1096
1167
  ) -> str:
@@ -1129,16 +1200,8 @@ class Session:
1129
1200
  base_uri = "https://s3.amazonaws.com/www3.ensight.com/PyEnSight/ExampleData"
1130
1201
  if root is not None:
1131
1202
  base_uri = root
1132
- uri = f"{base_uri}/{example_name}"
1133
- pathname = f"{self.launcher.session_directory}/{example_name}"
1134
- script = "import requests\n"
1135
- script += "import shutil\n"
1136
- script += "import os\n"
1137
- script += f'url = "{uri}"\n'
1138
- script += f'outpath = r"""{pathname}"""\n'
1139
- script += "with requests.get(url, stream=True) as r:\n"
1140
- script += " with open(outpath, 'wb') as f:\n"
1141
- script += " shutil.copyfileobj(r.raw, f)\n"
1203
+ pathname = self.download_pyansys_example(example_name, root=base_uri)
1204
+ script = f'outpath = r"""{pathname}"""\n'
1142
1205
  if uncompress:
1143
1206
  # in this case, remove the extension and unzip the file
1144
1207
  pathname_dir = os.path.splitext(pathname)[0]
@@ -73,8 +73,6 @@ class Export:
73
73
  ) -> None:
74
74
  """Render an image of the current EnSight scene.
75
75
 
76
- This method returns a PIL image object.
77
-
78
76
  Parameters
79
77
  ----------
80
78
  filename : str
@@ -464,3 +462,108 @@ class Export:
464
462
  mp4_data = fp.read()
465
463
 
466
464
  return mp4_data
465
+
466
+ GEOM_EXPORT_GLTF = "gltf2"
467
+ GEOM_EXPORT_AVZ = "avz"
468
+ GEOM_EXPORT_PLY = "ply"
469
+ GEOM_EXPORT_STL = "stl"
470
+
471
+ extension_map = {
472
+ GEOM_EXPORT_GLTF: ".glb",
473
+ GEOM_EXPORT_AVZ: ".avz",
474
+ GEOM_EXPORT_PLY: ".ply",
475
+ GEOM_EXPORT_STL: ".stl",
476
+ }
477
+
478
+ def _geometry_remote(
479
+ self, format: str, starting_timestep: int, frames: int, delta_timestep: int
480
+ ) -> bytes:
481
+ """EnSight-side implementation.
482
+
483
+ Parameters
484
+ ----------
485
+ format : str
486
+ The format to export
487
+ starting_timestep: int
488
+ The first timestep to export. If None, defaults to the current timestep
489
+ frames: int
490
+ Number of timesteps to save. If None, defaults from the current timestep to the last
491
+ delta_timestep: int
492
+ The delta timestep to use when exporting
493
+
494
+ Returns
495
+ -------
496
+ bytes
497
+ Geometry export in bytes
498
+ """
499
+ rawdata = None
500
+ extension = self.extension_map.get(format)
501
+ if not extension:
502
+ raise RuntimeError("The geometry export format provided is not supported.")
503
+ with tempfile.TemporaryDirectory() as tmpdirname:
504
+ self._ensight.part.select_all()
505
+ self._ensight.savegeom.format(format)
506
+ self._ensight.savegeom.begin_step(starting_timestep)
507
+ # frames is 1-indexed, so I need to decrease of 1
508
+ self._ensight.savegeom.end_step(starting_timestep + frames - 1)
509
+ self._ensight.savegeom.step_by(delta_timestep)
510
+ tmpfilename = os.path.join(tmpdirname, str(uuid.uuid1()))
511
+ self._ensight.savegeom.save_geometric_entities(tmpfilename)
512
+ with open(tmpfilename + extension, "rb") as tmpfile:
513
+ rawdata = tmpfile.read()
514
+ return rawdata
515
+
516
+ def geometry(
517
+ self,
518
+ filename: str,
519
+ format: str = GEOM_EXPORT_GLTF,
520
+ starting_timestep: Optional[int] = None,
521
+ frames: Optional[int] = 1,
522
+ delta_timestep: Optional[int] = None,
523
+ ) -> None:
524
+ """Export a geometry file.
525
+
526
+ Parameters
527
+ ----------
528
+ filename: str
529
+ The location where to export the geometry
530
+ format : str
531
+ The format to export
532
+ starting_timestep: int
533
+ The first timestep to export. If None, defaults to the current timestep
534
+ frames: int
535
+ Number of timesteps to save. If None, defaults from the current timestep to the last
536
+ delta_timestep: int
537
+ The delta timestep to use when exporting
538
+
539
+ Examples
540
+ --------
541
+ >>> s = LocalLauncher().start()
542
+ >>> data = f"{s.cei_home}/ensight{s.cei_suffix}gui/demos/Crash Queries.ens"
543
+ >>> s.ensight.objs.ensxml_restore_file(data)
544
+ >>> s.ensight.utils.export.geometry("local_file.glb", format=s.ensight.utils.export.GEOM_EXPORT_GLTF)
545
+ """
546
+ if not starting_timestep:
547
+ starting_timestep = int(self._ensight.objs.core.TIMESTEP)
548
+ if not frames or frames == -1:
549
+ # Timesteps are 0-indexed so frames need to be increased of 1
550
+ frames = int(self._ensight.objs.core.TIMESTEP_LIMITS[1]) + 1
551
+ if not delta_timestep:
552
+ delta_timestep = 1
553
+ self._remote_support_check()
554
+ raw_data = None
555
+ if isinstance(self._ensight, ModuleType):
556
+ raw_data = self._geometry_remote(
557
+ format,
558
+ starting_timestep=starting_timestep,
559
+ frames=frames,
560
+ delta_timestep=delta_timestep,
561
+ )
562
+ else:
563
+ cmd = f"ensight.utils.export._geometry_remote('{format}', {starting_timestep}, {frames}, {delta_timestep})"
564
+ raw_data = self._ensight._session.cmd(cmd)
565
+ if raw_data:
566
+ with open(filename, "wb") as fp:
567
+ fp.write(raw_data)
568
+ else:
569
+ raise IOError("Export was not successful")
@@ -31,24 +31,46 @@ class Support:
31
31
  def __init__(self, interface: Union["ensight_api.ensight", "ensight"]):
32
32
  self._ensight = interface
33
33
 
34
- @staticmethod
35
- def scoped_name(obj: Any) -> ContextManager:
34
+ def scoped_name(self, obj: Any, native_exceptions: bool = False) -> ContextManager:
36
35
  """Allow for the use of ``with`` to shorten APIs.
37
36
 
38
37
  In the EnSight and PyEnsight APIs, the interfaces can become lengthy.
39
38
  This class makes it possible to shorten APIs for modules, classes,
40
- and namespaces.
39
+ and namespaces. The native_exceptions keyword can be used to enable
40
+ exceptions for EnSight native Python API. By default, an invalid
41
+ native API call like ``ensight.part.select_begin(-9999)`` will return
42
+ -1. If native_exceptions is True, a Python exception will be thrown.
43
+ The scope of this operational change parallels the scoped_name()
44
+ instance.
45
+
46
+ Parameters
47
+ ----------
48
+ obj: Any
49
+ The object for which to generate a simplified namespace.
50
+ native_exceptions: bool
51
+ If True, then EnSight native Python API exceptions are enabled.
52
+ The default is False.
53
+
54
+ Returns
55
+ -------
56
+ The passed object wrapped in a context manager that can be used as a
57
+ simplified namespace.
41
58
 
42
59
  Examples
43
60
  --------
44
61
  >>> sn = s.ensight.utils.support.scoped_name
45
62
  >>> with sn(s.ensight.objs.core) as core, sn(s.ensight.objs.enums) as enums:
46
63
  >>> print(core.PARTS.find(True, enums.VISIBLE))
64
+
47
65
  >>> sn = ensight.utils.support.scoped_name
48
66
  >>> with sn(ensight.objs.core) as core, sn(ensight.objs.enums) as enums:
49
67
  >>> print(core.PARTS.find(True, enums.VISIBLE))
68
+
69
+ >>> sn = ensight.utils.support.scoped_name
70
+ >>> with sn(ensight.part, native_exceptions=True) as part:
71
+ >>> part.select_begin(-9999)
50
72
  """
51
- return ScopedName(obj)
73
+ return ScopedName(self._ensight, obj, native_exceptions=native_exceptions)
52
74
 
53
75
 
54
76
  class ScopedName:
@@ -59,11 +81,26 @@ class ScopedName:
59
81
  and namespaces.
60
82
  """
61
83
 
62
- def __init__(self, obj: Any):
84
+ def __init__(
85
+ self,
86
+ interface: Union["ensight_api.ensight", "ensight"],
87
+ obj: Any,
88
+ native_exceptions: bool = False,
89
+ ):
63
90
  self._obj = obj
91
+ self._ensight = interface
92
+ self._old_raise = None
93
+ if native_exceptions:
94
+ # if we are being asked to enable exceptions, record what to restore it to
95
+ self._old_raise = self._ensight.query("SENDMESG_RAISE")
64
96
 
65
97
  def __enter__(self) -> Any:
98
+ if self._old_raise is not None:
99
+ # if a restore value is set, enable them
100
+ self._ensight.sendmesgoptions(exception=1)
66
101
  return self._obj
67
102
 
68
103
  def __exit__(self, exc_type, exc_value, exc_trace):
69
- pass
104
+ if self._old_raise is not None:
105
+ # if the restore value is set, restore it here
106
+ self._ensight.sendmesgoptions(exception=self._old_raise)
@@ -1,24 +1,24 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ansys-pyensight-core
3
- Version: 0.6.1
3
+ Version: 0.7.0
4
4
  Summary: A python wrapper for Ansys EnSight
5
5
  Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
6
6
  Maintainer-email: "ANSYS, Inc." <pyansys.core@ansys.com>
7
- Requires-Python: >=3.8,<4
7
+ Requires-Python: >=3.9,<4
8
8
  Description-Content-Type: text/x-rst
9
9
  Classifier: Development Status :: 4 - Beta
10
10
  Classifier: Intended Audience :: Science/Research
11
11
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
12
12
  Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Operating System :: OS Independent
14
- Classifier: Programming Language :: Python :: 3.8
15
14
  Classifier: Programming Language :: Python :: 3.9
16
15
  Classifier: Programming Language :: Python :: 3.10
17
16
  Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
18
  Requires-Dist: importlib-metadata>=4.0; python_version<='3.8'
19
19
  Requires-Dist: ansys-api-pyensight==0.3.2
20
20
  Requires-Dist: requests>=2.28.2
21
- Requires-Dist: pyansys-docker>=5.0.4
21
+ Requires-Dist: docker>=6.1.0
22
22
  Requires-Dist: urllib3<2
23
23
  Requires-Dist: typing>=3.7.4.3
24
24
  Requires-Dist: typing-extensions>=4.5.0
@@ -35,7 +35,7 @@ Requires-Dist: ansys-sphinx-theme==0.9.9 ; extra == "doc"
35
35
  Requires-Dist: sphinx-copybutton==0.5.2 ; extra == "doc"
36
36
  Requires-Dist: sphinx-gallery==0.13.0 ; extra == "doc"
37
37
  Requires-Dist: sphinxcontrib-mermaid==0.9.2 ; extra == "doc"
38
- Requires-Dist: pyansys-docker>=5.0.4 ; extra == "doc"
38
+ Requires-Dist: docker>=6.1.0 ; extra == "doc"
39
39
  Requires-Dist: matplotlib==3.7.2 ; extra == "doc"
40
40
  Requires-Dist: requests>=2.28.2 ; extra == "doc"
41
41
  Requires-Dist: sphinxcontrib.jquery==4.1 ; extra == "doc"
@@ -47,7 +47,7 @@ Requires-Dist: dill>=0.3.5.1 ; extra == "tests"
47
47
  Requires-Dist: pytest-mock==3.10.0 ; extra == "tests"
48
48
  Requires-Dist: urllib3==1.26.10 ; extra == "tests"
49
49
  Requires-Dist: requests>=2.28.2 ; extra == "tests"
50
- Requires-Dist: pyansys-docker>=5.0.4 ; extra == "tests"
50
+ Requires-Dist: docker>=6.1.0 ; extra == "tests"
51
51
  Project-URL: Changelog, https://github.com/ansys/pyensight/blob/main/CHANGELOG.rst
52
52
  Project-URL: Documentation, https://ensight.docs.pyansys.com/
53
53
  Project-URL: Homepage, https://github.com/ansys/pyensight
@@ -131,7 +131,7 @@ Installation
131
131
  ------------
132
132
  To use PyEnSight, you must have a locally installed and licensed copy of
133
133
  Ansys EnSight 2022 R2 or later. The ``ansys-pyensight-core`` package supports
134
- Python 3.8 through Python 3.11 on Windows and Linux.
134
+ Python 3.9 through Python 3.12 on Windows and Linux.
135
135
 
136
136
  Two modes of installation are available:
137
137
 
@@ -1,26 +1,26 @@
1
1
  ansys/pyensight/core/__init__.py,sha256=ZOASvqNxSR8CGJDHQACGwjtFVvI_vmmfbpy1IAmEJhk,828
2
- ansys/pyensight/core/deep_pixel_view.html,sha256=86JNwI-Q5iXtBEbkVUDLSK0D7PxJB3O5enlRsslMZBY,3351
3
- ansys/pyensight/core/dockerlauncher.py,sha256=DYC1RsJmof_dIj0VrIlZ7IiRhQ0yLg57IsKcJBTCtTU,25129
2
+ ansys/pyensight/core/deep_pixel_view.html,sha256=oZmcCIS3Dqqsoj8oheYubLAH2ZVKXao3iJM2WXYBEKs,3421
3
+ ansys/pyensight/core/dockerlauncher.py,sha256=tFiemu2hFQE_Ce0FlJ_TdqUs36W-gxtoe5uRL0u6JXs,27175
4
4
  ansys/pyensight/core/enscontext.py,sha256=UfeFvY4ZyOcIkgKcIyhs3GohZhWl515QFhJtBxvIfpE,11803
5
- ansys/pyensight/core/enshell_grpc.py,sha256=veRCXgP_7CMOdPS4gU_tOT6KkA9c56NXxkZEHRFWTTc,14963
5
+ ansys/pyensight/core/enshell_grpc.py,sha256=nNvJqrFG_-glM90dPAC6anFT9qXg7WohQ6CoULXgaSQ,15134
6
6
  ansys/pyensight/core/ensight_grpc.py,sha256=yFnvxjI2cAWd0c0gcM46MEIA5Ov7DUMlufqUwwc3g9U,14343
7
7
  ansys/pyensight/core/ensobj.py,sha256=tynUyYrpzCz2lvcse6fcmutnG6Jj111s518OlO19EqE,17354
8
- ansys/pyensight/core/launch_ensight.py,sha256=p8eT7_Z7W_pPUxRZKrUbK6qJbhqVZkzobJt5E19Az8o,5940
9
- ansys/pyensight/core/launcher.py,sha256=3MzPugpBh2WPkq24yX_1vypzKiTR8Dx5E5rS1i5FO2Q,8977
8
+ ansys/pyensight/core/launch_ensight.py,sha256=KqUq3dYc2j4aKMkZYu9rXXw7ODZDqFbD6kx4Vt0uJcg,5915
9
+ ansys/pyensight/core/launcher.py,sha256=zj-6DBp307-IJ0RTDmZOxCFVGemJu8YaagJLZFLloNw,10445
10
10
  ansys/pyensight/core/listobj.py,sha256=vsVTeI3RY0P1n5GNOHW-iU95GCWnHlOg_E6leVMQScw,8223
11
11
  ansys/pyensight/core/locallauncher.py,sha256=sgaPrG-7ctXZ_ytGuHeriiVmgvI0kUeX6nKVJ4OiDUs,13984
12
12
  ansys/pyensight/core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- ansys/pyensight/core/renderable.py,sha256=-eVJd1X_8saziCO9EWP7zVz3N62WFPWp8Yy95zdJCxc,26860
14
- ansys/pyensight/core/session.py,sha256=Eoss0yZFV_YVlEflSb6sjxU5XzgvknrdsR0iTKr5ZRM,60023
13
+ ansys/pyensight/core/renderable.py,sha256=z61Pum_Pa2CVoXVWOCqPngeHT_ifBS3fpqA5mZDDmnc,30777
14
+ ansys/pyensight/core/session.py,sha256=nTeqiXsOz_FffeYGsYLsWDznP86-ZBxS0AA8wgOEBeU,62690
15
15
  ansys/pyensight/core/sgeo_poll.html,sha256=1M4BIc5CZpYA3b40qzk22NcPCLhjFnWdoS2PrS6Rhn4,752
16
16
  ansys/pyensight/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  ansys/pyensight/core/utils/adr.py,sha256=XslZhlwcrSGzOlnhzprOv3ju_ppxxsWBjCnQL5KiNms,3570
18
- ansys/pyensight/core/utils/export.py,sha256=RDJXrVoLcxSXfiGyh_0Bxhx-tsZr_tFmKe0-1WFuc38,17652
18
+ ansys/pyensight/core/utils/export.py,sha256=MGdPAPpI4CoLR-Fnctkqf9J7--J3DPEXK79kKZGVCqw,21552
19
19
  ansys/pyensight/core/utils/parts.py,sha256=x0Zso-ef64UJ-3BmYS3dymjftaWQI21WFTsDt-ghI-k,3986
20
20
  ansys/pyensight/core/utils/query.py,sha256=cQXt_07ZuNAwueAIXinI3_f7G9lXass6j7G0aRJltZE,19035
21
- ansys/pyensight/core/utils/support.py,sha256=gNBH_VyQ_Gdas7P28W_GZ62Tz4Gg7YK8UASUzdT-lSU,2397
21
+ ansys/pyensight/core/utils/support.py,sha256=QI3z9ex7zJxjFbkCPba9DWqWgPFIThORqr0nvRfVjuc,4089
22
22
  ansys/pyensight/core/utils/views.py,sha256=vf4gSBRl6uC_LPwZdzrdMcR0dyi_PwYmRo20CPmjEBE,12209
23
- ansys_pyensight_core-0.6.1.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
24
- ansys_pyensight_core-0.6.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
25
- ansys_pyensight_core-0.6.1.dist-info/METADATA,sha256=R1G_6oQ-lZNIiqIEO_OQHCJ-PVJwqxhvVm-LA6GagjM,11804
26
- ansys_pyensight_core-0.6.1.dist-info/RECORD,,
23
+ ansys_pyensight_core-0.7.0.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
24
+ ansys_pyensight_core-0.7.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
25
+ ansys_pyensight_core-0.7.0.dist-info/METADATA,sha256=nKZPh4wq6SSDRrRwbZsHViS4MSp82NPfOXVOWqXARvE,11781
26
+ ansys_pyensight_core-0.7.0.dist-info/RECORD,,