From 4f3f50bd28f216c31a27c963350ace02f0da80c2 Mon Sep 17 00:00:00 2001 From: Matt Drozt Date: Fri, 25 Aug 2023 09:11:00 -0700 Subject: [PATCH 1/4] Add a smart info target for info about current SS installation --- smartsim/_core/_cli/cli.py | 6 +++ smartsim/_core/_cli/info.py | 84 +++++++++++++++++++++++++++++++++++++ tests/test_cli.py | 5 +++ 3 files changed, 95 insertions(+) create mode 100644 smartsim/_core/_cli/info.py diff --git a/smartsim/_core/_cli/cli.py b/smartsim/_core/_cli/cli.py index c3128e3b8..ce2376c15 100644 --- a/smartsim/_core/_cli/cli.py +++ b/smartsim/_core/_cli/cli.py @@ -35,6 +35,7 @@ from smartsim._core._cli.clean import execute as clean_execute from smartsim._core._cli.clean import execute_all as clobber_execute from smartsim._core._cli.dbcli import execute as dbcli_execute +from smartsim._core._cli.info import execute as info_execute from smartsim._core._cli.site import execute as site_execute from smartsim._core._cli.validate import ( execute as validate_execute, @@ -117,6 +118,11 @@ def default_cli() -> SmartCli: validate_execute, validate_parser, ), + MenuItemConfig( + "info", + "Display information about the current SmartSim installation", + info_execute, + ), ] return SmartCli(menu) diff --git a/smartsim/_core/_cli/info.py b/smartsim/_core/_cli/info.py new file mode 100644 index 000000000..15740abf9 --- /dev/null +++ b/smartsim/_core/_cli/info.py @@ -0,0 +1,84 @@ +import argparse +import importlib.metadata +from smartsim._core._install.buildenv import BuildEnv as _BuildEnv +import smartsim._core._cli.utils as _utils +import smartsim._core.utils.helpers as _helpers +from tabulate import tabulate + +_MISSING_DEP = _helpers.colorize("Not Installed", "red") + + +def execute(_args: argparse.Namespace, /) -> int: + print("\nSmart Python Packages:") + print( + tabulate( + [ + ["SmartSim", _fmt_py_pkg_version("smartsim")], + ["SmartRedis", _fmt_py_pkg_version("smartredis")], + ], + headers=["Name", "Version"], + tablefmt="fancy_outline", + ), + end="\n\n", + ) + + print("Orchestrator Configuration:") + db_path = _utils.get_db_path() + db_table = [["Installed", _fmt_installed_db(db_path)]] + if db_path: + db_table.append(["Location", db_path]) + print(tabulate(db_table, tablefmt="fancy_outline"), end="\n\n") + + print("Redis AI Configuration:") + rai_path = _helpers.redis_install_base().parent / "redisai.so" + rai_table = [["Is Installed", _fmt_installed_redis_ai(rai_path)]] + if rai_path.is_file(): + rai_table.append(["Location", rai_path]) + print(tabulate(rai_table, tablefmt="fancy_outline"), end="\n\n") + + print("Machine Learning Backends:") + backends = _helpers.installed_redisai_backends() + print( + tabulate( + [ + [ + "Tensorflow", + _utils.color_bool("tensorflow" in backends), + _fmt_py_pkg_version("tensorflow"), + ], + [ + "Torch", + _utils.color_bool("torch" in backends), + _fmt_py_pkg_version("torch"), + ], + [ + "ONNX", + _utils.color_bool("onnxruntime" in backends), + _fmt_py_pkg_version("onnx"), + ], + ], + headers=["Name", "Backend Available", "Python Package"], + tablefmt="fancy_outline", + ), + end="\n\n", + ) + + +def _fmt_installed_db(db_path): + if db_path is None: + return _MISSING_DEP + db_name, _ = db_path.name.split("-", 1) + return _helpers.colorize(db_name.upper(), "green") + + +def _fmt_installed_redis_ai(rai_path): + if not rai_path.is_file(): + return _MISSING_DEP + return _helpers.colorize("Installed", "green") + + +def _fmt_py_pkg_version(pkg_name): + try: + return _helpers.colorize(_BuildEnv.get_py_package_version(pkg_name), "green") + except importlib.metadata.PackageNotFoundError: + return _MISSING_DEP diff --git a/tests/test_cli.py b/tests/test_cli.py index c4ea976c0..ee07bc853 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -339,6 +339,7 @@ def test_cli_default_cli(capsys): pytest.param("site", "site_execute", "mocked-site", id="ensure site action is executed"), pytest.param("clobber", "clobber_execute", "mocked-clobber", id="ensure clobber action is executed"), pytest.param("validate", "validate_execute", "mocked-validate", id="ensure validate action is executed"), + pytest.param("info", "info_execute", "mocked-validate", id="ensure info action is executed"), ] ) def test_cli_action(capsys, monkeypatch, command, mock_location, exp_output): @@ -434,6 +435,7 @@ def mock_execute(ns: argparse.Namespace): pytest.param("dbcli", "clean_execute", "helpful mocked-dbcli", "usage: smart dbcli", id="dbcli"), pytest.param("site", "clean_execute", "helpful mocked-site", "usage: smart site", id="site"), pytest.param("validate", "validate_execute", "helpful mocked-validate", "usage: smart validate", id="validate"), + pytest.param("info", "info_execute", "helpful mocked-validate", "usage: smart info", id="info"), ] ) def test_cli_help_support(capsys, @@ -472,6 +474,7 @@ def mock_execute(ns: argparse.Namespace): pytest.param("dbcli", "dbcli_execute", "verbose mocked-dbcli", id="dbcli"), pytest.param("site", "site_execute", "verbose mocked-site", id="site"), pytest.param("validate", "validate_execute", "verbose mocked-validate", id="validate"), + pytest.param("info", "info_execute", "verbose mocked-validate", id="validate"), ] ) def test_cli_invalid_optional_args(capsys, @@ -508,6 +511,8 @@ def mock_execute(ns: argparse.Namespace): pytest.param("clobber", id="clobber"), pytest.param("dbcli", id="dbcli"), pytest.param("site", id="site"), + pytest.param("validate", id="validate"), + pytest.param("info", id="info"), ] ) def test_cli_invalid_optional_args(capsys, command): From b4b96babbcf7ee5ed0d27a8065bc688b73ebeb0a Mon Sep 17 00:00:00 2001 From: Matt Drozt Date: Fri, 25 Aug 2023 12:24:21 -0700 Subject: [PATCH 2/4] add types --- smartsim/_core/_cli/info.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/smartsim/_core/_cli/info.py b/smartsim/_core/_cli/info.py index 15740abf9..fb285cfa6 100644 --- a/smartsim/_core/_cli/info.py +++ b/smartsim/_core/_cli/info.py @@ -1,14 +1,20 @@ -import argparse import importlib.metadata -from smartsim._core._install.buildenv import BuildEnv as _BuildEnv +import typing as t + +from tabulate import tabulate + import smartsim._core._cli.utils as _utils import smartsim._core.utils.helpers as _helpers -from tabulate import tabulate +from smartsim._core._install.buildenv import BuildEnv as _BuildEnv + +if t.TYPE_CHECKING: + import argparse + import pathlib _MISSING_DEP = _helpers.colorize("Not Installed", "red") -def execute(_args: argparse.Namespace, /) -> int: +def execute(_args: "argparse.Namespace", /) -> int: print("\nSmart Python Packages:") print( tabulate( @@ -26,14 +32,14 @@ def execute(_args: argparse.Namespace, /) -> int: db_path = _utils.get_db_path() db_table = [["Installed", _fmt_installed_db(db_path)]] if db_path: - db_table.append(["Location", db_path]) + db_table.append(["Location", str(db_path)]) print(tabulate(db_table, tablefmt="fancy_outline"), end="\n\n") print("Redis AI Configuration:") rai_path = _helpers.redis_install_base().parent / "redisai.so" rai_table = [["Is Installed", _fmt_installed_redis_ai(rai_path)]] if rai_path.is_file(): - rai_table.append(["Location", rai_path]) + rai_table.append(["Location", str(rai_path)]) print(tabulate(rai_table, tablefmt="fancy_outline"), end="\n\n") print("Machine Learning Backends:") @@ -62,22 +68,23 @@ def execute(_args: argparse.Namespace, /) -> int: ), end="\n\n", ) + return 0 -def _fmt_installed_db(db_path): +def _fmt_installed_db(db_path: "t.Optional[pathlib.Path]") -> str: if db_path is None: return _MISSING_DEP db_name, _ = db_path.name.split("-", 1) return _helpers.colorize(db_name.upper(), "green") -def _fmt_installed_redis_ai(rai_path): +def _fmt_installed_redis_ai(rai_path: "pathlib.Path") -> str: if not rai_path.is_file(): return _MISSING_DEP return _helpers.colorize("Installed", "green") -def _fmt_py_pkg_version(pkg_name): +def _fmt_py_pkg_version(pkg_name: str) -> str: try: return _helpers.colorize(_BuildEnv.get_py_package_version(pkg_name), "green") except importlib.metadata.PackageNotFoundError: From 1eeae72c918d46427413425c58507763048d89e1 Mon Sep 17 00:00:00 2001 From: Matt Drozt Date: Fri, 25 Aug 2023 12:43:15 -0700 Subject: [PATCH 3/4] make old pylint happy --- smartsim/_core/_cli/info.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/smartsim/_core/_cli/info.py b/smartsim/_core/_cli/info.py index fb285cfa6..d2b94f631 100644 --- a/smartsim/_core/_cli/info.py +++ b/smartsim/_core/_cli/info.py @@ -1,4 +1,6 @@ +import argparse import importlib.metadata +import pathlib import typing as t from tabulate import tabulate @@ -7,14 +9,10 @@ import smartsim._core.utils.helpers as _helpers from smartsim._core._install.buildenv import BuildEnv as _BuildEnv -if t.TYPE_CHECKING: - import argparse - import pathlib - _MISSING_DEP = _helpers.colorize("Not Installed", "red") -def execute(_args: "argparse.Namespace", /) -> int: +def execute(_args: argparse.Namespace, /) -> int: print("\nSmart Python Packages:") print( tabulate( @@ -71,14 +69,14 @@ def execute(_args: "argparse.Namespace", /) -> int: return 0 -def _fmt_installed_db(db_path: "t.Optional[pathlib.Path]") -> str: +def _fmt_installed_db(db_path: t.Optional[pathlib.Path]) -> str: if db_path is None: return _MISSING_DEP db_name, _ = db_path.name.split("-", 1) return _helpers.colorize(db_name.upper(), "green") -def _fmt_installed_redis_ai(rai_path: "pathlib.Path") -> str: +def _fmt_installed_redis_ai(rai_path: pathlib.Path) -> str: if not rai_path.is_file(): return _MISSING_DEP return _helpers.colorize("Installed", "green") From d1b21f2bd617e52af09e02faa15efdb77b8bc6cd Mon Sep 17 00:00:00 2001 From: Matt Drozt Date: Fri, 25 Aug 2023 12:53:33 -0700 Subject: [PATCH 4/4] Less redundant name --- smartsim/_core/_cli/info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartsim/_core/_cli/info.py b/smartsim/_core/_cli/info.py index d2b94f631..35ee9b9ec 100644 --- a/smartsim/_core/_cli/info.py +++ b/smartsim/_core/_cli/info.py @@ -35,7 +35,7 @@ def execute(_args: argparse.Namespace, /) -> int: print("Redis AI Configuration:") rai_path = _helpers.redis_install_base().parent / "redisai.so" - rai_table = [["Is Installed", _fmt_installed_redis_ai(rai_path)]] + rai_table = [["Status", _fmt_installed_redis_ai(rai_path)]] if rai_path.is_file(): rai_table.append(["Location", str(rai_path)]) print(tabulate(rai_table, tablefmt="fancy_outline"), end="\n\n")