diff --git a/doc/changelog.d/1779.added.md b/doc/changelog.d/1779.added.md new file mode 100644 index 0000000000..fd655598a5 --- /dev/null +++ b/doc/changelog.d/1779.added.md @@ -0,0 +1 @@ +Streaming upload support \ No newline at end of file diff --git a/src/ansys/geometry/core/connection/__init__.py b/src/ansys/geometry/core/connection/__init__.py index f765a87a85..45bba0ae85 100644 --- a/src/ansys/geometry/core/connection/__init__.py +++ b/src/ansys/geometry/core/connection/__init__.py @@ -38,11 +38,7 @@ trimmed_curve_to_grpc_trimmed_curve, unit_vector_to_grpc_direction, ) -from ansys.geometry.core.connection.defaults import ( - DEFAULT_HOST, - DEFAULT_PORT, - GEOMETRY_SERVICE_DOCKER_IMAGE, -) +import ansys.geometry.core.connection.defaults as defaults from ansys.geometry.core.connection.docker_instance import ( GeometryContainers, LocalDockerInstance, diff --git a/src/ansys/geometry/core/connection/client.py b/src/ansys/geometry/core/connection/client.py index 6136a5c893..fc2ae7f5c7 100644 --- a/src/ansys/geometry/core/connection/client.py +++ b/src/ansys/geometry/core/connection/client.py @@ -54,7 +54,7 @@ ) from ansys.api.dbu.v0.admin_pb2_grpc import AdminStub from ansys.geometry.core.connection.backend import BackendType -from ansys.geometry.core.connection.defaults import DEFAULT_HOST, DEFAULT_PORT, MAX_MESSAGE_LENGTH +import ansys.geometry.core.connection.defaults as pygeom_defaults from ansys.geometry.core.connection.docker_instance import LocalDockerInstance from ansys.geometry.core.connection.product_instance import ProductInstance from ansys.geometry.core.logger import LOG, PyGeometryCustomAdapter @@ -158,8 +158,8 @@ class GrpcClient: @check_input_types def __init__( self, - host: str = DEFAULT_HOST, - port: str | int = DEFAULT_PORT, + host: str = pygeom_defaults.DEFAULT_HOST, + port: str | int = pygeom_defaults.DEFAULT_PORT, channel: grpc.Channel | None = None, remote_instance: Optional["Instance"] = None, docker_instance: LocalDockerInstance | None = None, @@ -183,8 +183,8 @@ def __init__( self._channel = grpc.insecure_channel( self._target, options=[ - ("grpc.max_receive_message_length", MAX_MESSAGE_LENGTH), - ("grpc.max_send_message_length", MAX_MESSAGE_LENGTH), + ("grpc.max_receive_message_length", pygeom_defaults.MAX_MESSAGE_LENGTH), + ("grpc.max_send_message_length", pygeom_defaults.MAX_MESSAGE_LENGTH), ], ) diff --git a/src/ansys/geometry/core/connection/docker_instance.py b/src/ansys/geometry/core/connection/docker_instance.py index 9011194086..07e53071c9 100644 --- a/src/ansys/geometry/core/connection/docker_instance.py +++ b/src/ansys/geometry/core/connection/docker_instance.py @@ -37,7 +37,7 @@ except ModuleNotFoundError: # pragma: no cover _HAS_DOCKER = False -from ansys.geometry.core.connection.defaults import DEFAULT_PORT, GEOMETRY_SERVICE_DOCKER_IMAGE +import ansys.geometry.core.connection.defaults as pygeom_defaults from ansys.geometry.core.logger import LOG @@ -157,7 +157,7 @@ def is_docker_installed() -> bool: @_docker_python_available def __init__( self, - port: int = DEFAULT_PORT, + port: int = pygeom_defaults.DEFAULT_PORT, connect_to_existing_service: bool = True, restart_if_existing_service: bool = False, name: str | None = None, @@ -234,7 +234,10 @@ def _is_cont_geom_service(self, cont: "Container") -> bool: # If one of the tags matches a Geometry service tag --> Return True for tag in cont.image.tags: for geom_services in GeometryContainers: - if tag == f"{GEOMETRY_SERVICE_DOCKER_IMAGE}:{geom_services.value[2]}": + if ( + tag + == f"{pygeom_defaults.GEOMETRY_SERVICE_DOCKER_IMAGE}:{geom_services.value[2]}" + ): return True # If you have reached this point, the image is not a Geometry service @@ -290,7 +293,7 @@ def _deploy_container(self, port: int, name: str | None, image: GeometryContaine # Try to deploy it try: container: Container = self.docker_client().containers.run( - image=f"{GEOMETRY_SERVICE_DOCKER_IMAGE}:{image.value[2]}", + image=f"{pygeom_defaults.GEOMETRY_SERVICE_DOCKER_IMAGE}:{image.value[2]}", detach=True, auto_remove=True, name=name, @@ -350,7 +353,7 @@ def get_geometry_container_type(instance: LocalDockerInstance) -> GeometryContai """ for tag in instance.container.image.tags: for geom_services in GeometryContainers: - if tag == f"{GEOMETRY_SERVICE_DOCKER_IMAGE}:{geom_services.value[2]}": + if tag == f"{pygeom_defaults.GEOMETRY_SERVICE_DOCKER_IMAGE}:{geom_services.value[2]}": return geom_services return None diff --git a/src/ansys/geometry/core/connection/launcher.py b/src/ansys/geometry/core/connection/launcher.py index ac1a841e33..81bd11c2a9 100644 --- a/src/ansys/geometry/core/connection/launcher.py +++ b/src/ansys/geometry/core/connection/launcher.py @@ -27,8 +27,7 @@ from typing import TYPE_CHECKING from ansys.geometry.core.connection.backend import ApiVersions, BackendType -from ansys.geometry.core.connection.client import MAX_MESSAGE_LENGTH -from ansys.geometry.core.connection.defaults import DEFAULT_PIM_CONFIG, DEFAULT_PORT +import ansys.geometry.core.connection.defaults as pygeom_defaults from ansys.geometry.core.connection.docker_instance import ( _HAS_DOCKER, GeometryContainers, @@ -290,7 +289,7 @@ def launch_remote_modeler( def launch_docker_modeler( - port: int = DEFAULT_PORT, + port: int = pygeom_defaults.DEFAULT_PORT, connect_to_existing_service: bool = True, restart_if_existing_service: bool = False, name: str | None = None, @@ -958,7 +957,7 @@ def _launch_pim_instance( # If PIM Light is being used and PyPIM configuration is not defined... use defaults. if is_pim_light and not os.environ.get("ANSYS_PLATFORM_INSTANCEMANAGEMENT_CONFIG", None): - os.environ["ANSYS_PLATFORM_INSTANCEMANAGEMENT_CONFIG"] = DEFAULT_PIM_CONFIG + os.environ["ANSYS_PLATFORM_INSTANCEMANAGEMENT_CONFIG"] = pygeom_defaults.DEFAULT_PIM_CONFIG pop_out = True else: pop_out = False @@ -969,7 +968,7 @@ def _launch_pim_instance( instance.wait_for_ready() channel = instance.build_grpc_channel( options=[ - ("grpc.max_receive_message_length", MAX_MESSAGE_LENGTH), + ("grpc.max_receive_message_length", pygeom_defaults.MAX_MESSAGE_LENGTH), ] ) diff --git a/src/ansys/geometry/core/designer/body.py b/src/ansys/geometry/core/designer/body.py index e6ac91cca8..ddd465a52a 100644 --- a/src/ansys/geometry/core/designer/body.py +++ b/src/ansys/geometry/core/designer/body.py @@ -36,6 +36,7 @@ BooleanRequest, CopyRequest, GetCollisionRequest, + GetTessellationRequest, MapRequest, MirrorRequest, RotateRequest, @@ -59,6 +60,7 @@ ShellRequest, ) from ansys.api.geometry.v0.commands_pb2_grpc import CommandsStub +from ansys.api.geometry.v0.models_pb2 import TessellationOptions as GRPCTessellationOptions from ansys.geometry.core.connection.client import GrpcClient from ansys.geometry.core.connection.conversions import ( frame_to_grpc_frame, @@ -96,6 +98,7 @@ min_backend_version, ) from ansys.geometry.core.misc.measurements import DEFAULT_UNITS, Angle, Distance +from ansys.geometry.core.misc.options import TessellationOptions from ansys.geometry.core.shapes.curves.trimmed_curve import TrimmedCurve from ansys.geometry.core.sketch.sketch import Sketch from ansys.geometry.core.typing import Real @@ -564,7 +567,9 @@ def copy(self, parent: "Component", name: str = None) -> "Body": return @abstractmethod - def tessellate(self, merge: bool = False) -> Union["PolyData", "MultiBlock"]: + def tessellate( + self, merge: bool = False, tessellation_options: TessellationOptions = None + ) -> Union["PolyData", "MultiBlock"]: """Tessellate the body and return the geometry as triangles. Parameters @@ -573,6 +578,8 @@ def tessellate(self, merge: bool = False) -> Union["PolyData", "MultiBlock"]: Whether to merge the body into a single mesh. When ``False`` (default), the number of triangles are preserved and only the topology is merged. When ``True``, the individual faces of the tessellation are merged. + tessellation_options : TessellationOptions, default: None + A set of options to determine the tessellation quality. Returns ------- @@ -1266,7 +1273,10 @@ def copy(self, parent: "Component", name: str = None) -> "Body": # noqa: D102 @protect_grpc @graphics_required def tessellate( # noqa: D102 - self, merge: bool = False, transform: Matrix44 = IDENTITY_MATRIX44 + self, + merge: bool = False, + transform: Matrix44 = IDENTITY_MATRIX44, + tess_options: TessellationOptions = None, ) -> Union["PolyData", "MultiBlock"]: # lazy import here to improve initial module load time import pyvista as pv @@ -1278,11 +1288,45 @@ def tessellate( # noqa: D102 # cache tessellation if not self._tessellation: - resp = self._bodies_stub.GetTessellation(self._grpc_id) - self._tessellation = { - str(face_id): tess_to_pd(face_tess) - for face_id, face_tess in resp.face_tessellation.items() - } + if tess_options is not None: + request = GetTessellationRequest( + id=self._grpc_id, + options=GRPCTessellationOptions( + surface_deviation=tess_options.surface_deviation, + angle_deviation=tess_options.angle_deviation, + maximum_aspect_ratio=tess_options.max_aspect_ratio, + maximum_edge_length=tess_options.max_edge_length, + watertight=tess_options.watertight, + ), + ) + try: + resp = self._bodies_stub.GetTessellationWithOptions(request) + self._tessellation = { + str(face_id): tess_to_pd(face_tess) + for face_id, face_tess in resp.face_tessellation.items() + } + except Exception: + tessellation_map = {} + for response in self._bodies_stub.GetTessellationStream(request): + for key, value in response.face_tessellation.items(): + tessellation_map[key] = tess_to_pd(value) + + self._tessellation = tessellation_map + else: + try: + resp = self._bodies_stub.GetTessellation(self._grpc_id) + self._tessellation = { + str(face_id): tess_to_pd(face_tess) + for face_id, face_tess in resp.face_tessellation.items() + } + except Exception: + tessellation_map = {} + request = GetTessellationRequest(self._grpc_id) + for response in self._bodies_stub.GetTessellationStream(request): + for key, value in response.face_tessellation.items(): + tessellation_map[key] = tess_to_pd(value) + + self._tessellation = tessellation_map pdata = [tess.transform(transform, inplace=False) for tess in self._tessellation.values()] comp = pv.MultiBlock(pdata) @@ -1810,9 +1854,11 @@ def copy(self, parent: "Component", name: str = None) -> "Body": # noqa: D102 @ensure_design_is_active def tessellate( # noqa: D102 - self, merge: bool = False + self, merge: bool = False, tess_options: TessellationOptions = None ) -> Union["PolyData", "MultiBlock"]: - return self._template.tessellate(merge, self.parent_component.get_world_transform()) + return self._template.tessellate( + merge, self.parent_component.get_world_transform(), tess_options + ) @ensure_design_is_active def shell_body(self, offset: Real) -> bool: # noqa: D102 diff --git a/src/ansys/geometry/core/designer/design.py b/src/ansys/geometry/core/designer/design.py index c7d054ac52..732394c77b 100644 --- a/src/ansys/geometry/core/designer/design.py +++ b/src/ansys/geometry/core/designer/design.py @@ -326,10 +326,7 @@ def download( file_location.write_bytes(received_bytes) self._grpc_client.log.debug(f"Design downloaded at location {file_location}.") - def __export_and_download_legacy( - self, - format: DesignFileFormat = DesignFileFormat.SCDOCX, - ) -> bytes: + def __export_and_download_legacy(self, format: DesignFileFormat) -> bytes: """Export and download the design from the server. Notes @@ -339,7 +336,7 @@ def __export_and_download_legacy( Parameters ---------- - format : DesignFileFormat, default: DesignFileFormat.SCDOCX + format : DesignFileFormat Format for the file to save to. Returns @@ -371,15 +368,12 @@ def __export_and_download_legacy( return received_bytes - def __export_and_download( - self, - format: DesignFileFormat = DesignFileFormat.SCDOCX, - ) -> bytes: + def __export_and_download(self, format: DesignFileFormat) -> bytes: """Export and download the design from the server. Parameters ---------- - format : DesignFileFormat, default: DesignFileFormat.SCDOCX + format : DesignFileFormat Format for the file to save to. Returns @@ -402,10 +396,23 @@ def __export_and_download( DesignFileFormat.SCDOCX, DesignFileFormat.STRIDE, ]: - response = self._design_stub.DownloadExportFile( - DownloadExportFileRequest(format=format.value[1]) - ) - received_bytes += response.data + try: + response = self._design_stub.DownloadExportFile( + DownloadExportFileRequest(format=format.value[1]) + ) + received_bytes += response.data + except Exception: + self._grpc_client.log.warning( + f"Failed to download the file in {format.value[0]} format." + " Attempting to stream download." + ) + # Attempt to download the file via streaming + received_bytes = bytes() + responses = self._design_stub.StreamDownloadExportFile( + DownloadExportFileRequest(format=format.value[1]) + ) + for response in responses: + received_bytes += response.data else: self._grpc_client.log.warning( f"{format.value[0]} format requested is not supported. Ignoring download request." diff --git a/src/ansys/geometry/core/misc/options.py b/src/ansys/geometry/core/misc/options.py index 0ef68c54cd..6cea43376d 100644 --- a/src/ansys/geometry/core/misc/options.py +++ b/src/ansys/geometry/core/misc/options.py @@ -23,6 +23,10 @@ from dataclasses import asdict, dataclass +from beartype import beartype as check_input_types + +from ansys.geometry.core.typing import Real + @dataclass class ImportOptions: @@ -57,3 +61,77 @@ class ImportOptions: def to_dict(self): """Provide the dictionary representation of the ImportOptions class.""" return {k: bool(v) for k, v in asdict(self).items()} + + +class TessellationOptions: + """Provides options for getting tessellation. + + Parameters + ---------- + surface_deviation : Real + The maximum deviation from the true surface position. + angle_deviation : Real + The maximum deviation from the true surface normal, in radians. + max_aspect_ratio : Real, default=0.0 + The maximum aspect ratio of facets. + max_edge_length : Real, default=0.0 + The maximum facet edge length. + watertight : bool, default=False + Whether triangles on opposite sides of an edge should match. + """ + + @check_input_types + def __init__( + self, + surface_deviation: Real, + angle_deviation: Real, + max_aspect_ratio: Real = 0.0, + max_edge_length: Real = 0.0, + watertight: bool = False, + ): + """Initialize ``TessellationOptions`` class.""" + self._surface_deviation = surface_deviation + self._angle_deviation = angle_deviation + self._max_aspect_ratio = max_aspect_ratio + self._max_edge_length = max_edge_length + self._watertight = watertight + + @property + def surface_deviation(self) -> Real: + """Surface Deviation. + + The maximum deviation from the true surface position. + """ + return self._surface_deviation + + @property + def angle_deviation(self) -> Real: + """Angle deviation. + + The maximum deviation from the true surface normal, in radians. + """ + return self._angle_deviation + + @property + def max_aspect_ratio(self) -> Real: + """Maximum aspect ratio. + + The maximum aspect ratio of facets. + """ + return self._max_aspect_ratio + + @property + def max_edge_length(self) -> Real: + """Maximum edge length. + + The maximum facet edge length. + """ + return self._max_edge_length + + @property + def watertight(self) -> bool: + """Watertight. + + Whether triangles on opposite sides of an edge should match. + """ + return self._watertight diff --git a/src/ansys/geometry/core/modeler.py b/src/ansys/geometry/core/modeler.py index 8aea87fed4..cb43014358 100644 --- a/src/ansys/geometry/core/modeler.py +++ b/src/ansys/geometry/core/modeler.py @@ -35,7 +35,7 @@ from ansys.api.geometry.v0.commands_pb2_grpc import CommandsStub from ansys.geometry.core.connection.backend import ApiVersions, BackendType from ansys.geometry.core.connection.client import GrpcClient -from ansys.geometry.core.connection.defaults import DEFAULT_HOST, DEFAULT_PORT +import ansys.geometry.core.connection.defaults as pygeom_defaults from ansys.geometry.core.errors import GeometryRuntimeError, protect_grpc from ansys.geometry.core.misc.checks import check_type, deprecated_method, min_backend_version from ansys.geometry.core.misc.options import ImportOptions @@ -92,8 +92,8 @@ class Modeler: def __init__( self, - host: str = DEFAULT_HOST, - port: str | int = DEFAULT_PORT, + host: str = pygeom_defaults.DEFAULT_HOST, + port: str | int = pygeom_defaults.DEFAULT_PORT, channel: Channel | None = None, remote_instance: Optional["Instance"] = None, docker_instance: Optional["LocalDockerInstance"] = None, @@ -256,6 +256,7 @@ def exit(self, close_design: bool = True) -> None: """ self.close(close_design=close_design) + @protect_grpc def _upload_file( self, file_path: str, @@ -310,6 +311,82 @@ def _upload_file( return response.file_path @protect_grpc + def _upload_file_stream( + self, + file_path: str, + open_file: bool = False, + import_options: ImportOptions = ImportOptions(), + ) -> str: + """Upload a file from the client to the server via streaming. + + Parameters + ---------- + file_path : str + Path of the file to upload. The extension of the file must be included. + open_file : bool, default: False + Whether to open the file in the Geometry service. + import_options : ImportOptions + Import options that toggle certain features when opening a file. + + Returns + ------- + file_path : str + Full path of the file uploaded to the server. + + Notes + ----- + This method creates a file on the server that has the same name and extension + as the file on the client. + """ + from pathlib import Path + + fp_path = Path(file_path).resolve() + + if not fp_path.exists(): + raise ValueError(f"Could not find file: {file_path}") + if fp_path.is_dir(): + raise ValueError("File path must lead to a file, not a directory.") + + c_stub = CommandsStub(self.client.channel) + + response = c_stub.StreamFileUpload( + self._generate_file_chunks(fp_path, open_file, import_options) + ) + return response.file_path + + def _generate_file_chunks( + self, file_path: Path, open_file: bool, import_options: ImportOptions + ): + """Generate appropriate chunk sizes for uploading files. + + Parameters + ---------- + file_path : Path + Path of the file to upload. The extension of the file must be included. + open_file : bool + Whether to open the file in the Geometry service. + import_options : ImportOptions + Import options that toggle certain features when opening a file. + + Returns + ------- + Chunked UploadFileRequest + + """ + msg_buffer = 5 * 1024 # 5KB - for additional message data + if pygeom_defaults.MAX_MESSAGE_LENGTH - msg_buffer < 0: # pragma: no cover + raise ValueError("MAX_MESSAGE_LENGTH is too small for file upload.") + + chunk_size = pygeom_defaults.MAX_MESSAGE_LENGTH - msg_buffer + with Path.open(file_path, "rb") as file: + while chunk := file.read(chunk_size): + yield UploadFileRequest( + data=chunk, + file_name=file_path.name, + open=open_file, + import_options=import_options.to_dict(), + ) + def open_file( self, file_path: str | Path, @@ -350,16 +427,23 @@ def open_file( # Format-specific logic - upload the whole containing folder for assemblies if upload_to_server: + fp_path = Path(file_path) + file_size_kb = fp_path.stat().st_size if any( ext in str(file_path) for ext in [".CATProduct", ".asm", ".solution", ".sldasm"] ): - fp_path = Path(file_path) dir = fp_path.parent for file in dir.iterdir(): full_path = file.resolve() if full_path != fp_path: - self._upload_file(full_path) - self._upload_file(file_path, True, import_options) + if full_path.stat().st_size < pygeom_defaults.MAX_MESSAGE_LENGTH: + self._upload_file(full_path) + else: + self._upload_file_stream(full_path) + if file_size_kb < pygeom_defaults.MAX_MESSAGE_LENGTH: + self._upload_file(file_path, True, import_options) + else: + self._upload_file_stream(file_path, True, import_options) else: DesignsStub(self.client.channel).Open( OpenRequest(filepath=file_path, import_options=import_options.to_dict()) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 6261cd0315..9e24cd9e53 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -51,7 +51,7 @@ from ansys.geometry.core import Modeler from ansys.geometry.core.connection.backend import BackendType -from ansys.geometry.core.connection.defaults import GEOMETRY_SERVICE_DOCKER_IMAGE +import ansys.geometry.core.connection.defaults as pygeom_defaults from ansys.geometry.core.connection.docker_instance import GeometryContainers, LocalDockerInstance IMPORT_FILES_DIR = Path(Path(__file__).parent, "files", "import") @@ -116,13 +116,15 @@ def docker_instance(use_existing_service): list_containers = [] for geom_service in GeometryContainers: if geom_service.value[1] == docker_os: - list_images.append(f"{GEOMETRY_SERVICE_DOCKER_IMAGE}:{geom_service.value[2]}") + list_images.append( + f"{pygeom_defaults.GEOMETRY_SERVICE_DOCKER_IMAGE}:{geom_service.value[2]}" + ) list_containers.append(geom_service) # Now, check 2) # available_images = LocalDockerInstance.docker_client().images.list( - name=GEOMETRY_SERVICE_DOCKER_IMAGE + name=pygeom_defaults.GEOMETRY_SERVICE_DOCKER_IMAGE ) for image in available_images: for geom_image, geom_cont in zip(list_images, list_containers): diff --git a/tests/integration/test_client.py b/tests/integration/test_client.py index 45fd3701d0..4753a94307 100644 --- a/tests/integration/test_client.py +++ b/tests/integration/test_client.py @@ -27,7 +27,8 @@ import pytest from ansys.geometry.core import Modeler -from ansys.geometry.core.connection import DEFAULT_HOST, DEFAULT_PORT, GrpcClient +from ansys.geometry.core.connection.client import GrpcClient +import ansys.geometry.core.connection.defaults as pygeom_defaults @pytest.fixture(scope="function") @@ -49,7 +50,7 @@ def test_client_init(client: GrpcClient): def test_client_through_channel(modeler: Modeler): """Test the instantiation of a client from a gRPC channel.""" - target = f"{DEFAULT_HOST}:{DEFAULT_PORT}" + target = f"{pygeom_defaults.DEFAULT_HOST}:{pygeom_defaults.DEFAULT_PORT}" channel = insecure_channel(target) client = GrpcClient(channel=channel) assert client.healthy is True diff --git a/tests/integration/test_design.py b/tests/integration/test_design.py index e32d032ea6..375127fd17 100644 --- a/tests/integration/test_design.py +++ b/tests/integration/test_design.py @@ -1081,6 +1081,34 @@ def test_upload_file(modeler: Modeler, tmp_path_factory: pytest.TempPathFactory) assert path_on_server is not None +def test_stream_upload_file(tmp_path_factory: pytest.TempPathFactory): + """Test uploading a file to the server.""" + # Define a new maximum message length + import ansys.geometry.core.connection.defaults as pygeom_defaults + + old_value = pygeom_defaults.MAX_MESSAGE_LENGTH + try: + # Set the new maximum message length + pygeom_defaults.MAX_MESSAGE_LENGTH = 1024**2 # 1 MB + + file = tmp_path_factory.mktemp("test_design") / "upload_stream_example.scdocx" + file_size = 5 * 1024**2 # stream five messages + + # Write random bytes + with file.open(mode="wb") as fout: + fout.write(os.urandom(file_size)) + assert file.exists() + + # Upload file - necessary to import the Modeler class and create an instance + from ansys.geometry.core import Modeler + + modeler = Modeler() + path_on_server = modeler._upload_file_stream(file) + assert path_on_server is not None + finally: + pygeom_defaults.MAX_MESSAGE_LENGTH = old_value + + def test_slot_extrusion(modeler: Modeler): """Test the extrusion of a slot.""" # Create your design on the server side diff --git a/tests/integration/test_launcher_remote.py b/tests/integration/test_launcher_remote.py index 349ec4a46a..9cfa3f3fb5 100644 --- a/tests/integration/test_launcher_remote.py +++ b/tests/integration/test_launcher_remote.py @@ -28,7 +28,7 @@ import pytest from ansys.geometry.core import Modeler -from ansys.geometry.core.connection.client import MAX_MESSAGE_LENGTH +import ansys.geometry.core.connection.defaults as pygeom_defaults from ansys.geometry.core.connection.docker_instance import LocalDockerInstance from ansys.geometry.core.connection.launcher import launch_modeler import ansys.tools.path.path as atpp @@ -60,7 +60,7 @@ def test_launch_remote_instance(monkeypatch, modeler: Modeler): pim_channel = insecure_channel( modeler.client._target, options=[ - ("grpc.max_receive_message_length", MAX_MESSAGE_LENGTH), + ("grpc.max_receive_message_length", pygeom_defaults.MAX_MESSAGE_LENGTH), ], ) mock_instance.wait_for_ready = create_autospec(mock_instance.wait_for_ready) @@ -90,7 +90,7 @@ def test_launch_remote_instance(monkeypatch, modeler: Modeler): assert mock_instance.wait_for_ready.called mock_instance.build_grpc_channel.assert_called_with( options=[ - ("grpc.max_receive_message_length", MAX_MESSAGE_LENGTH), + ("grpc.max_receive_message_length", pygeom_defaults.MAX_MESSAGE_LENGTH), ] )