Skip to content

Commit

Permalink
Create Simple Report of SmartSim Configuration (#350)
Browse files Browse the repository at this point in the history
Adds a `smart info` target to the `smart` CLI that to allow users
to view info about current SS installation, including smart python
package version, orchestrator type used, and which optional ML
dependencies are installed.

[ committed by @MattToast ]
[ reviewed by @al-rigazzi ]
  • Loading branch information
MattToast authored Aug 25, 2023
1 parent f0d510d commit 90ba36e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
6 changes: 6 additions & 0 deletions smartsim/_core/_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
89 changes: 89 additions & 0 deletions smartsim/_core/_cli/info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import argparse
import importlib.metadata
import pathlib
import typing as t

from tabulate import tabulate

import smartsim._core._cli.utils as _utils
import smartsim._core.utils.helpers as _helpers
from smartsim._core._install.buildenv import BuildEnv as _BuildEnv

_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", 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 = [["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")

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",
)
return 0


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:
if not rai_path.is_file():
return _MISSING_DEP
return _helpers.colorize("Installed", "green")


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:
return _MISSING_DEP
5 changes: 5 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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):
Expand Down

0 comments on commit 90ba36e

Please sign in to comment.