From 2d7e0e9e92cd2055bb39f05ef0587a1aded93941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Jedlicska?= Date: Wed, 17 May 2023 18:47:54 +0200 Subject: [PATCH 1/3] feat(universal-installer): use pkg_resources to check for dependecies installed --- utils/installer.py | 66 ++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/utils/installer.py b/utils/installer.py index 9f22cc8f..fbfbc8fc 100644 --- a/utils/installer.py +++ b/utils/installer.py @@ -6,6 +6,7 @@ from pathlib import Path from typing import Optional from importlib import import_module, invalidate_caches +import pkg_resources _user_data_env_var = "SPECKLE_USERDATA_PATH" @@ -55,9 +56,7 @@ def user_application_data_path() -> Path: if sys.platform.startswith("win"): app_data_path = os.getenv("APPDATA") if not app_data_path: - raise Exception( - "Cannot get appdata path from environment." - ) + raise Exception("Cannot get appdata path from environment.") return Path(app_data_path) else: # try getting the standard XDG_DATA_HOME value @@ -68,9 +67,7 @@ def user_application_data_path() -> Path: else: return _ensure_folder_exists(Path.home(), ".config") except Exception as ex: - raise Exception( - "Failed to initialize user application data path.", ex - ) + raise Exception("Failed to initialize user application data path.", ex) def user_speckle_folder_path() -> Path: @@ -90,19 +87,16 @@ def user_speckle_connector_installation_path(host_application: str) -> Path: ) - - - - print("Starting module dependency installation") print(sys.executable) PYTHON_PATH = sys.executable - def connector_installation_path(host_application: str) -> Path: - connector_installation_path = user_speckle_connector_installation_path(host_application) + connector_installation_path = user_speckle_connector_installation_path( + host_application + ) connector_installation_path.mkdir(exist_ok=True, parents=True) # set user modules path at beginning of paths for earlier hit @@ -113,7 +107,6 @@ def connector_installation_path(host_application: str) -> Path: return connector_installation_path - def is_pip_available() -> bool: try: import_module("pip") # noqa F401 @@ -132,13 +125,15 @@ def ensure_pip() -> None: if completed_process.returncode == 0: print("Successfully installed pip") else: - raise Exception(f"Failed to install pip, got {completed_process.returncode} return code") + raise Exception( + f"Failed to install pip, got {completed_process.returncode} return code" + ) def get_requirements_path() -> Path: # we assume that a requirements.txt exists next to the __init__.py file - path = Path(Path(__file__).parent, "requirements.txt") - assert path.exists() + path = Path(__file__).parent.with_name("requirements.txt") + assert path.exists(), f"Can't find requirements file at {path}" return path @@ -179,29 +174,24 @@ def install_dependencies(host_application: str) -> None: install_requirements(host_application) -def _import_dependencies() -> None: - import_module("specklepy") - # the code above doesn't work for now, it fails on importing graphql-core - # despite that, the connector seams to be working as expected - # But it would be nice to make this solution work - # it would ensure that all dependencies are fully loaded - # requirements = get_requirements_path().read_text() - # reqs = [ - # req.split(" ; ")[0].split("==")[0].split("[")[0].replace("-", "_") - # for req in requirements.split("\n") - # if req and not req.startswith(" ") - # ] - # for req in reqs: - # print(req) - # import_module("specklepy") +def _dependencies_installed() -> bool: + try: + pkg_resources.require(get_requirements_path().read_text()) + return True + except (pkg_resources.DistributionNotFound, pkg_resources.VersionConflict): + return False + def ensure_dependencies(host_application: str) -> None: - try: - install_dependencies(host_application) - invalidate_caches() - _import_dependencies() - print("Successfully found dependencies") - except ImportError: - raise Exception(f"Cannot automatically ensure Speckle dependencies. Please try restarting the host application {host_application}!") + if _dependencies_installed(): + return + install_dependencies(host_application) + invalidate_caches() + if _dependencies_installed(): + print("Successfully found dependencies") + return + raise Exception( + f"Cannot automatically ensure Speckle dependencies. Please try restarting the host application {host_application}!" + ) From e98a80d45ab772d24b53428cfccae53f8c2bf147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Jedlicska?= Date: Wed, 17 May 2023 18:48:34 +0200 Subject: [PATCH 2/3] style(installer): fix style --- utils/installer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/installer.py b/utils/installer.py index fbfbc8fc..23c02486 100644 --- a/utils/installer.py +++ b/utils/installer.py @@ -3,9 +3,10 @@ """ import os import sys +from importlib import import_module, invalidate_caches from pathlib import Path from typing import Optional -from importlib import import_module, invalidate_caches + import pkg_resources _user_data_env_var = "SPECKLE_USERDATA_PATH" From 0330c6cf8308dd22374bfe846d01eb91a800e46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Jedlicska?= Date: Wed, 17 May 2023 18:50:45 +0200 Subject: [PATCH 3/3] style(installer): fix line length --- utils/installer.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/utils/installer.py b/utils/installer.py index 23c02486..c1236ec7 100644 --- a/utils/installer.py +++ b/utils/installer.py @@ -163,7 +163,10 @@ def install_requirements(host_application: str) -> None: ) if completed_process.returncode != 0: - m = f"Failed to install dependenices through pip, got {completed_process.returncode} return code" + m = ( + "Failed to install dependenices through pip, ", + f"got {completed_process.returncode} return code", + ) print(m) raise Exception(m) @@ -194,5 +197,6 @@ def ensure_dependencies(host_application: str) -> None: return raise Exception( - f"Cannot automatically ensure Speckle dependencies. Please try restarting the host application {host_application}!" + "Cannot automatically ensure Speckle dependencies. ", + f"Please try restarting the host application {host_application}!", )