From 8da6441c87532d20d3c8dad538e46dc99d073927 Mon Sep 17 00:00:00 2001 From: Dmitrii Agibov Date: Tue, 13 Dec 2022 09:39:21 +0000 Subject: MLIA-460 Revisit backend management - Provide command for backend installation in case if backend is not available - Fix issue with connection timeout during downloading - Show installation tools output only in verbose mode Change-Id: Ic0e495ba19879cc2cda4fd0bce20b57ba896cfeb --- src/mlia/backend/errors.py | 12 ++++++++++ src/mlia/backend/tosa_checker/compat.py | 6 ++--- src/mlia/cli/main.py | 9 ++++++++ src/mlia/utils/download.py | 3 ++- src/mlia/utils/py_manager.py | 41 ++++++++++++++++++++++++--------- 5 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 src/mlia/backend/errors.py (limited to 'src') diff --git a/src/mlia/backend/errors.py b/src/mlia/backend/errors.py new file mode 100644 index 0000000..bd5da95 --- /dev/null +++ b/src/mlia/backend/errors.py @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates. +# SPDX-License-Identifier: Apache-2.0 +"""Backend errors.""" + + +class BackendUnavailableError(Exception): + """Backend unavailable error.""" + + def __init__(self, msg: str, backend: str) -> None: + """Init error.""" + super().__init__(msg) + self.backend = backend diff --git a/src/mlia/backend/tosa_checker/compat.py b/src/mlia/backend/tosa_checker/compat.py index e1bcb24..bd21774 100644 --- a/src/mlia/backend/tosa_checker/compat.py +++ b/src/mlia/backend/tosa_checker/compat.py @@ -8,6 +8,7 @@ from typing import Any from typing import cast from typing import Protocol +from mlia.backend.errors import BackendUnavailableError from mlia.core.typing import PathOrFileLike @@ -45,9 +46,8 @@ def get_tosa_compatibility_info( checker = get_tosa_checker(tflite_model_path) if checker is None: - raise Exception( - "TOSA checker is not available. " - "Please make sure that 'tosa-checker' backend is installed." + raise BackendUnavailableError( + "Backend tosa-checker is not available", "tosa-checker" ) ops = [ diff --git a/src/mlia/cli/main.py b/src/mlia/cli/main.py index 33a44e1..98fdb63 100644 --- a/src/mlia/cli/main.py +++ b/src/mlia/cli/main.py @@ -11,6 +11,7 @@ from inspect import signature from pathlib import Path from mlia import __version__ +from mlia.backend.errors import BackendUnavailableError from mlia.cli.commands import all_tests from mlia.cli.commands import backend_install from mlia.cli.commands import backend_list @@ -225,6 +226,14 @@ def run_command(args: argparse.Namespace) -> int: logger.error("Internal error: %s", err) except ConfigurationError as err: logger.error(err) + except BackendUnavailableError as err: + logger.error("Error: Backend %s is not available.", err.backend) + # apart from tosa-checker all other backends are currently optional + if err.backend in ("tosa-checker",): + logger.error( + 'Please use next command to install it: mlia-backend install "%s"', + err.backend, + ) except Exception as err: # pylint: disable=broad-except logger.error( "\nExecution finished with error: %s", diff --git a/src/mlia/utils/download.py b/src/mlia/utils/download.py index c8d0b69..e00be28 100644 --- a/src/mlia/utils/download.py +++ b/src/mlia/utils/download.py @@ -46,9 +46,10 @@ def download( show_progress: bool = False, label: str | None = None, chunk_size: int = 8192, + timeout: int = 30, ) -> None: """Download the file.""" - with requests.get(url, stream=True, timeout=10.0) as resp: + with requests.get(url, stream=True, timeout=timeout) as resp: resp.raise_for_status() content_chunks = resp.iter_content(chunk_size=chunk_size) diff --git a/src/mlia/utils/py_manager.py b/src/mlia/utils/py_manager.py index 5f98fcc..d7821d3 100644 --- a/src/mlia/utils/py_manager.py +++ b/src/mlia/utils/py_manager.py @@ -3,10 +3,16 @@ """Util functions for managing python packages.""" from __future__ import annotations +import logging +import subprocess # nosec import sys from importlib.metadata import distribution from importlib.metadata import PackageNotFoundError -from subprocess import check_call # nosec + +from mlia.core.errors import InternalError + + +logger = logging.getLogger(__name__) class PyPackageManager: @@ -45,16 +51,29 @@ class PyPackageManager: """Execute pip command.""" assert sys.executable, "Unable to launch pip command" - check_call( - [ - sys.executable, - "-m", - "pip", - "--disable-pip-version-check", - subcommand, - *params, - ] - ) + try: + output = subprocess.check_output( # nosec + [ + sys.executable, + "-m", + "pip", + "--disable-pip-version-check", + subcommand, + *params, + ], + stderr=subprocess.STDOUT, + text=True, + ) + returncode = 0 + except subprocess.CalledProcessError as err: + output = err.output + returncode = err.returncode + + for line in output.splitlines(): + logger.debug(line.rstrip()) + + if returncode != 0: + raise InternalError("Unable to install python package") def get_package_manager() -> PyPackageManager: -- cgit v1.2.1