Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 2 additions & 32 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -93,7 +64,6 @@ jobs:
docs:
name: Documentation
runs-on: ubuntu-latest
needs: [docs-style]
steps:

- name: Login in Github Container registry
Expand All @@ -107,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:
Expand Down
11 changes: 11 additions & 0 deletions doc/source/getting_started/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 establishes a connection between the Client and the Server with local a connection only.

Dependencies
------------
Expand Down
1 change: 1 addition & 0 deletions doc/styles/config/vocabularies/ANSYS/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ AutoMesh
automesh
Boolean
CAD
client_certs_dir
conformally
[Dd]efeature
defeaturing
Expand Down
7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -31,20 +31,21 @@ 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.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",
"pyvista>=0.44.1",
"sphinx-autodoc-typehints==2.0.1",
"sphinx-copybutton==0.5.2",
"sphinx-gallery==0.15.0",
Expand Down
2 changes: 1 addition & 1 deletion src/ansys/meshing/prime/graphics/graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
51 changes: 31 additions & 20 deletions src/ansys/meshing/prime/internals/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -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:
Expand Down
5 changes: 5 additions & 0 deletions src/ansys/meshing/prime/internals/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"""Configuration utility for PyPrimeMesh."""

from contextlib import contextmanager
from enum import Enum

__all__ = [
'enable_optimizing_numpy_arrays',
Expand All @@ -45,6 +46,10 @@
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."""
return __DEFAULT_USE_BINARY
Expand Down
8 changes: 7 additions & 1 deletion src/ansys/meshing/prime/internals/grpc_communicator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
25 changes: 23 additions & 2 deletions src/ansys/meshing/prime/internals/launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import os
import subprocess
import sys
import uuid
from typing import Optional

import ansys.meshing.prime.internals.config as config
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
}
Expand Down Expand Up @@ -211,6 +216,7 @@ def launch_prime(
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,
Expand Down Expand Up @@ -262,8 +268,23 @@ 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,
)
Loading