From c76dd98d85f1b02b0f253a2fff8c5a74d1ae4ec6 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Thu, 13 Jun 2024 10:33:11 +0200 Subject: [PATCH 01/12] Improve typehinting Signed-off-by: paul.profizi --- src/ansys/dpf/core/server_types.py | 70 ++++++++++++++++-------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/src/ansys/dpf/core/server_types.py b/src/ansys/dpf/core/server_types.py index 0d842e74c36..09399dc244a 100644 --- a/src/ansys/dpf/core/server_types.py +++ b/src/ansys/dpf/core/server_types.py @@ -4,6 +4,7 @@ Contains the different kinds of servers available for the factory. """ +from __future__ import annotations import abc import io import os @@ -15,7 +16,8 @@ import traceback from threading import Thread, Lock from abc import ABC -from ctypes import * +import ctypes +from typing import TYPE_CHECKING, Union import psutil @@ -26,6 +28,9 @@ from ansys.dpf.core import server_context from ansys.dpf.gate import load_api, data_processing_grpcapi +if TYPE_CHECKING: + from ansys.dpf.core.server_factory import DockerConfig + import logging LOG = logging.getLogger(__name__) @@ -671,17 +676,17 @@ class GrpcServer(CServer): def __init__( self, - ansys_path=None, - ip=LOCALHOST, - port=DPF_DEFAULT_PORT, - timeout=10, - as_global=True, - load_operators=True, - launch_server=True, - docker_config=RUNNING_DOCKER, - use_pypim=True, - num_connection_tryouts=3, - context=server_context.SERVER_CONTEXT, + ansys_path: Union[str, None] = None, + ip: str = LOCALHOST, + port: str = DPF_DEFAULT_PORT, + timeout: float = 10., + as_global: bool = True, + load_operators: bool = True, + launch_server: bool = True, + docker_config: DockerConfig = RUNNING_DOCKER, + use_pypim: bool = True, + num_connection_tryouts: int = 3, + context: Union[server_context.AvailableServerContexts, None] = server_context.SERVER_CONTEXT, ): # Load DPFClientAPI from ansys.dpf.core.misc import is_pypim_configured @@ -892,11 +897,11 @@ class InProcessServer(CServer): def __init__( self, - ansys_path=None, - as_global=True, - load_operators=True, - timeout=None, - context=server_context.SERVER_CONTEXT, + ansys_path: Union[str, None] = None, + as_global: bool = True, + load_operators: bool = True, + timeout: None = None, + context: Union[server_context.AvailableServerContexts, None] = server_context.SERVER_CONTEXT, ): # Load DPFClientAPI super().__init__(ansys_path=ansys_path, load_operators=load_operators) @@ -974,19 +979,20 @@ def config(self): def get_system_path() -> str: """Return the current PATH environment variable value of the system.""" if not os.name == "posix": - windll.kernel32.GetEnvironmentVariableA.argtypes = (c_char_p, c_char_p, c_int) - windll.kernel32.GetEnvironmentVariableA.restype = c_int + ctypes.windll.kernel32.GetEnvironmentVariableA.argtypes = ( + ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int + ) + ctypes.windll.kernel32.GetEnvironmentVariableA.restype = ctypes.c_int name = "PATH" b_name = name.encode("utf-8") size = 32767 - buffer = create_string_buffer(b"", size) - _ = windll.kernel32.GetEnvironmentVariableA(b_name, buffer, size) + buffer = ctypes.create_string_buffer(b"", size) + _ = ctypes.windll.kernel32.GetEnvironmentVariableA(b_name, buffer, size) return buffer.value.decode("utf-8") else: return sys.path - class LegacyGrpcServer(BaseServer): """Provides an instance of the DPF server using InProcess gRPC. Kept for backward-compatibility with dpf servers <0.5.0. @@ -1023,16 +1029,16 @@ class LegacyGrpcServer(BaseServer): def __init__( self, - ansys_path=None, - ip=LOCALHOST, - port=DPF_DEFAULT_PORT, - timeout=5, - as_global=True, - load_operators=True, - launch_server=True, - docker_config=RUNNING_DOCKER, - use_pypim=True, - context=server_context.SERVER_CONTEXT, + ansys_path: Union[str, None] = None, + ip: str = LOCALHOST, + port: str = DPF_DEFAULT_PORT, + timeout: float = 5., + as_global: bool = True, + load_operators: bool = True, + launch_server: bool = True, + docker_config: DockerConfig = RUNNING_DOCKER, + use_pypim: bool = True, + context: Union[server_context.AvailableServerContexts, None] = server_context.SERVER_CONTEXT, ): """Start the DPF server.""" # Use ansys.grpc.dpf From c7ceb37b02c4bbd1e5d00048285d257a5cf6c8af Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Thu, 13 Jun 2024 10:35:57 +0200 Subject: [PATCH 02/12] Add BaseService.initialize() Signed-off-by: paul.profizi --- src/ansys/dpf/core/core.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ansys/dpf/core/core.py b/src/ansys/dpf/core/core.py index 2f7e0663358..f23c6f629e7 100644 --- a/src/ansys/dpf/core/core.py +++ b/src/ansys/dpf/core/core.py @@ -499,6 +499,10 @@ def initialize_with_context(self, context): int(context.licensing_context_type), context.xml_path ) + def initialize(self): + """Initialize a DPF server without a context.""" + self._api.data_processing_initialization() + @version_requires("6.0") def release_dpf(self): """Clears the available Operators and Releases licenses when necessary. From 9a1de6df4937ee4bb6b99da134f4ccfe065c5956 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Thu, 13 Jun 2024 10:37:15 +0200 Subject: [PATCH 03/12] Initialize servers with no context Signed-off-by: paul.profizi --- src/ansys/dpf/core/server_types.py | 32 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/ansys/dpf/core/server_types.py b/src/ansys/dpf/core/server_types.py index 09399dc244a..e346262461a 100644 --- a/src/ansys/dpf/core/server_types.py +++ b/src/ansys/dpf/core/server_types.py @@ -738,11 +738,14 @@ def __init__( self.live = True self._create_shutdown_funcs() self._check_first_call(num_connection_tryouts) - try: - self._base_service.initialize_with_context(context) - self._context = context - except errors.DpfVersionNotSupported: - pass + if context: + try: + self._base_service.initialize_with_context(context) + self._context = context + except errors.DpfVersionNotSupported: + pass + else: + self._base_service.initialize() self.set_as_global(as_global=as_global) def _check_first_call(self, num_connection_tryouts): @@ -919,14 +922,17 @@ def __init__( f"Unable to locate the following file: {path}" ) raise e - try: - self.apply_context(context) - except errors.DpfVersionNotSupported: - self._base_service.initialize_with_context( - server_context.AvailableServerContexts.premium - ) - self._context = server_context.AvailableServerContexts.premium - pass + if context: + try: + self.apply_context(context) + except errors.DpfVersionNotSupported: + self._base_service.initialize_with_context( + server_context.AvailableServerContexts.premium + ) + self._context = server_context.AvailableServerContexts.premium + pass + else: + self._base_service.initialize() self.set_as_global(as_global=as_global) # Update the python os.environment if not os.name == "posix": From 6113ee2668c8044e09cd39077bc1451200e6cff6 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Thu, 13 Jun 2024 11:51:29 +0200 Subject: [PATCH 04/12] Add a no_context ServerContext Signed-off-by: paul.profizi --- src/ansys/dpf/core/server_context.py | 2 ++ src/ansys/dpf/core/server_types.py | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/ansys/dpf/core/server_context.py b/src/ansys/dpf/core/server_context.py index f43735132d0..e8c6d69cbcf 100644 --- a/src/ansys/dpf/core/server_context.py +++ b/src/ansys/dpf/core/server_context.py @@ -21,6 +21,7 @@ class LicensingContextType(Enum): + none = 5 premium = 1 """Checks if at least one license increment exists and allows operators to block an increment.""" @@ -207,6 +208,7 @@ def __ne__(self, other): class AvailableServerContexts: """Defines available server contexts.""" + no_context = ServerContext(LicensingContextType.none, "") pre_defined_environment = ServerContext(0) """DataProcessingCore.xml that is next to DataProcessingCore.dll/libDataProcessingCore.so will be taken""" diff --git a/src/ansys/dpf/core/server_types.py b/src/ansys/dpf/core/server_types.py index e346262461a..6883b015746 100644 --- a/src/ansys/dpf/core/server_types.py +++ b/src/ansys/dpf/core/server_types.py @@ -686,7 +686,7 @@ def __init__( docker_config: DockerConfig = RUNNING_DOCKER, use_pypim: bool = True, num_connection_tryouts: int = 3, - context: Union[server_context.AvailableServerContexts, None] = server_context.SERVER_CONTEXT, + context: server_context.AvailableServerContexts = server_context.SERVER_CONTEXT, ): # Load DPFClientAPI from ansys.dpf.core.misc import is_pypim_configured @@ -738,7 +738,7 @@ def __init__( self.live = True self._create_shutdown_funcs() self._check_first_call(num_connection_tryouts) - if context: + if context != core.AvailableServerContexts.no_context: try: self._base_service.initialize_with_context(context) self._context = context @@ -746,6 +746,7 @@ def __init__( pass else: self._base_service.initialize() + self._context = context self.set_as_global(as_global=as_global) def _check_first_call(self, num_connection_tryouts): @@ -904,7 +905,7 @@ def __init__( as_global: bool = True, load_operators: bool = True, timeout: None = None, - context: Union[server_context.AvailableServerContexts, None] = server_context.SERVER_CONTEXT, + context: server_context.AvailableServerContexts = server_context.SERVER_CONTEXT, ): # Load DPFClientAPI super().__init__(ansys_path=ansys_path, load_operators=load_operators) @@ -922,7 +923,7 @@ def __init__( f"Unable to locate the following file: {path}" ) raise e - if context: + if context != core.AvailableServerContexts.no_context: try: self.apply_context(context) except errors.DpfVersionNotSupported: @@ -933,6 +934,7 @@ def __init__( pass else: self._base_service.initialize() + self._context = context self.set_as_global(as_global=as_global) # Update the python os.environment if not os.name == "posix": @@ -1044,7 +1046,7 @@ def __init__( launch_server: bool = True, docker_config: DockerConfig = RUNNING_DOCKER, use_pypim: bool = True, - context: Union[server_context.AvailableServerContexts, None] = server_context.SERVER_CONTEXT, + context: server_context.AvailableServerContexts = server_context.SERVER_CONTEXT, ): """Start the DPF server.""" # Use ansys.grpc.dpf @@ -1109,11 +1111,14 @@ def __init__( self._create_shutdown_funcs() check_ansys_grpc_dpf_version(self, timeout) - try: - self._base_service.initialize_with_context(context) + if context != core.AvailableServerContexts.no_context: + try: + self._base_service.initialize_with_context(context) + self._context = context + except errors.DpfVersionNotSupported: + pass + else: self._context = context - except errors.DpfVersionNotSupported: - pass self.set_as_global(as_global=as_global) def _create_shutdown_funcs(self): From 628d18015392866dfc2ec6f8463ccc6552f4eea1 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Thu, 13 Jun 2024 11:51:44 +0200 Subject: [PATCH 05/12] Add a test Signed-off-by: paul.profizi --- tests/test_service.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_service.py b/tests/test_service.py index f3f62bd5d14..ca6e9556cec 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -481,6 +481,17 @@ def test_context_environment_variable(reset_context_environment_variable): continue +def test_server_without_context(remote_config_server_type): + """Tests starting a server without a no_context given.""" + server = dpf.core.start_local_server( + as_global=True, + config=remote_config_server_type, + context=dpf.core.AvailableServerContexts.no_context + ) + print(server.context) + assert server.context == dpf.core.AvailableServerContexts.no_context + + @pytest.mark.order("last") @pytest.mark.skipif( running_docker or not conftest.SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_5_0, From e1af3373f0c7e8fc7a5e25553fb0a6b9618c01a0 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Thu, 13 Jun 2024 12:06:14 +0200 Subject: [PATCH 06/12] Fix retro and case where SERVER_CONTEXT is indeed None (Docker) Signed-off-by: paul.profizi --- src/ansys/dpf/core/server_types.py | 57 ++++++++++++++++-------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/ansys/dpf/core/server_types.py b/src/ansys/dpf/core/server_types.py index 6883b015746..bc1088dc7ea 100644 --- a/src/ansys/dpf/core/server_types.py +++ b/src/ansys/dpf/core/server_types.py @@ -738,15 +738,16 @@ def __init__( self.live = True self._create_shutdown_funcs() self._check_first_call(num_connection_tryouts) - if context != core.AvailableServerContexts.no_context: - try: - self._base_service.initialize_with_context(context) + if context: + if context == core.AvailableServerContexts.no_context: + self._base_service.initialize() self._context = context - except errors.DpfVersionNotSupported: - pass - else: - self._base_service.initialize() - self._context = context + else: + try: + self._base_service.initialize_with_context(context) + self._context = context + except errors.DpfVersionNotSupported: + pass self.set_as_global(as_global=as_global) def _check_first_call(self, num_connection_tryouts): @@ -923,18 +924,19 @@ def __init__( f"Unable to locate the following file: {path}" ) raise e - if context != core.AvailableServerContexts.no_context: - try: - self.apply_context(context) - except errors.DpfVersionNotSupported: - self._base_service.initialize_with_context( - server_context.AvailableServerContexts.premium - ) - self._context = server_context.AvailableServerContexts.premium - pass - else: - self._base_service.initialize() - self._context = context + if context: + if context == core.AvailableServerContexts.no_context: + self._base_service.initialize() + self._context = context + else: + try: + self.apply_context(context) + except errors.DpfVersionNotSupported: + self._base_service.initialize_with_context( + server_context.AvailableServerContexts.premium + ) + self._context = server_context.AvailableServerContexts.premium + pass self.set_as_global(as_global=as_global) # Update the python os.environment if not os.name == "posix": @@ -1111,14 +1113,15 @@ def __init__( self._create_shutdown_funcs() check_ansys_grpc_dpf_version(self, timeout) - if context != core.AvailableServerContexts.no_context: - try: - self._base_service.initialize_with_context(context) + if context: + if context == core.AvailableServerContexts.no_context: self._context = context - except errors.DpfVersionNotSupported: - pass - else: - self._context = context + else: + try: + self._base_service.initialize_with_context(context) + self._context = context + except errors.DpfVersionNotSupported: + pass self.set_as_global(as_global=as_global) def _create_shutdown_funcs(self): From f7416dc2181d2f11bced5539234449c249568583 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Thu, 13 Jun 2024 15:07:18 +0200 Subject: [PATCH 07/12] Try fixing LicensingContextType.same_licensing_context for LicensingContextType.none Signed-off-by: paul.profizi --- src/ansys/dpf/core/server_context.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ansys/dpf/core/server_context.py b/src/ansys/dpf/core/server_context.py index e8c6d69cbcf..3379100c016 100644 --- a/src/ansys/dpf/core/server_context.py +++ b/src/ansys/dpf/core/server_context.py @@ -34,6 +34,9 @@ def __int__(self): @staticmethod def same_licensing_context(first, second): + if ((first == LicensingContextType.none and second != LicensingContextType.none) + or (first != LicensingContextType.none and second == LicensingContextType.none)): + return False if int(first) == int(LicensingContextType.entry) and int(second) != int( LicensingContextType.entry ): From ec55da3c47028786c0e6bb571c5f352167a8d435 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Thu, 13 Jun 2024 15:49:25 +0200 Subject: [PATCH 08/12] Fix test_server_without_context Signed-off-by: paul.profizi --- tests/test_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_service.py b/tests/test_service.py index ca6e9556cec..f9249fc18f7 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -484,7 +484,7 @@ def test_context_environment_variable(reset_context_environment_variable): def test_server_without_context(remote_config_server_type): """Tests starting a server without a no_context given.""" server = dpf.core.start_local_server( - as_global=True, + as_global=False, config=remote_config_server_type, context=dpf.core.AvailableServerContexts.no_context ) From d846ec44573aa7b16bfd9e259ddf8a8d4da7e99b Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Thu, 13 Jun 2024 16:18:11 +0200 Subject: [PATCH 09/12] Fix test_server_without_context Signed-off-by: paul.profizi --- tests/test_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_service.py b/tests/test_service.py index f9249fc18f7..a955410acd7 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -488,8 +488,8 @@ def test_server_without_context(remote_config_server_type): config=remote_config_server_type, context=dpf.core.AvailableServerContexts.no_context ) - print(server.context) - assert server.context == dpf.core.AvailableServerContexts.no_context + none_type = dpf.core.AvailableServerContexts.no_context.licensing_context_type + assert server.context.licensing_context_type == none_type @pytest.mark.order("last") From 51e9842617ad41c4c9d68ac87903d0f6b77623d4 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Fri, 14 Jun 2024 10:45:31 +0200 Subject: [PATCH 10/12] Initialize on client if server has client Signed-off-by: paul.profizi --- src/ansys/dpf/core/core.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ansys/dpf/core/core.py b/src/ansys/dpf/core/core.py index f23c6f629e7..639e9a4d298 100644 --- a/src/ansys/dpf/core/core.py +++ b/src/ansys/dpf/core/core.py @@ -501,7 +501,12 @@ def initialize_with_context(self, context): def initialize(self): """Initialize a DPF server without a context.""" - self._api.data_processing_initialization() + if self._server().has_client(): + self._api.data_processing_initialization_on_client( + self._server().client + ) + else: + self._api.data_processing_initialization() @version_requires("6.0") def release_dpf(self): From dcf67f75f24e50d1518e3bafa298ae3b36504479 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Fri, 14 Jun 2024 13:41:48 +0200 Subject: [PATCH 11/12] Skip test <232 Signed-off-by: paul.profizi --- tests/test_service.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_service.py b/tests/test_service.py index a955410acd7..fad0f5eeae2 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -481,6 +481,7 @@ def test_context_environment_variable(reset_context_environment_variable): continue +@pytest.mark.skipif(not conftest.SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_6_0) def test_server_without_context(remote_config_server_type): """Tests starting a server without a no_context given.""" server = dpf.core.start_local_server( From b0f140692ebf09be14c75a9f040f786a259aa8c1 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Fri, 14 Jun 2024 13:52:50 +0200 Subject: [PATCH 12/12] Skip test <232 Signed-off-by: paul.profizi --- tests/test_service.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_service.py b/tests/test_service.py index fad0f5eeae2..cc2bd4591cd 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -481,7 +481,10 @@ def test_context_environment_variable(reset_context_environment_variable): continue -@pytest.mark.skipif(not conftest.SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_6_0) +@pytest.mark.skipif( + not conftest.SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_6_0, + reason="Failures on Windows 231" +) def test_server_without_context(remote_config_server_type): """Tests starting a server without a no_context given.""" server = dpf.core.start_local_server(