diff --git a/guardrails/cli/hub/install.py b/guardrails/cli/hub/install.py index d6c990cb8..33f7be2e5 100644 --- a/guardrails/cli/hub/install.py +++ b/guardrails/cli/hub/install.py @@ -237,62 +237,67 @@ def install( package_uri: str = typer.Argument( help="URI to the package to install. Example: hub://guardrails/regex_match." ), + quiet: bool = typer.Option( + False, + "--quiet", + help="Run the command in quiet mode to reduce output verbosity.", + ), ): """Install a validator from the Hub.""" if not package_uri.startswith("hub://"): logger.error("Invalid URI!") sys.exit(1) - console.print(f"\nInstalling {package_uri}...\n") - logger.log( - level=LEVELS.get("SPAM"), # type: ignore - msg=f"Installing {package_uri}...", - ) + logger.log(level=5, msg=f"Installing {package_uri}...") + logger.info(f"\nInstalling {package_uri}...\n") # Validation module_name = package_uri.replace("hub://", "") # Prep - with console.status("Fetching manifest", spinner="bouncingBar"): + with console.status("Fetching manifest", spinner="bouncingBar") as status: + if not quiet: + status.update("Fetching manifest") module_manifest = get_validator_manifest(module_name) site_packages = get_site_packages_location() # Install - with console.status("Downloading dependencies", spinner="bouncingBar"): + with console.status("Downloading dependencies", spinner="bouncingBar") as status: + if not quiet: + status.update("Downloading dependencies") install_hub_module(module_manifest, site_packages) # Post-install - with console.status("Running post-install setup", spinner="bouncingBar"): + with console.status("Running post-install setup", spinner="bouncingBar") as status: + if not quiet: + status.update("Running post-install setup") run_post_install(module_manifest, site_packages) add_to_hub_inits(module_manifest, site_packages) - success_message_cli = Template( - """✅Successfully installed ${module_name}! - -[bold]Import validator:[/bold] -from guardrails.hub import ${export} - -[bold]Get more info:[/bold] -https://hub.guardrailsai.com/validator/${id} -""" - ).safe_substitute( - module_name=package_uri, - id=module_manifest.id, - export=module_manifest.exports[0], - ) - success_message_logger = Template( - """✅Successfully installed ${module_name}! - -Import validator: -from guardrails.hub import ${export} - -Get more info: -https://hub.guardrailsai.com/validator/${id} -""" - ).safe_substitute( - module_name=package_uri, - id=module_manifest.id, - export=module_manifest.exports[0], - ) - console.print(success_message_cli) # type: ignore - logger.log(level=LEVELS.get("SPAM"), msg=success_message_logger) # type: ignore + logger.info("Installation complete") + + if not quiet: + success_message_cli = Template( + "✅Successfully installed ${module_name}!\n\n" + "[bold]Import validator:[/bold]\n" + "from guardrails.hub import ${export}\n\n" + "[bold]Get more info:[/bold]\n" + "https://hub.guardrailsai.com/validator/${id}\n" + ).safe_substitute( + module_name=package_uri, + id=module_manifest.id, + export=module_manifest.exports[0], + ) + success_message_logger = Template( + "✅Successfully installed ${module_name}!\n\n" + "Import validator:\n" + "from guardrails.hub import ${export}\n\n" + "Get more info:\n" + "https://hub.guardrailsai.com/validator/${id}\n" + ).safe_substitute( + module_name=package_uri, + id=module_manifest.id, + export=module_manifest.exports[0], + ) + console.print(success_message_cli) # type: ignore + logger.log(level=LEVELS.get("SPAM"), msg=success_message_logger) # type: ignore diff --git a/tests/unit_tests/cli/hub/test_install.py b/tests/unit_tests/cli/hub/test_install.py index bf07e1847..fd7c55145 100644 --- a/tests/unit_tests/cli/hub/test_install.py +++ b/tests/unit_tests/cli/hub/test_install.py @@ -60,7 +60,7 @@ def test_happy_path(self, mocker): from guardrails.cli.hub.install import install - install("hub://guardrails/test-validator") + install("hub://guardrails/test-validator", quiet=False) log_calls = [ call(level=5, msg="Installing hub://guardrails/test-validator..."), @@ -706,3 +706,19 @@ def test_install_hub_module(mocker): call("install", "pydash>=7.0.6,<8.0.0"), ] mock_pip_process.assert_has_calls(pip_calls) + + def test_quiet_install(self, mocker): + mock_console_print = mocker.patch("guardrails.cli.hub.install.console.print") + + from guardrails.cli.hub.install import install + + install("hub://guardrails/test-validator", quiet=True) + + # Expect no output other than the mandatory lines + mock_console_print.assert_has_calls( + [ + call("Installing validator..."), + call("Installation complete"), + ] + ) + assert mock_console_print.call_count == 2