diff --git a/doc/changelog.d/1162.miscellaneous.md b/doc/changelog.d/1162.miscellaneous.md new file mode 100644 index 0000000000..d053632209 --- /dev/null +++ b/doc/changelog.d/1162.miscellaneous.md @@ -0,0 +1 @@ +Fix: Improve code quality diff --git a/pyproject.toml b/pyproject.toml index 27681aab31..de687ed96e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ dependencies = [ "ansys-api-meshing-prime==0.1.4", + "docker>=7.1.0", # TODO: Discuss if this should be optional "numpy>=1.14.0", "appdirs>=1.4.0", "importlib-metadata>=4.0,<5; python_version<='3.8'", diff --git a/src/ansys/meshing/prime/core/dynaexportutils.py b/src/ansys/meshing/prime/core/dynaexportutils.py index 6af71133be..6b02da961a 100644 --- a/src/ansys/meshing/prime/core/dynaexportutils.py +++ b/src/ansys/meshing/prime/core/dynaexportutils.py @@ -2461,6 +2461,7 @@ def _get_zone_with_id(self, _id): zone_details = zone_details return zone_name, zone_details except: + self._logger.warning(f'Zone {zone} does not have id for it ') pass return None, {} diff --git a/src/ansys/meshing/prime/examples/download_utilities.py b/src/ansys/meshing/prime/examples/download_utilities.py index 6a023e0267..45dd433a79 100644 --- a/src/ansys/meshing/prime/examples/download_utilities.py +++ b/src/ansys/meshing/prime/examples/download_utilities.py @@ -24,7 +24,7 @@ import urllib.request from threading import Lock from typing import Optional -from urllib.parse import urljoin +from urllib.parse import urljoin, urlparse import ansys.meshing.prime.internals.defaults as defaults @@ -142,6 +142,10 @@ def _get_filepath_on_default_server(self, filename: str, *directory: str): return joiner(server, filename) def _retrieve_url(self, url, dest): + parsed = urlparse(url) + if parsed.scheme not in ('http', 'https'): + raise ValueError(f"Unsupported URL scheme: {parsed.scheme}") + saved_file, _ = urllib.request.urlretrieve(url, filename=dest) return saved_file diff --git a/src/ansys/meshing/prime/internals/client.py b/src/ansys/meshing/prime/internals/client.py index 3bd2284977..fa3347dad7 100644 --- a/src/ansys/meshing/prime/internals/client.py +++ b/src/ansys/meshing/prime/internals/client.py @@ -170,7 +170,8 @@ def exit(self): self._comm.close() self._comm = None if self._process is not None: - assert self._local == False + if self._local: + raise ValueError('Local client cannot have a server process') terminate_process(self._process) self._process = None diff --git a/src/ansys/meshing/prime/internals/grpc_communicator.py b/src/ansys/meshing/prime/internals/grpc_communicator.py index aa98c37a12..586d93012e 100644 --- a/src/ansys/meshing/prime/internals/grpc_communicator.py +++ b/src/ansys/meshing/prime/internals/grpc_communicator.py @@ -21,6 +21,7 @@ """Module for communications with the gRPC server.""" __all__ = ['GRPCCommunicator'] +import logging from typing import Optional import grpc @@ -33,6 +34,7 @@ from ansys.meshing.prime.core.model import Model from ansys.meshing.prime.internals.communicator import Communicator from ansys.meshing.prime.internals.error_handling import ( + PrimeRuntimeError, communicator_error_handler, error_code_handler, ) @@ -58,7 +60,8 @@ def get_response_messages(response_generator): if response.HasField('completion_token'): break - assert response.HasField('content') + if not response.HasField('content'): + raise PrimeRuntimeError('Bad response from server') yield response.content @@ -128,7 +131,7 @@ def __init__( except ConnectionError: raise except: - pass + logging.getLogger("PyPrimeMesh").error('Uncontrolled error, continuing execution') @error_code_handler @communicator_error_handler @@ -185,8 +188,6 @@ def serve(self, model: Model, command: str, *args, **kwargs) -> dict: ) message = get_response(response, '') if defaults.print_communicator_stats(): - import logging - logging.getLogger("PyPrimeMesh").info( f'Data Transfer: Received {len(message)} bytes' ) diff --git a/src/ansys/meshing/prime/internals/prime_communicator.py b/src/ansys/meshing/prime/internals/prime_communicator.py index 66e16ff1aa..a2dcf8fc05 100644 --- a/src/ansys/meshing/prime/internals/prime_communicator.py +++ b/src/ansys/meshing/prime/internals/prime_communicator.py @@ -117,11 +117,7 @@ def run_on_server(self, model, recipe: str) -> dict: dict Response from the server. """ - exec(recipe, globals()) - output = '{"Results" : "' + str(return_value) + '"}' - with config.numpy_array_optimization_disabled(): - result = json.loads(output) - return result + pass def close(self): """Close session.""" diff --git a/src/ansys/meshing/prime/internals/utils.py b/src/ansys/meshing/prime/internals/utils.py index a41ac4ee1c..98cf0a0837 100644 --- a/src/ansys/meshing/prime/internals/utils.py +++ b/src/ansys/meshing/prime/internals/utils.py @@ -30,8 +30,10 @@ import ansys.meshing.prime.internals.config as config import ansys.meshing.prime.internals.defaults as defaults +import docker _LOCAL_PORTS = [] +_DOCKER_CLIENT = docker.from_env() def make_unique_container_name(name: str): @@ -83,15 +85,13 @@ def get_child_processes(process): Process IDs of the processes. """ children = [] - cmd = subprocess.Popen("pgrep -P %d" % process, shell=True, stdout=subprocess.PIPE) + cmd = subprocess.Popen(['pgrep', '-P', str(process)], stdout=subprocess.PIPE) out = cmd.stdout.read().decode("utf-8") cmd.wait() for pid in out.split("\n")[:1]: if pid.strip() == '': break - ps_cmd = subprocess.Popen( - "ps -o cmd= {}".format(int(pid)), stdout=subprocess.PIPE, shell=True - ) + ps_cmd = subprocess.Popen(['ps', '-o', 'cmd=', str(int(pid))], stdout=subprocess.PIPE) ps_out = ps_cmd.stdout.read().decode("utf-8") ps_cmd.wait() cmd_name = ps_out.split()[0] @@ -238,42 +238,38 @@ def launch_prime_github_container( raise ValueError('Licensing information to launch container not found') if version is None: version = os.environ.get('PYPRIMEMESH_IMAGE_TAG', 'latest') - docker_command = [ - 'docker', - 'run', - '--shm-size=4g', - '-d', - '--rm', - '--name', - f'{name}', - '-p', - f'{port}:{port}', - '-v', - f'{mount_host}:{mount_image}', - '-e', - f'ANSYSLMD_LICENSE_FILE={license_file}', - ] - graphics_port = int(os.environ.get('PRIME_GRAPHICS_PORT', '0')) - if graphics_port > 0: - print(f'PyPrimeMesh: using Prime graphics port {graphics_port}') - docker_command += ['-p', f'{graphics_port}:{graphics_port}'] - prime_arguments = [ - f'{image_name}:{version}', - '--port', - f'{port}', - ] - subprocess.run(docker_command + prime_arguments, stdout=subprocess.DEVNULL) - - -def stop_prime_github_container(name): - """Stop a running container. + + ports = {f'{port}/tcp': port} + + volumes = {mount_host: {'bind': mount_image, 'mode': 'rw'}} + + environment = {'ANSYSLMD_LICENSE_FILE': license_file} + container = _DOCKER_CLIENT.containers.run( + image=f'{image_name}:{version}', + name=name, + detach=True, + shm_size='4g', + ports=ports, + volumes=volumes, + environment=environment, + remove=True, + command=['--port', str(port)], + ) + + +def stop_prime_github_container(container_name: str): + """Stop a container. Parameters ---------- - name : str - Name of the container. + container : str + Name of the container to stop. """ - subprocess.run(['docker', 'stop', f'{name}'], stdout=subprocess.DEVNULL) + try: + cont = _DOCKER_CLIENT.containers.get(container_name) + cont.stop() + except docker.errors.NotFound: + pass @contextmanager