Skip to content

Commit 3ab596f

Browse files
feat: enhancements to transport mode (#2419)
Co-authored-by: pyansys-ci-bot <[email protected]>
1 parent 5bde7de commit 3ab596f

File tree

11 files changed

+76
-49
lines changed

11 files changed

+76
-49
lines changed

doc/changelog.d/2419.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Enhancements to transport mode

src/ansys/geometry/core/connection/client.py

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@
2323

2424
import atexit
2525
import logging
26-
import os
2726
from pathlib import Path
2827
import time
2928
from typing import Optional
30-
import warnings
3129

3230
from beartype import beartype as check_input_types
3331
import grpc
@@ -52,7 +50,7 @@
5250

5351
def _create_geometry_channel(
5452
target: str,
55-
transport_mode: str | None = None,
53+
transport_mode: str,
5654
uds_dir: Path | str | None = None,
5755
uds_id: str | None = None,
5856
certs_dir: Path | str | None = None,
@@ -64,9 +62,8 @@ def _create_geometry_channel(
6462
target : str
6563
Target of the channel. This is usually a string in the form of
6664
``host:port``.
67-
transport_mode : str | None
68-
Transport mode selected, by default `None` and thus it will be selected
69-
for you based on the connection criteria. Options are: "insecure", "uds", "wnua", "mtls"
65+
transport_mode : str
66+
Transport mode selected. Options are: "insecure", "uds", "wnua", "mtls"
7067
uds_dir : Path | str | None
7168
Directory to use for Unix Domain Sockets (UDS) transport mode.
7269
By default `None` and thus it will use the "~/.conn" folder.
@@ -102,9 +99,9 @@ def _create_geometry_channel(
10299

103100
# Create the channel accordingly
104101
return create_channel(
102+
transport_mode=transport_mode,
105103
host=host,
106104
port=port,
107-
transport_mode=transport_mode,
108105
uds_service="aposdas_socket",
109106
uds_dir=uds_dir,
110107
uds_id=uds_id,
@@ -139,8 +136,8 @@ def wait_until_healthy(
139136
* If the total elapsed time exceeds the value for the ``timeout`` parameter,
140137
a ``TimeoutError`` is raised.
141138
transport_mode : str | None
142-
Transport mode selected, by default `None` and thus it will be selected
143-
for you based on the connection criteria. Options are: "insecure", "uds", "wnua", "mtls"
139+
Transport mode selected. Needed if channel is a string.
140+
Options are: "insecure", "uds", "wnua", "mtls".
144141
uds_dir : Path | str | None
145142
Directory to use for Unix Domain Sockets (UDS) transport mode.
146143
By default `None` and thus it will use the "~/.conn" folder.
@@ -168,23 +165,22 @@ def wait_until_healthy(
168165
t_max = time.time() + timeout
169166
t_out = 0.1
170167

171-
# If transport mode is not specified, default to insecure when running in CI
172-
if transport_mode is None:
173-
if os.getenv("IS_WORKFLOW_RUNNING") is not None:
174-
warnings.warn(
175-
"Transport mode forced to 'insecure' when running in CI workflows.",
176-
)
177-
transport_mode = "insecure"
178-
else:
168+
# If the channel is a string, create a channel using the specified transport mode
169+
channel_creation_required = True if isinstance(channel, str) else False
170+
tmp_channel = None
171+
172+
# If transport mode is not specified and a channel creation is required, raise an error
173+
if channel_creation_required:
174+
if transport_mode is None:
179175
raise ValueError(
180-
"Transport mode must be specified when not running in CI workflows."
176+
"Transport mode must be specified."
181177
" Use 'transport_mode' parameter with one of the possible options."
182178
" Options are: 'insecure', 'uds', 'wnua', 'mtls'."
183179
)
180+
else:
181+
from ansys.tools.common.cyberchannel import verify_transport_mode
184182

185-
# If the channel is a string, create a channel using the default insecure channel
186-
channel_creation_required = True if isinstance(channel, str) else False
187-
tmp_channel = None
183+
verify_transport_mode(transport_mode)
188184

189185
while time.time() < t_max:
190186
try:
@@ -262,8 +258,8 @@ class GrpcClient:
262258
Protocol version to use for communication with the server. If None, v0 is used.
263259
Available versions are "v0", "v1", etc.
264260
transport_mode : str | None
265-
Transport mode selected, by default `None` and thus it will be selected
266-
for you based on the connection criteria. Options are: "insecure", "uds", "wnua", "mtls"
261+
Transport mode selected. Needed if ``channel`` is not provided.
262+
Options are: "insecure", "uds", "wnua", "mtls".
267263
uds_dir : Path | str | None
268264
Directory to use for Unix Domain Sockets (UDS) transport mode.
269265
By default `None` and thus it will use the "~/.conn" folder.

src/ansys/geometry/core/connection/docker_instance.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ def __init__(
182182
# Initialize instance variables
183183
self._container: Container = None
184184
self._existed_previously: bool = False
185+
self._transport_mode: str | None = transport_mode
185186

186187
# Check the port availability
187188
port_available, cont = self._check_port_availability(port)
@@ -197,6 +198,17 @@ def __init__(
197198
# Finally, store the container
198199
self._container = cont
199200
self._existed_previously = True
201+
# If no transport mode was provided, try to extract it from the existing
202+
# container command line arguments
203+
if transport_mode is None:
204+
cmd_args = cont.attrs["Config"].get("Cmd", [])
205+
for arg in cmd_args:
206+
if "--transport-mode=" in arg:
207+
self._transport_mode = arg.split("=")[1]
208+
break
209+
# If still None, default to "mtls"
210+
if self._transport_mode is None:
211+
self._transport_mode = "mtls"
200212
return
201213

202214
# At this stage, confirm that you have to deploy our own Geometry service.
@@ -389,6 +401,7 @@ def _deploy_container(
389401
# If the deployment went fine, this means that you have deployed the service.
390402
self._container = container
391403
self._existed_previously = False
404+
self._transport_mode = transport_mode
392405

393406
@property
394407
def container(self) -> "Container":
@@ -404,6 +417,18 @@ def existed_previously(self) -> bool:
404417
"""
405418
return self._existed_previously
406419

420+
@property
421+
def transport_mode(self) -> str:
422+
"""Transport mode used by the Docker container.
423+
424+
Returns
425+
-------
426+
str
427+
Transport mode used by the Docker container. If no transport mode
428+
was specified during initialization, it defaults to "mtls".
429+
"""
430+
return self._transport_mode if self._transport_mode else "mtls"
431+
407432

408433
def get_geometry_container_type(instance: LocalDockerInstance) -> GeometryContainers | None:
409434
"""Provide back the ``GeometryContainers`` value.

src/ansys/geometry/core/connection/launcher.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import os
2626
from pathlib import Path
2727
from typing import TYPE_CHECKING
28-
import warnings
2928

3029
from ansys.geometry.core.connection.backend import ApiVersions, BackendType
3130
import ansys.geometry.core.connection.defaults as pygeom_defaults
@@ -340,7 +339,7 @@ def launch_docker_modeler(
340339
in which case the client logs to the console.
341340
transport_mode : str | None
342341
Transport mode selected, by default `None` and thus it will be selected
343-
for you based on the connection criteria. Options are: "insecure", "mtls"
342+
for you based on the connection criteria. Options are: "insecure", "mtls".
344343
certs_dir : Path | str | None
345344
Directory to use for TLS certificates.
346345
By default `None` and thus search for the "ANSYS_GRPC_CERTIFICATES" environment variable.
@@ -360,12 +359,6 @@ def launch_docker_modeler(
360359
if not _HAS_DOCKER: # pragma: no cover
361360
raise ModuleNotFoundError("The package 'docker' is required to use this function.")
362361

363-
if os.getenv("IS_WORKFLOW_RUNNING") is not None:
364-
warnings.warn(
365-
"Transport mode forced to 'insecure' when running in CI workflows.",
366-
)
367-
transport_mode = "insecure"
368-
369362
# Call the LocalDockerInstance ctor.
370363
docker_instance = LocalDockerInstance(
371364
port=port,
@@ -384,7 +377,7 @@ def launch_docker_modeler(
384377
docker_instance=docker_instance,
385378
logging_level=client_log_level,
386379
logging_file=client_log_file,
387-
transport_mode=transport_mode if transport_mode else "mtls",
380+
transport_mode=docker_instance.transport_mode,
388381
certs_dir=certs_dir,
389382
)
390383

src/ansys/geometry/core/connection/validate.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@
3636

3737
def validate(*args, **kwargs): # pragma: no cover
3838
"""Create a client using the default settings and validate it."""
39-
print(GrpcClient(*args, **kwargs))
39+
# Assume local transport mode for validation if not provided
40+
if "transport_mode" not in kwargs:
41+
import platform
42+
43+
kwargs["transport_mode"] = "wnua" if platform.system() == "Windows" else "uds"
44+
try:
45+
GrpcClient(*args, **kwargs)
46+
except Exception:
47+
# Let's give it a try to insecure mode... just in case
48+
kwargs["transport_mode"] = "insecure"
49+
GrpcClient(*args, **kwargs)
50+
else:
51+
GrpcClient(*args, **kwargs)
52+
4053
# TODO: consider adding additional server stat reporting
4154
# https://github.com/ansys/pyansys-geometry/issues/1319

src/ansys/geometry/core/modeler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ class Modeler:
8787
Protocol version to use for communication with the server. If None, v0 is used.
8888
Available versions are "v0", "v1", etc.
8989
transport_mode : str | None
90-
Transport mode selected, by default `None` and thus it will be selected
91-
for you based on the connection criteria. Options are: "insecure", "uds", "wnua", "mtls"
90+
Transport mode selected. Needed if ``channel`` is not provided.
91+
Options are: "insecure", "uds", "wnua", "mtls".
9292
uds_dir : Path | str | None
9393
Directory to use for Unix Domain Sockets (UDS) transport mode.
9494
By default `None` and thus it will use the "~/.conn" folder.

tests/conftest.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ def pytest_addoption(parser):
7979
parser.addoption(
8080
"--transport-mode",
8181
action="store",
82-
default="default",
83-
help=("Specify the transport mode to use for the tests. By default, 'default'."),
84-
choices=("default", "insecure", "uds", "wnua", "mtls"),
82+
default="insecure",
83+
help=("Specify the transport mode to use for the tests. By default, 'insecure'."),
84+
choices=("insecure", "uds", "wnua", "mtls"),
8585
)
8686

8787

@@ -184,10 +184,9 @@ def proto_version(request):
184184
def transport_mode(request):
185185
"""Fixture to determine transport mode to be used."""
186186

187-
value: str = request.config.getoption("--transport-mode", default="default")
188-
mode = None if value.lower() == "default" else value.lower()
187+
value: str = request.config.getoption("--transport-mode", default="insecure")
189188

190-
return mode
189+
return value.lower()
191190

192191

193192
@pytest.fixture

tests/integration/test_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232

3333

3434
@pytest.fixture(scope="function")
35-
def client(modeler: Modeler):
35+
def client(modeler: Modeler, transport_mode: str) -> GrpcClient:
3636
# this uses DEFAULT_HOST and DEFAULT_PORT which are set by environment
3737
# variables in the workflow
38-
return GrpcClient()
38+
return GrpcClient(transport_mode=transport_mode)
3939

4040

4141
def test_client_init(client: GrpcClient):

tests/integration/test_design.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,7 +1312,7 @@ def test_upload_file(modeler: Modeler, tmp_path_factory: pytest.TempPathFactory)
13121312
assert path_on_server is not None
13131313

13141314

1315-
def test_stream_upload_file(tmp_path_factory: pytest.TempPathFactory):
1315+
def test_stream_upload_file(tmp_path_factory: pytest.TempPathFactory, transport_mode: str):
13161316
"""Test uploading a file to the server."""
13171317
# Define a new maximum message length
13181318
import ansys.geometry.core.connection.defaults as pygeom_defaults
@@ -1333,7 +1333,7 @@ def test_stream_upload_file(tmp_path_factory: pytest.TempPathFactory):
13331333
# Upload file - necessary to import the Modeler class and create an instance
13341334
from ansys.geometry.core import Modeler
13351335

1336-
modeler = Modeler()
1336+
modeler = Modeler(transport_mode=transport_mode)
13371337
path_on_server = modeler._upload_file_stream(file)
13381338
assert path_on_server is not None
13391339
finally:

tests/integration/test_design_import.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def _checker_method(comp: Component, comp_ref: Component, precise_check: bool =
110110
_checker_method(subcomp, subcomp_ref, precise_check)
111111

112112

113-
def test_design_import_simple_case(modeler: Modeler):
113+
def test_design_import_simple_case(modeler: Modeler, transport_mode: str):
114114
# With the given session let's create a the following Design
115115
#
116116
# Create your design on the server side
@@ -157,7 +157,7 @@ def test_design_import_simple_case(modeler: Modeler):
157157
)
158158

159159
# Now, let's create a new client session
160-
new_client = Modeler()
160+
new_client = Modeler(transport_mode=transport_mode)
161161
read_design = new_client.read_existing_design()
162162

163163
# And now assert all its elements

0 commit comments

Comments
 (0)