ansys-speos-core 0.6.3__tar.gz → 0.7.0__tar.gz
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.
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/PKG-INFO +17 -20
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/README.rst +3 -3
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/pyproject.toml +18 -17
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/generic/general_methods.py +3 -7
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/body.py +2 -1
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/client.py +80 -30
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/face.py +3 -3
- ansys_speos_core-0.7.0/src/ansys/speos/core/kernel/grpc/transport_options.py +171 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/intensity_template.py +3 -2
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/job.py +39 -2
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/part.py +2 -1
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/scene.py +3 -2
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/sensor_template.py +3 -2
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/simulation_template.py +3 -2
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/sop_template.py +3 -2
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/source_template.py +2 -1
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/spectrum.py +3 -2
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/vop_template.py +3 -2
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/launcher.py +43 -11
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/lxp.py +1 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/project.py +2 -4
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/simulation.py +1 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/speos.py +28 -19
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/LICENSE +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/__init__.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/body.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/bsdf.py +4 -4
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/face.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/generic/constants.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/generic/visualization_methods.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/geo_ref.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/intensity.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/__init__.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/crud.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/proto_message_utils.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/logger.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/opt_prop.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/part.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/proto_message_utils.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/py.typed +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/sensor.py +1 -1
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/source.py +1 -1
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/spectrum.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/workflow/__init__.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/workflow/combine_speos.py +0 -0
- {ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/workflow/open_result.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ansys-speos-core
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: A Python wrapper for Ansys Speos
|
|
5
5
|
Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
6
6
|
Maintainer-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
@@ -21,28 +21,25 @@ Classifier: Topic :: Scientific/Engineering :: Physics
|
|
|
21
21
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
22
22
|
License-File: LICENSE
|
|
23
23
|
Requires-Dist: protobuf>=3.20,<7
|
|
24
|
-
Requires-Dist: grpcio>=1.50.0,<1.
|
|
24
|
+
Requires-Dist: grpcio>=1.50.0,<1.77
|
|
25
25
|
Requires-Dist: grpcio-health-checking>=1.45.0,<1.68
|
|
26
26
|
Requires-Dist: ansys-api-speos==0.15.3
|
|
27
|
-
Requires-Dist: ansys-tools-
|
|
27
|
+
Requires-Dist: ansys-tools-common>=0.3.1
|
|
28
28
|
Requires-Dist: numpy>=1.20.3,<3
|
|
29
29
|
Requires-Dist: comtypes>=1.4,<1.5; platform_system=='Windows'
|
|
30
|
-
Requires-Dist: ansys-sphinx-theme==1.6.
|
|
31
|
-
Requires-Dist:
|
|
30
|
+
Requires-Dist: ansys-sphinx-theme[autoapi]==1.6.3 ; extra == "doc"
|
|
31
|
+
Requires-Dist: ansys-tools-visualization-interface>=0.8.3 ; extra == "doc"
|
|
32
|
+
Requires-Dist: numpydoc==1.10.0 ; extra == "doc"
|
|
32
33
|
Requires-Dist: Sphinx==8.1.3 ; extra == "doc"
|
|
33
34
|
Requires-Dist: sphinx-copybutton==0.5.2 ; extra == "doc"
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist: sphinx_design==0.6.1 ; extra == "doc"
|
|
36
|
-
Requires-Dist: sphinx-jinja==2.0.2 ; extra == "doc"
|
|
37
|
-
Requires-Dist: sphinxcontrib-mermaid==1.0.0 ; extra == "doc"
|
|
35
|
+
Requires-Dist: sphinxcontrib-mermaid==1.2.3 ; extra == "doc"
|
|
38
36
|
Requires-Dist: myst-parser==4.0.1 ; extra == "doc"
|
|
39
|
-
Requires-Dist: nbsphinx==0.9.
|
|
40
|
-
Requires-Dist: jupytext==1.
|
|
41
|
-
Requires-Dist: jupyterlab==4.
|
|
37
|
+
Requires-Dist: nbsphinx==0.9.8 ; extra == "doc"
|
|
38
|
+
Requires-Dist: jupytext==1.18.1 ; extra == "doc"
|
|
39
|
+
Requires-Dist: jupyterlab==4.5.0 ; extra == "doc"
|
|
42
40
|
Requires-Dist: jupyter-server==2.17.0 ; extra == "doc"
|
|
43
41
|
Requires-Dist: nbconvert==7.16.6 ; extra == "doc"
|
|
44
42
|
Requires-Dist: pyvista[jupyter]>=0.43,<0.47 ; extra == "doc"
|
|
45
|
-
Requires-Dist: ansys-tools-visualization-interface>=0.8.3 ; extra == "doc"
|
|
46
43
|
Requires-Dist: pyvista>=0.40.0,<0.47 ; extra == "graphics"
|
|
47
44
|
Requires-Dist: ansys-tools-visualization-interface>=0.8.3 ; extra == "graphics"
|
|
48
45
|
Requires-Dist: matplotlib ; extra == "jupyter"
|
|
@@ -50,13 +47,13 @@ Requires-Dist: jupyterlab>=3 ; extra == "jupyter"
|
|
|
50
47
|
Requires-Dist: ipywidgets ; extra == "jupyter"
|
|
51
48
|
Requires-Dist: pyvista[jupyter]>=0.43,<0.47 ; extra == "jupyter"
|
|
52
49
|
Requires-Dist: ansys-tools-visualization-interface>=0.8.3 ; extra == "jupyter"
|
|
53
|
-
Requires-Dist: notebook==7.
|
|
54
|
-
Requires-Dist: psutil==7.
|
|
55
|
-
Requires-Dist: pytest==
|
|
50
|
+
Requires-Dist: notebook==7.5.0 ; extra == "jupyter"
|
|
51
|
+
Requires-Dist: psutil==7.1.3 ; extra == "tests"
|
|
52
|
+
Requires-Dist: pytest==9.0.1 ; extra == "tests"
|
|
56
53
|
Requires-Dist: pyvista>=0.40.0,<0.47 ; extra == "tests"
|
|
57
54
|
Requires-Dist: ansys-tools-visualization-interface>=0.8.3 ; extra == "tests"
|
|
58
55
|
Requires-Dist: ansys-platform-instancemanagement>=1.0.3 ; extra == "tests"
|
|
59
|
-
Requires-Dist: pytest-cov==
|
|
56
|
+
Requires-Dist: pytest-cov==7.0.0 ; extra == "tests"
|
|
60
57
|
Project-URL: Changelog, https://github.com/ansys/pyspeos/blob/main/doc/source/changelog.rst
|
|
61
58
|
Project-URL: Discussions, https://github.com/ansys/pyspeos/discussions
|
|
62
59
|
Project-URL: Documentation, https://speos.docs.pyansys.com/
|
|
@@ -143,7 +140,7 @@ All sources are located in `<src/>`_ folder.
|
|
|
143
140
|
|
|
144
141
|
from ansys.speos.core.speos import Speos
|
|
145
142
|
|
|
146
|
-
speos = Speos(
|
|
143
|
+
speos = Speos()
|
|
147
144
|
|
|
148
145
|
Documentation and issues
|
|
149
146
|
------------------------
|
|
@@ -213,11 +210,11 @@ Then, to launch SpeosRPC server with product version 2025.1, you can run:
|
|
|
213
210
|
|
|
214
211
|
cat GH_TOKEN.txt | docker login ghcr.io -u "$GH_USERNAME" --password-stdin
|
|
215
212
|
docker pull ghcr.io/ansys/speos-rpc:252
|
|
216
|
-
docker run --detach --name speos-rpc -p 127.0.0.1:50098:50098 -e ANSYSLMD_LICENSE_FILE=$LICENSE_SERVER --entrypoint /app/SpeosRPC_Server.x ghcr.io/ansys/speos-rpc:252 --host 0.0.0.0
|
|
213
|
+
docker run --detach --name speos-rpc -p 127.0.0.1:50098:50098 -e ANSYSLMD_LICENSE_FILE=$LICENSE_SERVER --entrypoint /app/SpeosRPC_Server.x ghcr.io/ansys/speos-rpc:252 --transport_insecure --host 0.0.0.0
|
|
217
214
|
|
|
218
215
|
.. note::
|
|
219
216
|
|
|
220
|
-
To use the latest image in development, you can use `ghcr.io/ansys/speos-rpc:
|
|
217
|
+
To use the latest image in development, you can use `ghcr.io/ansys/speos-rpc:dev`.
|
|
221
218
|
|
|
222
219
|
On the other hand, the SpeosRPC server can be started locally.
|
|
223
220
|
|
|
@@ -73,7 +73,7 @@ All sources are located in `<src/>`_ folder.
|
|
|
73
73
|
|
|
74
74
|
from ansys.speos.core.speos import Speos
|
|
75
75
|
|
|
76
|
-
speos = Speos(
|
|
76
|
+
speos = Speos()
|
|
77
77
|
|
|
78
78
|
Documentation and issues
|
|
79
79
|
------------------------
|
|
@@ -143,11 +143,11 @@ Then, to launch SpeosRPC server with product version 2025.1, you can run:
|
|
|
143
143
|
|
|
144
144
|
cat GH_TOKEN.txt | docker login ghcr.io -u "$GH_USERNAME" --password-stdin
|
|
145
145
|
docker pull ghcr.io/ansys/speos-rpc:252
|
|
146
|
-
docker run --detach --name speos-rpc -p 127.0.0.1:50098:50098 -e ANSYSLMD_LICENSE_FILE=$LICENSE_SERVER --entrypoint /app/SpeosRPC_Server.x ghcr.io/ansys/speos-rpc:252 --host 0.0.0.0
|
|
146
|
+
docker run --detach --name speos-rpc -p 127.0.0.1:50098:50098 -e ANSYSLMD_LICENSE_FILE=$LICENSE_SERVER --entrypoint /app/SpeosRPC_Server.x ghcr.io/ansys/speos-rpc:252 --transport_insecure --host 0.0.0.0
|
|
147
147
|
|
|
148
148
|
.. note::
|
|
149
149
|
|
|
150
|
-
To use the latest image in development, you can use `ghcr.io/ansys/speos-rpc:
|
|
150
|
+
To use the latest image in development, you can use `ghcr.io/ansys/speos-rpc:dev`.
|
|
151
151
|
|
|
152
152
|
On the other hand, the SpeosRPC server can be started locally.
|
|
153
153
|
|
|
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ansys-speos-core"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.0"
|
|
8
8
|
description = "A Python wrapper for Ansys Speos"
|
|
9
9
|
readme = "README.rst"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -28,10 +28,10 @@ classifiers=[
|
|
|
28
28
|
]
|
|
29
29
|
dependencies=[
|
|
30
30
|
"protobuf>=3.20,<7",
|
|
31
|
-
"grpcio>=1.50.0,<1.
|
|
31
|
+
"grpcio>=1.50.0,<1.77",
|
|
32
32
|
"grpcio-health-checking>=1.45.0,<1.68",
|
|
33
33
|
"ansys-api-speos==0.15.3",
|
|
34
|
-
"ansys-tools-
|
|
34
|
+
"ansys-tools-common>=0.3.1",
|
|
35
35
|
"numpy>=1.20.3,<3",
|
|
36
36
|
"comtypes>=1.4,<1.5; platform_system=='Windows'",
|
|
37
37
|
]
|
|
@@ -42,12 +42,12 @@ graphics = [
|
|
|
42
42
|
"ansys-tools-visualization-interface>=0.8.3",
|
|
43
43
|
]
|
|
44
44
|
tests = [
|
|
45
|
-
"psutil==7.
|
|
46
|
-
"pytest==
|
|
45
|
+
"psutil==7.1.3",
|
|
46
|
+
"pytest==9.0.1",
|
|
47
47
|
"pyvista>=0.40.0,<0.47",
|
|
48
48
|
"ansys-tools-visualization-interface>=0.8.3",
|
|
49
49
|
"ansys-platform-instancemanagement>=1.0.3",
|
|
50
|
-
"pytest-cov==
|
|
50
|
+
"pytest-cov==7.0.0",
|
|
51
51
|
]
|
|
52
52
|
jupyter = [
|
|
53
53
|
"matplotlib",
|
|
@@ -55,25 +55,22 @@ jupyter = [
|
|
|
55
55
|
"ipywidgets",
|
|
56
56
|
"pyvista[jupyter]>=0.43,<0.47",
|
|
57
57
|
"ansys-tools-visualization-interface>=0.8.3",
|
|
58
|
-
"notebook==7.
|
|
58
|
+
"notebook==7.5.0",
|
|
59
59
|
]
|
|
60
60
|
doc = [
|
|
61
|
-
"ansys-sphinx-theme==1.6.
|
|
62
|
-
"
|
|
61
|
+
"ansys-sphinx-theme[autoapi]==1.6.3",
|
|
62
|
+
"ansys-tools-visualization-interface>=0.8.3",
|
|
63
|
+
"numpydoc==1.10.0",
|
|
63
64
|
"Sphinx==8.1.3",
|
|
64
65
|
"sphinx-copybutton==0.5.2",
|
|
65
|
-
"
|
|
66
|
-
"sphinx_design==0.6.1",
|
|
67
|
-
"sphinx-jinja==2.0.2",
|
|
68
|
-
"sphinxcontrib-mermaid==1.0.0",
|
|
66
|
+
"sphinxcontrib-mermaid==1.2.3",
|
|
69
67
|
"myst-parser==4.0.1",
|
|
70
|
-
"nbsphinx==0.9.
|
|
71
|
-
"jupytext==1.
|
|
72
|
-
"jupyterlab==4.
|
|
68
|
+
"nbsphinx==0.9.8",
|
|
69
|
+
"jupytext==1.18.1",
|
|
70
|
+
"jupyterlab==4.5.0",
|
|
73
71
|
"jupyter-server==2.17.0",
|
|
74
72
|
"nbconvert==7.16.6",
|
|
75
73
|
"pyvista[jupyter]>=0.43,<0.47",
|
|
76
|
-
"ansys-tools-visualization-interface>=0.8.3",
|
|
77
74
|
]
|
|
78
75
|
|
|
79
76
|
[project.urls]
|
|
@@ -147,6 +144,10 @@ show_missing = true
|
|
|
147
144
|
minversion = "7.1"
|
|
148
145
|
addopts = "-vvv --color=yes -ra --durations=25 --cov=ansys.speos --cov-report html:.cov/html --cov-report xml:.cov/xml --cov-report term"
|
|
149
146
|
testpaths = ["tests"]
|
|
147
|
+
markers = [
|
|
148
|
+
"all_speos_versions: Supported on all Speos versions.",
|
|
149
|
+
"supported_speos_versions(min, max): Feature only supported from minimal to maximal Speos versions."
|
|
150
|
+
]
|
|
150
151
|
|
|
151
152
|
[tool.mypy]
|
|
152
153
|
python_version = "3.10"
|
{ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/generic/general_methods.py
RENAMED
|
@@ -34,10 +34,10 @@ from pathlib import Path
|
|
|
34
34
|
from typing import List, Optional, Union, cast
|
|
35
35
|
import warnings
|
|
36
36
|
|
|
37
|
+
from ansys.tools.common.path import get_available_ansys_installations
|
|
37
38
|
import numpy as np
|
|
38
39
|
|
|
39
40
|
from ansys.speos.core.generic.constants import DEFAULT_VERSION
|
|
40
|
-
from ansys.tools.path import get_available_ansys_installations
|
|
41
41
|
|
|
42
42
|
_GRAPHICS_AVAILABLE = None
|
|
43
43
|
|
|
@@ -90,9 +90,8 @@ def run_if_graphics_required(warning=False):
|
|
|
90
90
|
global _GRAPHICS_AVAILABLE
|
|
91
91
|
if _GRAPHICS_AVAILABLE is None:
|
|
92
92
|
try:
|
|
93
|
-
import pyvista as pv # noqa: F401
|
|
94
|
-
|
|
95
93
|
from ansys.tools.visualization_interface import Plotter # noqa: F401
|
|
94
|
+
import pyvista as pv # noqa: F401
|
|
96
95
|
|
|
97
96
|
_GRAPHICS_AVAILABLE = True
|
|
98
97
|
except ImportError: # pragma: no cover
|
|
@@ -179,11 +178,8 @@ def error_no_install(install_path: Union[Path, str], version: Union[int, str]):
|
|
|
179
178
|
version : Union[int, str]
|
|
180
179
|
Version
|
|
181
180
|
"""
|
|
182
|
-
install_loc_msg = ""
|
|
183
|
-
if install_path:
|
|
184
|
-
install_loc_msg = f"at {Path(install_path).parent}"
|
|
185
181
|
raise FileNotFoundError(
|
|
186
|
-
f"Ansys Speos RPC server installation not found{
|
|
182
|
+
f"Ansys Speos RPC server installation not found at {install_path}. "
|
|
187
183
|
f"Please define AWP_ROOT{version} environment variable"
|
|
188
184
|
)
|
|
189
185
|
|
|
@@ -28,6 +28,7 @@ from ansys.api.speos.part.v1 import (
|
|
|
28
28
|
body_pb2 as messages,
|
|
29
29
|
body_pb2_grpc as service,
|
|
30
30
|
)
|
|
31
|
+
|
|
31
32
|
from ansys.speos.core.kernel.crud import CrudItem, CrudStub
|
|
32
33
|
from ansys.speos.core.kernel.proto_message_utils import protobuf_message_to_str
|
|
33
34
|
|
|
@@ -94,7 +95,7 @@ class BodyStub(CrudStub):
|
|
|
94
95
|
Like in the following example:
|
|
95
96
|
|
|
96
97
|
>>> from ansys.speos.core.speos import Speos
|
|
97
|
-
>>> speos = Speos(
|
|
98
|
+
>>> speos = Speos()
|
|
98
99
|
>>> body_db = speos.client.bodies()
|
|
99
100
|
|
|
100
101
|
"""
|
|
@@ -25,14 +25,15 @@
|
|
|
25
25
|
import logging
|
|
26
26
|
import os
|
|
27
27
|
from pathlib import Path
|
|
28
|
-
import subprocess
|
|
28
|
+
import subprocess # nosec
|
|
29
|
+
import tempfile
|
|
29
30
|
import time
|
|
30
31
|
from typing import TYPE_CHECKING, List, Optional, Union
|
|
31
32
|
|
|
33
|
+
from ansys.api.speos.part.v1 import body_pb2, face_pb2, part_pb2
|
|
32
34
|
import grpc
|
|
33
35
|
from grpc._channel import _InactiveRpcError
|
|
34
36
|
|
|
35
|
-
from ansys.api.speos.part.v1 import body_pb2, face_pb2, part_pb2
|
|
36
37
|
from ansys.speos.core.generic.constants import (
|
|
37
38
|
DEFAULT_HOST,
|
|
38
39
|
DEFAULT_PORT,
|
|
@@ -42,6 +43,13 @@ from ansys.speos.core.generic.constants import (
|
|
|
42
43
|
from ansys.speos.core.generic.general_methods import retrieve_speos_install_dir
|
|
43
44
|
from ansys.speos.core.kernel.body import BodyLink, BodyStub
|
|
44
45
|
from ansys.speos.core.kernel.face import FaceLink, FaceStub
|
|
46
|
+
from ansys.speos.core.kernel.grpc.transport_options import (
|
|
47
|
+
InsecureOptions,
|
|
48
|
+
TransportMode,
|
|
49
|
+
TransportOptions,
|
|
50
|
+
UDSOptions,
|
|
51
|
+
WNUAOptions,
|
|
52
|
+
)
|
|
45
53
|
from ansys.speos.core.kernel.intensity_template import (
|
|
46
54
|
IntensityTemplateLink,
|
|
47
55
|
IntensityTemplateStub,
|
|
@@ -82,7 +90,7 @@ def wait_until_healthy(channel: grpc.Channel, timeout: float):
|
|
|
82
90
|
|
|
83
91
|
Parameters
|
|
84
92
|
----------
|
|
85
|
-
channel :
|
|
93
|
+
channel : grpc.Channel
|
|
86
94
|
Channel to wait until established and healthy.
|
|
87
95
|
timeout : float
|
|
88
96
|
Timeout in seconds. One attempt will be made each 100 milliseconds
|
|
@@ -107,24 +115,45 @@ def wait_until_healthy(channel: grpc.Channel, timeout: float):
|
|
|
107
115
|
)
|
|
108
116
|
|
|
109
117
|
|
|
118
|
+
def default_docker_channel(
|
|
119
|
+
host: Optional[str] = DEFAULT_HOST,
|
|
120
|
+
port: Union[str, int] = DEFAULT_PORT,
|
|
121
|
+
message_size: int = MAX_CLIENT_MESSAGE_SIZE,
|
|
122
|
+
) -> grpc.Channel:
|
|
123
|
+
"""Create default transport options for docker on CI."""
|
|
124
|
+
return TransportOptions(
|
|
125
|
+
mode=TransportMode.INSECURE,
|
|
126
|
+
options=InsecureOptions(host=host, port=port, allow_remote_host=True),
|
|
127
|
+
).create_channel(grpc_options=[("grpc.max_receive_message_length", message_size)])
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def default_local_channel(
|
|
131
|
+
port: Union[str, int] = DEFAULT_PORT, message_size: int = MAX_CLIENT_MESSAGE_SIZE
|
|
132
|
+
) -> grpc.Channel:
|
|
133
|
+
"""Create default transport options, WNUA on Windows, UDS on Linux."""
|
|
134
|
+
if os.name == "nt":
|
|
135
|
+
transport = TransportOptions(
|
|
136
|
+
mode=TransportMode.WNUA, options=WNUAOptions(host=DEFAULT_HOST, port=port)
|
|
137
|
+
)
|
|
138
|
+
else:
|
|
139
|
+
sock_file = Path(tempfile.gettempdir()) / f"speosrpc_sock_{port}"
|
|
140
|
+
transport = TransportOptions(
|
|
141
|
+
mode=TransportMode.UDS, options=UDSOptions(uds_fullpath=str(sock_file))
|
|
142
|
+
)
|
|
143
|
+
return transport.create_channel(
|
|
144
|
+
grpc_options=[("grpc.max_receive_message_length", message_size)]
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
110
148
|
class SpeosClient:
|
|
111
149
|
"""
|
|
112
150
|
Wraps a speos gRPC connection.
|
|
113
151
|
|
|
114
152
|
Parameters
|
|
115
153
|
----------
|
|
116
|
-
|
|
117
|
-
Host where the server is running.
|
|
118
|
-
By default, ``DEFAULT_HOST``.
|
|
119
|
-
port : Union[str, int], optional
|
|
120
|
-
Port number where the server is running.
|
|
121
|
-
By default, ``DEFAULT_PORT``.
|
|
122
|
-
channel : ~grpc.Channel, optional
|
|
154
|
+
channel : grpc.Channel, optional
|
|
123
155
|
gRPC channel for server communication.
|
|
124
156
|
By default, ``None``.
|
|
125
|
-
message_size: int
|
|
126
|
-
Maximum Message size of a newly generated channel
|
|
127
|
-
By default, ``MAX_CLIENT_MESSAGE_SIZE``.
|
|
128
157
|
remote_instance : ansys.platform.instancemanagement.Instance
|
|
129
158
|
The corresponding remote instance when the Speos Service
|
|
130
159
|
is launched through PyPIM. This instance will be deleted when calling
|
|
@@ -143,11 +172,8 @@ class SpeosClient:
|
|
|
143
172
|
|
|
144
173
|
def __init__(
|
|
145
174
|
self,
|
|
146
|
-
host: Optional[str] = DEFAULT_HOST,
|
|
147
|
-
port: Union[str, int] = DEFAULT_PORT,
|
|
148
175
|
version: str = DEFAULT_VERSION,
|
|
149
176
|
channel: Optional[grpc.Channel] = None,
|
|
150
|
-
message_size: int = MAX_CLIENT_MESSAGE_SIZE,
|
|
151
177
|
remote_instance: Optional["Instance"] = None,
|
|
152
178
|
timeout: Optional[int] = 60,
|
|
153
179
|
logging_level: Optional[int] = logging.INFO,
|
|
@@ -170,23 +196,17 @@ class SpeosClient:
|
|
|
170
196
|
else:
|
|
171
197
|
self._version = version
|
|
172
198
|
if channel:
|
|
173
|
-
#
|
|
199
|
+
# grpc channel is provided by caller, used by PyPIM or Docker server
|
|
174
200
|
self._channel = channel
|
|
175
|
-
self._target = str(channel)
|
|
176
201
|
else:
|
|
177
|
-
self.
|
|
178
|
-
|
|
179
|
-
self._target = f"{host}:{port}"
|
|
180
|
-
self._channel = grpc.insecure_channel(
|
|
181
|
-
self._target,
|
|
182
|
-
options=[("grpc.max_receive_message_length", message_size)],
|
|
183
|
-
)
|
|
202
|
+
self._channel = default_local_channel()
|
|
203
|
+
|
|
184
204
|
# do not finish initialization until channel is healthy
|
|
185
205
|
wait_until_healthy(self._channel, timeout)
|
|
186
206
|
|
|
187
207
|
# once connection with the client is established, create a logger
|
|
188
208
|
self._log = LOGGER.add_instance_logger(
|
|
189
|
-
name=self.
|
|
209
|
+
name=self.target(), client_instance=self, level=logging_level
|
|
190
210
|
)
|
|
191
211
|
if logging_file:
|
|
192
212
|
if isinstance(logging_file, Path):
|
|
@@ -492,7 +512,7 @@ List[ansys.speos.core.kernel.face.FaceLink]]
|
|
|
492
512
|
"""Represent the client as a string."""
|
|
493
513
|
lines = []
|
|
494
514
|
lines.append(f"Ansys Speos client ({hex(id(self))})")
|
|
495
|
-
lines.append(f" Target: {self.
|
|
515
|
+
lines.append(f" Target: {self.target()}")
|
|
496
516
|
if self._closed:
|
|
497
517
|
lines.append(" Connection: Closed")
|
|
498
518
|
elif self.healthy:
|
|
@@ -504,6 +524,11 @@ List[ansys.speos.core.kernel.face.FaceLink]]
|
|
|
504
524
|
def close(self):
|
|
505
525
|
"""Close the channel.
|
|
506
526
|
|
|
527
|
+
.. warning::
|
|
528
|
+
|
|
529
|
+
Do not execute this function with untrusted environment variables.
|
|
530
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
531
|
+
|
|
507
532
|
Returns
|
|
508
533
|
-------
|
|
509
534
|
bool
|
|
@@ -517,7 +542,7 @@ List[ansys.speos.core.kernel.face.FaceLink]]
|
|
|
517
542
|
wait_time = 0
|
|
518
543
|
if self._remote_instance:
|
|
519
544
|
self._remote_instance.delete()
|
|
520
|
-
elif self.
|
|
545
|
+
elif self.__speos_exec:
|
|
521
546
|
self.__close_local_speos_rpc_server()
|
|
522
547
|
while self.healthy and wait_time < 15:
|
|
523
548
|
time.sleep(1)
|
|
@@ -543,5 +568,30 @@ List[ansys.speos.core.kernel.face.FaceLink]]
|
|
|
543
568
|
return self._closed
|
|
544
569
|
|
|
545
570
|
def __close_local_speos_rpc_server(self):
|
|
546
|
-
|
|
547
|
-
|
|
571
|
+
"""Close a locally started Speos RPC server.
|
|
572
|
+
|
|
573
|
+
.. warning::
|
|
574
|
+
Do not execute this function after modifying protected or private
|
|
575
|
+
attributes of the SpeosClient class or in a context with untrusted
|
|
576
|
+
environment variables.
|
|
577
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
578
|
+
|
|
579
|
+
"""
|
|
580
|
+
try:
|
|
581
|
+
# Extract port number at end of target string
|
|
582
|
+
target = self.target()
|
|
583
|
+
if ":" in target:
|
|
584
|
+
port = target.split(":")[-1]
|
|
585
|
+
else:
|
|
586
|
+
port = target.split("_")[-1]
|
|
587
|
+
int(port)
|
|
588
|
+
except ValueError:
|
|
589
|
+
raise RuntimeError("The port of the local server is not a valid integer.")
|
|
590
|
+
if (
|
|
591
|
+
not Path(self.__speos_exec).is_file()
|
|
592
|
+
or Path(self.__speos_exec).stem != "SpeosRPC_Server"
|
|
593
|
+
):
|
|
594
|
+
raise RuntimeError("Unexpected executable path for Speos rpc executable.")
|
|
595
|
+
|
|
596
|
+
command = [self.__speos_exec, f"-s{port}"]
|
|
597
|
+
subprocess.run(command, check=True) # nosec
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
|
|
25
25
|
from typing import Iterator, List
|
|
26
26
|
|
|
27
|
-
from grpc import RpcError
|
|
28
|
-
|
|
29
27
|
from ansys.api.speos.part.v1 import (
|
|
30
28
|
face_pb2 as messages,
|
|
31
29
|
face_pb2_grpc as service,
|
|
32
30
|
)
|
|
31
|
+
from grpc import RpcError
|
|
32
|
+
|
|
33
33
|
from ansys.speos.core.generic.general_methods import min_speos_version
|
|
34
34
|
from ansys.speos.core.kernel.crud import CrudItem, CrudStub
|
|
35
35
|
from ansys.speos.core.kernel.proto_message_utils import protobuf_message_to_str
|
|
@@ -97,7 +97,7 @@ class FaceStub(CrudStub):
|
|
|
97
97
|
Like in the following example:
|
|
98
98
|
|
|
99
99
|
>>> from ansys.speos.core.speos import Speos
|
|
100
|
-
>>> speos = Speos(
|
|
100
|
+
>>> speos = Speos()
|
|
101
101
|
>>> face_db = speos.client.faces()
|
|
102
102
|
|
|
103
103
|
"""
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Copyright (C) 2021 - 2025 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
|
+
"""Define supported transport options for the FileTransfer Tool client.
|
|
24
|
+
|
|
25
|
+
This module provides classes and enumerations to configure and manage
|
|
26
|
+
different transport modes (UDS, mTLS, Insecure) for the FileTransfer Tool.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from dataclasses import dataclass
|
|
30
|
+
import enum
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
|
|
33
|
+
from ansys.tools.common.cyberchannel import create_channel
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TransportMode(enum.Enum):
|
|
37
|
+
"""Enumeration of transport modes supported by the FileTransfer Tool."""
|
|
38
|
+
|
|
39
|
+
UDS = "uds"
|
|
40
|
+
MTLS = "mtls"
|
|
41
|
+
INSECURE = "insecure"
|
|
42
|
+
WNUA = "wnua"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass(kw_only=True)
|
|
46
|
+
class UDSOptions:
|
|
47
|
+
"""Options for UDS transport mode."""
|
|
48
|
+
|
|
49
|
+
uds_service: str | None = None
|
|
50
|
+
uds_dir: str | Path | None = None
|
|
51
|
+
uds_id: str | None = None
|
|
52
|
+
uds_fullpath: str | Path | None = None
|
|
53
|
+
|
|
54
|
+
def _to_cyberchannel_kwargs(self):
|
|
55
|
+
return {
|
|
56
|
+
"uds_service": self.uds_service,
|
|
57
|
+
"uds_dir": self.uds_dir,
|
|
58
|
+
"uds_id": self.uds_id,
|
|
59
|
+
"uds_fullpath": self.uds_fullpath,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass(kw_only=True)
|
|
64
|
+
class MTLSOptions:
|
|
65
|
+
"""Options for mTLS transport mode."""
|
|
66
|
+
|
|
67
|
+
certs_dir: str | Path | None = None
|
|
68
|
+
host: str = "localhost"
|
|
69
|
+
port: int
|
|
70
|
+
allow_remote_host: bool = False
|
|
71
|
+
|
|
72
|
+
def _to_cyberchannel_kwargs(self):
|
|
73
|
+
if not self.allow_remote_host:
|
|
74
|
+
if self.host not in ("localhost", "127.0.0.1"):
|
|
75
|
+
raise ValueError(
|
|
76
|
+
f"Remote host '{self.host}' is not allowed when "
|
|
77
|
+
"'allow_remote_host' is set to False."
|
|
78
|
+
)
|
|
79
|
+
return {
|
|
80
|
+
"certs_dir": self.certs_dir,
|
|
81
|
+
"host": self.host,
|
|
82
|
+
"port": self.port,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclass(kw_only=True)
|
|
87
|
+
class InsecureOptions:
|
|
88
|
+
"""Options for insecure transport mode."""
|
|
89
|
+
|
|
90
|
+
host: str = "localhost"
|
|
91
|
+
port: int
|
|
92
|
+
allow_remote_host: bool = False
|
|
93
|
+
|
|
94
|
+
def _to_cyberchannel_kwargs(self):
|
|
95
|
+
if not self.allow_remote_host:
|
|
96
|
+
if self.host not in ("localhost", "127.0.0.1"):
|
|
97
|
+
raise ValueError(
|
|
98
|
+
f"Remote host '{self.host}' is not allowed when "
|
|
99
|
+
"'allow_remote_host' is set to False."
|
|
100
|
+
)
|
|
101
|
+
return {
|
|
102
|
+
"host": self.host,
|
|
103
|
+
"port": self.port,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@dataclass(kw_only=True)
|
|
108
|
+
class WNUAOptions:
|
|
109
|
+
"""Options for Windows Named User Authentication transport mode."""
|
|
110
|
+
|
|
111
|
+
host: str = "localhost"
|
|
112
|
+
port: int
|
|
113
|
+
|
|
114
|
+
def _to_cyberchannel_kwargs(self):
|
|
115
|
+
return {
|
|
116
|
+
"host": self.host,
|
|
117
|
+
"port": self.port,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclass(kw_only=True)
|
|
122
|
+
class TransportOptions:
|
|
123
|
+
"""Transport options for the FileTransfer Tool client."""
|
|
124
|
+
|
|
125
|
+
mode: TransportMode
|
|
126
|
+
options: UDSOptions | MTLSOptions | InsecureOptions | WNUAOptions
|
|
127
|
+
|
|
128
|
+
def __init__(
|
|
129
|
+
self,
|
|
130
|
+
mode: TransportMode | str = "uds",
|
|
131
|
+
options: UDSOptions | MTLSOptions | InsecureOptions | WNUAOptions | None = None,
|
|
132
|
+
):
|
|
133
|
+
if isinstance(mode, str):
|
|
134
|
+
mode = TransportMode(mode)
|
|
135
|
+
if options is None:
|
|
136
|
+
if mode != TransportMode.UDS:
|
|
137
|
+
raise RuntimeError("TransportOptions must be provided for modes other than UDS.")
|
|
138
|
+
# The default cannot be set in the constructor signature
|
|
139
|
+
# since '_get_uds_dir_default' may raise.
|
|
140
|
+
options = UDSOptions()
|
|
141
|
+
|
|
142
|
+
if mode == TransportMode.UDS:
|
|
143
|
+
if not isinstance(options, UDSOptions):
|
|
144
|
+
raise TypeError("For UDS transport mode, options must be of type UDSOptions.")
|
|
145
|
+
elif mode == TransportMode.MTLS:
|
|
146
|
+
if not isinstance(options, MTLSOptions):
|
|
147
|
+
raise TypeError("For mTLS transport mode, options must be of type MTLSOptions.")
|
|
148
|
+
elif mode == TransportMode.INSECURE:
|
|
149
|
+
if not isinstance(options, InsecureOptions):
|
|
150
|
+
raise TypeError(
|
|
151
|
+
"For Insecure transport mode, options must be of type InsecureOptions."
|
|
152
|
+
)
|
|
153
|
+
elif mode == TransportMode.WNUA:
|
|
154
|
+
if not isinstance(options, WNUAOptions):
|
|
155
|
+
raise TypeError("For WNUA transport mode, options must be of type WNUAOptions.")
|
|
156
|
+
else:
|
|
157
|
+
raise ValueError(f"Unsupported transport mode: {mode}")
|
|
158
|
+
|
|
159
|
+
self.mode = mode
|
|
160
|
+
self.options = options
|
|
161
|
+
|
|
162
|
+
def _to_cyberchannel_kwargs(self):
|
|
163
|
+
"""Convert transport options to cyberchannel kwargs."""
|
|
164
|
+
return {
|
|
165
|
+
"transport_mode": self.mode.value,
|
|
166
|
+
**self.options._to_cyberchannel_kwargs(),
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
def create_channel(self, grpc_options):
|
|
170
|
+
"""Create a gRPC channel based on the transport options."""
|
|
171
|
+
return create_channel(**self._to_cyberchannel_kwargs(), grpc_options=grpc_options)
|
{ansys_speos_core-0.6.3 → ansys_speos_core-0.7.0}/src/ansys/speos/core/kernel/intensity_template.py
RENAMED
|
@@ -28,6 +28,7 @@ from ansys.api.speos.intensity.v1 import (
|
|
|
28
28
|
intensity_pb2 as messages,
|
|
29
29
|
intensity_pb2_grpc as service,
|
|
30
30
|
)
|
|
31
|
+
|
|
31
32
|
from ansys.speos.core.kernel.crud import CrudItem, CrudStub
|
|
32
33
|
from ansys.speos.core.kernel.proto_message_utils import protobuf_message_to_str
|
|
33
34
|
|
|
@@ -55,7 +56,7 @@ class IntensityTemplateLink(CrudItem):
|
|
|
55
56
|
>>> from ansys.speos.core.kernel.intensity_template import (
|
|
56
57
|
... ProtoIntensityTemplate,
|
|
57
58
|
... )
|
|
58
|
-
>>> speos = Speos(
|
|
59
|
+
>>> speos = Speos()
|
|
59
60
|
>>> int_t_db = speos.client.intensity_templates()
|
|
60
61
|
>>> int_t_message = ProtoIntensityTemplate(name="Cos_3_170")
|
|
61
62
|
>>> int_t_message.cos.N = 3.0
|
|
@@ -126,7 +127,7 @@ class IntensityTemplateStub(CrudStub):
|
|
|
126
127
|
intensity_templates() method. Like in the following example:
|
|
127
128
|
|
|
128
129
|
>>> from ansys.speos.core.speos import Speos
|
|
129
|
-
>>> speos = Speos(
|
|
130
|
+
>>> speos = Speos()
|
|
130
131
|
>>> int_t_db = speos.client.intensity_templates()
|
|
131
132
|
|
|
132
133
|
"""
|