From b13635ac029a78cff4c77e2f77b4db70c62c2ce9 Mon Sep 17 00:00:00 2001 From: Subha Nayak <118820636+subhnayak@users.noreply.github.com> Date: Fri, 28 Nov 2025 12:04:35 +0530 Subject: [PATCH 1/7] after first patch --- doc/source/getting_started/index.rst | 11 ++++ pyproject.toml | 2 +- src/ansys/meshing/prime/graphics/graphics.py | 2 +- src/ansys/meshing/prime/internals/client.py | 51 +++++++++++-------- src/ansys/meshing/prime/internals/config.py | 4 ++ .../prime/internals/grpc_communicator.py | 8 ++- src/ansys/meshing/prime/internals/launcher.py | 21 ++++++-- 7 files changed, 73 insertions(+), 26 deletions(-) diff --git a/doc/source/getting_started/index.rst b/doc/source/getting_started/index.rst index ccf8b96a4e..e8abd0874e 100644 --- a/doc/source/getting_started/index.rst +++ b/doc/source/getting_started/index.rst @@ -57,6 +57,17 @@ To install a basic version of the client, use this command instead: pip install -e . +Connecting through gRPC +----------------------- + +PyPrimeMesh uses gRPC to provide secure communications between client and server. +When you run the client and server on the same machine, + +- For Unix OS or Linux OS, PyPrimeMesh uses UDS (Unix Domain Socket) for communication. +- For Windows OS, server uses interceptor to validate gRPC connections, + ensures the client is running on the same Windows user account as the server and authenticates the client. + +When you launch PyPrimeMesh, gRPC establish connection between the Client and Server with local connection only. Dependencies ------------ diff --git a/pyproject.toml b/pyproject.toml index 4535ebb58b..514b6f5b4d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi" [project] name = "ansys-meshing-prime" -version = "0.6.2" +version = "0.6.3" description = "PyPrimeMesh is a Python client to Ansys Prime Server, which delivers core Ansys meshing technology." readme = "README.md" requires-python = ">=3.8,<4" diff --git a/src/ansys/meshing/prime/graphics/graphics.py b/src/ansys/meshing/prime/graphics/graphics.py index 6cc9a2c16e..d70d16f071 100644 --- a/src/ansys/meshing/prime/graphics/graphics.py +++ b/src/ansys/meshing/prime/graphics/graphics.py @@ -28,7 +28,7 @@ import numpy as np import pyvista as pv import vtk -from pyvista import Plotter +from pyvista.plotting.plotting import Plotter import ansys.meshing.prime as prime from ansys.meshing.prime.graphics.trame_gui import _HAS_TRAME, TrameVisualizer diff --git a/src/ansys/meshing/prime/internals/client.py b/src/ansys/meshing/prime/internals/client.py index 076ed65fb3..804ae54e9c 100644 --- a/src/ansys/meshing/prime/internals/client.py +++ b/src/ansys/meshing/prime/internals/client.py @@ -65,6 +65,8 @@ def __init__( port: int = defaults.port(), timeout: float = defaults.connection_timeout(), credentials=None, + connection_type: config.ConnectionType = config.ConnectionType.GRPC, + uds_file: str = None, **kwargs, ): """Initialize the client.""" @@ -76,28 +78,37 @@ def __init__( self._process = server_process self._comm = None if not local: - try: - from ansys.meshing.prime.internals.grpc_communicator import ( - GRPCCommunicator, - ) - - channel = kwargs.get('channel', None) - if channel is not None: - self._comm = GRPCCommunicator(channel=channel, timeout=timeout) - else: - self._comm = GRPCCommunicator( - ip=ip, port=port, timeout=timeout, credentials=credentials + if connection_type == config.ConnectionType.GRPC: + try: + from ansys.meshing.prime.internals.grpc_communicator import ( + GRPCCommunicator, ) - setattr(self, 'port', port) - except ImportError as err: - logging.getLogger('PyPrimeMesh').error( - f'Failed to load grpc_communicator with message: {err.msg}' - ) - raise - except ConnectionError: - self.exit() - logging.getLogger('PyPrimeMesh').error('Failed to connect to PRIME GRPC server') + channel = kwargs.get('channel', None) + if channel is not None: + self._comm = GRPCCommunicator(channel=channel, timeout=timeout) + else: + if os.name == 'nt': + self._comm = GRPCCommunicator( + ip=ip, port=port, timeout=timeout, credentials=credentials + ) + else: + self._comm = GRPCCommunicator( + uds_file=uds_file, timeout=timeout, credentials=credentials + ) + setattr(self, 'port', port) + except ImportError as err: + logging.getLogger('PyPrimeMesh').error( + f'Failed to load grpc_communicator with message: {err.msg}' + ) + raise + except ConnectionError: + self.exit() + + logging.getLogger('PyPrimeMesh').error('Failed to connect to PRIME GRPC server') + raise + else: + logging.getLogger('PyPrimeMesh').error(f'Invalid server type: {connection_type}') raise else: try: diff --git a/src/ansys/meshing/prime/internals/config.py b/src/ansys/meshing/prime/internals/config.py index b0692a06b5..63c3a7e338 100644 --- a/src/ansys/meshing/prime/internals/config.py +++ b/src/ansys/meshing/prime/internals/config.py @@ -23,6 +23,7 @@ """Configuration utility for PyPrimeMesh.""" from contextlib import contextmanager +from enum import Enum __all__ = [ 'enable_optimizing_numpy_arrays', @@ -44,6 +45,9 @@ from ansys.meshing.prime.internals.logger import PrimeLogger +class ConnectionType(Enum): + GRPC = 1 + def _optimize_vectors(): """Get the value of the flag for optimizing vectors.""" diff --git a/src/ansys/meshing/prime/internals/grpc_communicator.py b/src/ansys/meshing/prime/internals/grpc_communicator.py index 0ab1ee4ca7..d4e895efa9 100644 --- a/src/ansys/meshing/prime/internals/grpc_communicator.py +++ b/src/ansys/meshing/prime/internals/grpc_communicator.py @@ -104,7 +104,13 @@ def __init__( ip_addr = f"{ip}:{port}" channel_options = grpc_utils.get_default_channel_args() if credentials is None: - self._channel = grpc.insecure_channel(ip_addr, options=channel_options) + uds_file = kwargs.get('uds_file', None) + if uds_file is not None: + options = (('grpc.default_authority', 'localhost'),) + self._channel = grpc.insecure_channel(uds_file, options=options) + else: + options = (('grpc.default_authority', 'localhost'),) + self._channel = grpc.insecure_channel(ip_addr, options=options) else: self._channel = grpc.secure_channel(ip_addr, credentials, options=channel_options) diff --git a/src/ansys/meshing/prime/internals/launcher.py b/src/ansys/meshing/prime/internals/launcher.py index 9dd06b950a..8d1f3e838a 100644 --- a/src/ansys/meshing/prime/internals/launcher.py +++ b/src/ansys/meshing/prime/internals/launcher.py @@ -26,6 +26,7 @@ import subprocess import sys from typing import Optional +import uuid import ansys.meshing.prime.internals.config as config import ansys.meshing.prime.internals.defaults as defaults @@ -73,6 +74,7 @@ def launch_server_process( ip: str = defaults.ip(), port: int = defaults.port(), n_procs: Optional[int] = None, + connection_type: config.ConnectionType = None, **kw, ) -> subprocess.Popen: """Launch a server process for Ansys Prime Server. @@ -153,6 +155,9 @@ def launch_server_process( server_args.append(f'--scheduler') server_args.append(f'{scheduler}') + if os.name != 'nt' and connection_type == config.ConnectionType.GRPC: + server_args.append(f'--uds={kw.get("uds_file", "")}') + kwargs = { 'stdin': subprocess.DEVNULL, } @@ -205,12 +210,12 @@ def launch_remote_prime( return client - def launch_prime( prime_root: Optional[str] = None, ip: str = defaults.ip(), port: int = defaults.port(), timeout: float = defaults.connection_timeout(), + connection_type: config.ConnectionType = config.ConnectionType.GRPC, n_procs: Optional[int] = None, version: Optional[str] = None, **kwargs, @@ -262,8 +267,18 @@ def launch_prime( client.container_name = container_name return client + uds_file = f'unix:/tmp/pyprimemesh-{uuid.uuid4()}.sock' + server = launch_server_process( - prime_root=prime_root, ip=ip, port=port, n_procs=n_procs, **kwargs + prime_root=prime_root, ip=ip, port=port, n_procs=n_procs, + connection_type=connection_type, uds_file=uds_file, **kwargs ) - return Client(server_process=server, ip=ip, port=port, timeout=timeout) + return Client( + server_process=server, + ip=ip, + port=port, + timeout=timeout, + uds_file=uds_file, + connection_type=connection_type, + ) From 383bbf9e3deb710929ccc4ea9a3b0607f21a311d Mon Sep 17 00:00:00 2001 From: Subha Nayak <118820636+subhnayak@users.noreply.github.com> Date: Fri, 28 Nov 2025 12:04:48 +0530 Subject: [PATCH 2/7] after second patch --- doc/source/getting_started/index.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/source/getting_started/index.rst b/doc/source/getting_started/index.rst index e8abd0874e..36de93b74e 100644 --- a/doc/source/getting_started/index.rst +++ b/doc/source/getting_started/index.rst @@ -61,13 +61,13 @@ Connecting through gRPC ----------------------- PyPrimeMesh uses gRPC to provide secure communications between client and server. -When you run the client and server on the same machine, +When you run the client and server on the same machine: -- For Unix OS or Linux OS, PyPrimeMesh uses UDS (Unix Domain Socket) for communication. -- For Windows OS, server uses interceptor to validate gRPC connections, +- For Linux OS, PyPrimeMesh uses UDS (Unix Domain Socket) for communications. +- For Windows OS, PyPrimeMesh uses interceptor to validate gRPC connections, ensures the client is running on the same Windows user account as the server and authenticates the client. -When you launch PyPrimeMesh, gRPC establish connection between the Client and Server with local connection only. +When you launch PyPrimeMesh, gRPC establishes a connection between the Client and the Server with local a connection only. Dependencies ------------ From 5f363158daee389edf7347527e524a41bc081dec Mon Sep 17 00:00:00 2001 From: Subha Nayak <118820636+subhnayak@users.noreply.github.com> Date: Tue, 9 Dec 2025 10:48:12 +0530 Subject: [PATCH 3/7] specific changes included --- doc/styles/config/vocabularies/ANSYS/accept.txt | 1 + src/ansys/meshing/prime/internals/config.py | 1 + src/ansys/meshing/prime/internals/launcher.py | 12 +++++++++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/styles/config/vocabularies/ANSYS/accept.txt b/doc/styles/config/vocabularies/ANSYS/accept.txt index 600c223aa2..c59492bb5e 100644 --- a/doc/styles/config/vocabularies/ANSYS/accept.txt +++ b/doc/styles/config/vocabularies/ANSYS/accept.txt @@ -5,6 +5,7 @@ AutoMesh automesh Boolean CAD +client_certs_dir conformally [Dd]efeature defeaturing diff --git a/src/ansys/meshing/prime/internals/config.py b/src/ansys/meshing/prime/internals/config.py index 63c3a7e338..284e2aa171 100644 --- a/src/ansys/meshing/prime/internals/config.py +++ b/src/ansys/meshing/prime/internals/config.py @@ -45,6 +45,7 @@ from ansys.meshing.prime.internals.logger import PrimeLogger + class ConnectionType(Enum): GRPC = 1 diff --git a/src/ansys/meshing/prime/internals/launcher.py b/src/ansys/meshing/prime/internals/launcher.py index 8d1f3e838a..a6c311193e 100644 --- a/src/ansys/meshing/prime/internals/launcher.py +++ b/src/ansys/meshing/prime/internals/launcher.py @@ -25,8 +25,8 @@ import os import subprocess import sys -from typing import Optional import uuid +from typing import Optional import ansys.meshing.prime.internals.config as config import ansys.meshing.prime.internals.defaults as defaults @@ -210,6 +210,7 @@ def launch_remote_prime( return client + def launch_prime( prime_root: Optional[str] = None, ip: str = defaults.ip(), @@ -270,8 +271,13 @@ def launch_prime( uds_file = f'unix:/tmp/pyprimemesh-{uuid.uuid4()}.sock' server = launch_server_process( - prime_root=prime_root, ip=ip, port=port, n_procs=n_procs, - connection_type=connection_type, uds_file=uds_file, **kwargs + prime_root=prime_root, + ip=ip, + port=port, + n_procs=n_procs, + connection_type=connection_type, + uds_file=uds_file, + **kwargs, ) return Client( From a39a7399d23d9bb05f2d6cf07f0536ac7b389864 Mon Sep 17 00:00:00 2001 From: Alex Fernandez Luces Date: Tue, 9 Dec 2025 10:19:20 +0100 Subject: [PATCH 4/7] fix: Remove problematic jobs --- .github/workflows/ci_cd.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 71e9383e64..91b8cb36ff 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -39,38 +39,9 @@ jobs: with: token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }} - branch-name: - if: github.event_name == 'pull_request' - name: Check the name of the branch - runs-on: ubuntu-latest - steps: - - name: Check branch name - uses: ansys/actions/branch-name-style@main - - style: - name: Code style - runs-on: ubuntu-latest - steps: - - name: PyAnsys code style checks - uses: ansys/actions/code-style@v6 - with: - python-version: ${{ env.MAIN_PYTHON_VERSION }} - vale-config: "doc/.vale.ini" - vale-version: "3.4.1" - - docs-style: - name: Documentation Style Check - runs-on: ubuntu-latest - steps: - - name: PyAnsys documentation style checks - uses: ansys/actions/doc-style@v6 - with: - token: ${{ secrets.GITHUB_TOKEN }} - smoke-tests: name: Build and Smoke tests runs-on: ${{ matrix.os }} - needs: [style] strategy: fail-fast: false matrix: @@ -93,7 +64,6 @@ jobs: docs: name: Documentation runs-on: ubuntu-latest - needs: [docs-style] steps: - name: Login in Github Container registry From f94e1e1366eb7e3b939ec46f3bc6a7b11704beab Mon Sep 17 00:00:00 2001 From: Alex Fernandez Luces Date: Tue, 9 Dec 2025 10:26:02 +0100 Subject: [PATCH 5/7] fix: outdated deps --- pyproject.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 514b6f5b4d..701d5df986 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,13 +31,15 @@ dependencies = [ [project.optional-dependencies] graphics = [ "pyvista[jupyter]>=0.38.1", + "vtk>=9.3.0", ] tests = [ "pytest==8.2.2", "pytest-cov==5.0.0", "pytest-pyvista==0.1.9", "pytest-xvfb==3.0.0", - "pyvista[trame]==0.44.0" + "pyvista[trame]==0.44.0", + "vtk>=9.3.0" ] doc = [ "ansys-sphinx-theme==0.15.2", @@ -45,6 +47,7 @@ doc = [ "numpydoc==1.7.0", "Sphinx==7.2.6", "pyvista==0.44.0", + "vtk>=9.3.0", "sphinx-autodoc-typehints==2.0.1", "sphinx-copybutton==0.5.2", "sphinx-gallery==0.15.0", @@ -53,6 +56,7 @@ doc = [ ] all = [ "pyvista[jupyter]>=0.38.1", + "vtk>=9.3.0", ] [project.urls] From 614004b9abc0d369a6b7b44f68761c2af757bd44 Mon Sep 17 00:00:00 2001 From: Alex Fernandez Luces Date: Tue, 9 Dec 2025 10:34:25 +0100 Subject: [PATCH 6/7] fix: deps --- .github/workflows/ci_cd.yml | 4 ++-- pyproject.toml | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 91b8cb36ff..7a024613a8 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -77,10 +77,10 @@ jobs: run: docker pull ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }} - name: Setup headless display - uses: pyvista/setup-headless-display-action@v2 + uses: pyvista/setup-headless-display-action@v4 - name: "Run Ansys documentation building action" - uses: ansys/actions/doc-build@v6 + uses: ansys/actions/doc-build@v10 with: check-links: false env: diff --git a/pyproject.toml b/pyproject.toml index 701d5df986..188b2d4307 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,16 +38,14 @@ tests = [ "pytest-cov==5.0.0", "pytest-pyvista==0.1.9", "pytest-xvfb==3.0.0", - "pyvista[trame]==0.44.0", - "vtk>=9.3.0" + "pyvista[trame]>=0.44.1", ] doc = [ "ansys-sphinx-theme==0.15.2", "jupyter-sphinx==0.5.3", "numpydoc==1.7.0", "Sphinx==7.2.6", - "pyvista==0.44.0", - "vtk>=9.3.0", + "pyvista>=0.44.1", "sphinx-autodoc-typehints==2.0.1", "sphinx-copybutton==0.5.2", "sphinx-gallery==0.15.0", @@ -56,7 +54,6 @@ doc = [ ] all = [ "pyvista[jupyter]>=0.38.1", - "vtk>=9.3.0", ] [project.urls] From f14d16f67de8391e26f6cc1024232ef096480e32 Mon Sep 17 00:00:00 2001 From: Subha Nayak <118820636+subhnayak@users.noreply.github.com> Date: Fri, 19 Dec 2025 10:01:27 +0530 Subject: [PATCH 7/7] updated the image version --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 7a024613a8..cd188c56d2 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -15,7 +15,7 @@ on: env: DOCKER_IMAGE_NAME: ghcr.io/ansys/prime - DOCKER_IMAGE_TAG: '24.2.0' + DOCKER_IMAGE_TAG: '24.2.5' MAIN_PYTHON_VERSION: '3.9' PACKAGE_NAME: 'ansys-meshing-prime' PACKAGE_NAMESPACE: 'ansys.meshing.prime'