From 54e767767ced40dcd4a2695a463a16e17259162a Mon Sep 17 00:00:00 2001 From: Karan Acharya Date: Thu, 25 Apr 2024 18:35:22 -0700 Subject: [PATCH 1/7] Add functionality to toggle metrics without token/authentication + update gaurdrails configure output --- guardrails/cli/configure.py | 73 +++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/guardrails/cli/configure.py b/guardrails/cli/configure.py index d019410de..a3b7ef6a5 100644 --- a/guardrails/cli/configure.py +++ b/guardrails/cli/configure.py @@ -24,42 +24,85 @@ def save_configuration_file(token: str, no_metrics: bool) -> None: rc_file.close() +def get_existing_config() -> dict: + """Get the configuration from the file if it exists.""" + home = expanduser("~") + guardrails_rc = os.path.join(home, ".guardrailsrc") + config = {} + + # If the file exists + if os.path.exists(guardrails_rc): + with open(guardrails_rc, "r") as rc_file: + lines = rc_file.readlines() + for line in lines: + key, value = line.strip().split("=") + config[key] = value + return config + + @guardrails.command() def configure( token: Optional[str] = typer.Option( help="Your Guardrails Hub auth token.", hide_input=True, default="" ), no_metrics: Optional[str] = typer.Option( - help="Opt out of anonymous metrics collection.", default=False + help="Opt out of anonymous metrics collection.", default="" ), ): """Set the global configuration for the Guardrails CLI and Hub.""" + # Get the existing configuration if present + existing_config = get_existing_config() + + existing_token = existing_config.get("token", "") + existing_no_metrics = existing_config.get("no_metrics", "false") try: notice_message = """ You can find your token at https://hub.guardrailsai.com/tokens """ logger.log(level=LEVELS.get("NOTICE"), msg=notice_message) # type: ignore + + # Prompt for token if not provided if not token: - token = typer.prompt("Token", hide_input=True) - logger.info("Configuring...") - save_configuration_file(token, no_metrics) # type: ignore + token = typer.prompt( + "> Token", + default=existing_token, + hide_input=True, + ) - logger.info("Validating credentials...") - get_auth() - success_message = """ + # Prompt for no_metrics if not provided + if not no_metrics: + no_metrics = typer.prompt( + "> Disable anonymous metrics reporting?", + default=existing_no_metrics, + ) - Login successful. + # If token or no_metrics was updated, save the configuration + token_was_updated = token and token != existing_token + no_metrics_was_updated = no_metrics != existing_no_metrics + if token_was_updated or no_metrics_was_updated: + logger.info("Configuring...") + save_configuration_file(token, no_metrics) - Get started by installing our RegexMatch validator: - https://hub.guardrailsai.com/validator/guardrails_ai/regex_match + # Authenticate with the Hub if token was updated + if token_was_updated: + logger.info("Validating credentials...") + get_auth() + success_message = """ - You can install it by running: - guardrails hub install hub://guardrails/regex_match + Login successful. - Find more validators at https://hub.guardrailsai.com - """ - logger.log(level=LEVELS.get("SUCCESS"), msg=success_message) # type: ignore + Get started by installing our RegexMatch validator: + https://hub.guardrailsai.com/validator/guardrails_ai/regex_match + + You can install it by running: + guardrails hub install hub://guardrails/regex_match + + Find more validators at https://hub.guardrailsai.com + """ + logger.log(level=LEVELS.get("SUCCESS"), msg=success_message) # type: ignore` + else: + print("No token provided/Existing token found. Skipping authentication.") except AuthenticationError as auth_error: logger.error(auth_error) logger.error( From c6fde86df39e716925ba1f8d42c2198b660995ae Mon Sep 17 00:00:00 2001 From: Aarav Navani <38411399+oofmeister27@users.noreply.github.com> Date: Sun, 12 May 2024 01:46:54 -0700 Subject: [PATCH 2/7] update configure --- guardrails/cli/configure.py | 58 ++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/guardrails/cli/configure.py b/guardrails/cli/configure.py index a3b7ef6a5..88b46bd31 100644 --- a/guardrails/cli/configure.py +++ b/guardrails/cli/configure.py @@ -43,40 +43,49 @@ def get_existing_config() -> dict: @guardrails.command() def configure( token: Optional[str] = typer.Option( - help="Your Guardrails Hub auth token.", hide_input=True, default="" + None, + help="Your Guardrails Hub auth token.", + hide_input=True, + prompt="Token (optional) [None]", ), no_metrics: Optional[str] = typer.Option( - help="Opt out of anonymous metrics collection.", default="" + None, + help="Opt out of anonymous metrics collection.", + prompt="Disable anonymous metrics reporting? [Yes/No]", ), ): """Set the global configuration for the Guardrails CLI and Hub.""" # Get the existing configuration if present + + headless = token is not None or no_metrics is not None existing_config = get_existing_config() existing_token = existing_config.get("token", "") existing_no_metrics = existing_config.get("no_metrics", "false") - try: + + if not headless: notice_message = """ You can find your token at https://hub.guardrailsai.com/tokens """ logger.log(level=LEVELS.get("NOTICE"), msg=notice_message) # type: ignore - # Prompt for token if not provided - if not token: - token = typer.prompt( - "> Token", + # Prompt for token if not provided + if not token and not headless: + token = typer.prompt( + "> Token (optional) [None]", default=existing_token, hide_input=True, ) - # Prompt for no_metrics if not provided - if not no_metrics: - no_metrics = typer.prompt( - "> Disable anonymous metrics reporting?", - default=existing_no_metrics, - ) + # Prompt for no_metrics if not provided and not running headless + if no_metrics is None and not headless: + no_metrics = typer.prompt( + "> Disable anonymous metrics reporting?", + default=existing_no_metrics, + ) + try: # If token or no_metrics was updated, save the configuration token_was_updated = token and token != existing_token no_metrics_was_updated = no_metrics != existing_no_metrics @@ -84,25 +93,28 @@ def configure( logger.info("Configuring...") save_configuration_file(token, no_metrics) - # Authenticate with the Hub if token was updated + # Authenticate with the Hub if token was updated if token_was_updated: logger.info("Validating credentials...") get_auth() success_message = """ - Login successful. + Login successful. - Get started by installing our RegexMatch validator: - https://hub.guardrailsai.com/validator/guardrails_ai/regex_match + Get started by installing our RegexMatch validator: + https://hub.guardrailsai.com/validator/guardrails_ai/regex_match - You can install it by running: - guardrails hub install hub://guardrails/regex_match + You can install it by running: + guardrails hub install hub://guardrails/regex_match - Find more validators at https://hub.guardrailsai.com - """ + Find more validators at https://hub.guardrailsai.com + """ logger.log(level=LEVELS.get("SUCCESS"), msg=success_message) # type: ignore` - else: - print("No token provided/Existing token found. Skipping authentication.") + elif not token: + print("No token provided. Skipping authentication.") + + if not headless and not token_was_updated: + print("Existing token found. Skipping re-authentication.") except AuthenticationError as auth_error: logger.error(auth_error) logger.error( From 0df7de99365725142fe2a800b59f0749ff5ee8d0 Mon Sep 17 00:00:00 2001 From: Aarav Navani <38411399+oofmeister27@users.noreply.github.com> Date: Sun, 12 May 2024 19:22:15 -0700 Subject: [PATCH 3/7] lint fix --- guardrails/cli/configure.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/guardrails/cli/configure.py b/guardrails/cli/configure.py index 88b46bd31..f12f01f30 100644 --- a/guardrails/cli/configure.py +++ b/guardrails/cli/configure.py @@ -44,8 +44,8 @@ def get_existing_config() -> dict: def configure( token: Optional[str] = typer.Option( None, - help="Your Guardrails Hub auth token.", - hide_input=True, + help="Your Guardrails Hub auth token.", + hide_input=True, prompt="Token (optional) [None]", ), no_metrics: Optional[str] = typer.Option( @@ -63,7 +63,7 @@ def configure( existing_token = existing_config.get("token", "") existing_no_metrics = existing_config.get("no_metrics", "false") - if not headless: + if not headless: notice_message = """ You can find your token at https://hub.guardrailsai.com/tokens @@ -71,19 +71,19 @@ def configure( logger.log(level=LEVELS.get("NOTICE"), msg=notice_message) # type: ignore # Prompt for token if not provided - if not token and not headless: + if not token and not headless: token = typer.prompt( - "> Token (optional) [None]", - default=existing_token, - hide_input=True, - ) + "> Token (optional) [None]", + default=existing_token, + hide_input=True, + ) # Prompt for no_metrics if not provided and not running headless if no_metrics is None and not headless: no_metrics = typer.prompt( "> Disable anonymous metrics reporting?", default=existing_no_metrics, - ) + ) try: # If token or no_metrics was updated, save the configuration @@ -111,9 +111,9 @@ def configure( """ logger.log(level=LEVELS.get("SUCCESS"), msg=success_message) # type: ignore` elif not token: - print("No token provided. Skipping authentication.") - - if not headless and not token_was_updated: + print("No token provided. Skipping authentication.") + + if not headless and not token_was_updated: print("Existing token found. Skipping re-authentication.") except AuthenticationError as auth_error: logger.error(auth_error) From 8ccc2719bb5570ccd9d8cec03abfdb5065cb3f43 Mon Sep 17 00:00:00 2001 From: Aarav Navani <38411399+oofmeister27@users.noreply.github.com> Date: Sun, 12 May 2024 19:28:37 -0700 Subject: [PATCH 4/7] pytest --- guardrails/cli/configure.py | 79 +++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/guardrails/cli/configure.py b/guardrails/cli/configure.py index f12f01f30..205bba3fd 100644 --- a/guardrails/cli/configure.py +++ b/guardrails/cli/configure.py @@ -55,66 +55,61 @@ def configure( ), ): """Set the global configuration for the Guardrails CLI and Hub.""" - # Get the existing configuration if present - - headless = token is not None or no_metrics is not None existing_config = get_existing_config() - existing_token = existing_config.get("token", "") - existing_no_metrics = existing_config.get("no_metrics", "false") + # Normalize no_metrics to bool + input_no_metrics = no_metrics.lower() if no_metrics else None + if input_no_metrics == 'yes': + no_metrics_bool = True + elif input_no_metrics == 'no': + no_metrics_bool = False + else: + no_metrics_bool = bool(existing_config.get("no_metrics", "false") == "true") - if not headless: - notice_message = """ + # Default token to existing token if None provided + if token is None: + token = existing_config.get("token", "") - You can find your token at https://hub.guardrailsai.com/tokens - """ - logger.log(level=LEVELS.get("NOTICE"), msg=notice_message) # type: ignore + # Provide default logging level for NOTICE if not in LEVELS + notice_level = LEVELS.get("NOTICE", 20) # Assuming 20 is a reasonable default - # Prompt for token if not provided - if not token and not headless: - token = typer.prompt( - "> Token (optional) [None]", - default=existing_token, - hide_input=True, - ) - - # Prompt for no_metrics if not provided and not running headless - if no_metrics is None and not headless: - no_metrics = typer.prompt( - "> Disable anonymous metrics reporting?", - default=existing_no_metrics, - ) + if not token and not no_metrics: + notice_message = """ + You can find your token at https://hub.guardrailsai.com/tokens + """ + logger.log(level=notice_level, msg=notice_message) try: # If token or no_metrics was updated, save the configuration - token_was_updated = token and token != existing_token - no_metrics_was_updated = no_metrics != existing_no_metrics + token_was_updated = token and token != existing_config.get("token", "") + no_metrics_was_updated = no_metrics_bool != (existing_config.get("no_metrics", "false") == "true") + if token_was_updated or no_metrics_was_updated: logger.info("Configuring...") - save_configuration_file(token, no_metrics) + save_configuration_file(token, no_metrics_bool) # Authenticate with the Hub if token was updated - if token_was_updated: - logger.info("Validating credentials...") - get_auth() - success_message = """ - - Login successful. + if token_was_updated: + logger.info("Validating credentials...") + get_auth() + success_message = """ + Login successful. - Get started by installing our RegexMatch validator: - https://hub.guardrailsai.com/validator/guardrails_ai/regex_match + Get started by installing our RegexMatch validator: + https://hub.guardrailsai.com/validator/guardrails_ai/regex_match - You can install it by running: - guardrails hub install hub://guardrails/regex_match + You can install it by running: + guardrails hub install hub://guardrails/regex_match - Find more validators at https://hub.guardrailsai.com - """ - logger.log(level=LEVELS.get("SUCCESS"), msg=success_message) # type: ignore` + Find more validators at https://hub.guardrailsai.com + """ + logger.log(level=LEVELS.get("SUCCESS", 25), msg=success_message) # Assuming 25 is the SUCCESS level elif not token: print("No token provided. Skipping authentication.") - if not headless and not token_was_updated: - print("Existing token found. Skipping re-authentication.") + if not (token_was_updated or no_metrics_was_updated) and not (token and no_metrics): + print("Existing configuration found. Skipping re-authentication.") + except AuthenticationError as auth_error: logger.error(auth_error) logger.error( From 1356c621898998d1dfaf5e497add30220ff10c13 Mon Sep 17 00:00:00 2001 From: Aarav Navani <38411399+oofmeister27@users.noreply.github.com> Date: Sun, 12 May 2024 19:35:48 -0700 Subject: [PATCH 5/7] test --- guardrails/cli/configure.py | 88 +++++++++++++------------------------ 1 file changed, 30 insertions(+), 58 deletions(-) diff --git a/guardrails/cli/configure.py b/guardrails/cli/configure.py index 205bba3fd..8d01c7db4 100644 --- a/guardrails/cli/configure.py +++ b/guardrails/cli/configure.py @@ -58,71 +58,43 @@ def configure( existing_config = get_existing_config() # Normalize no_metrics to bool - input_no_metrics = no_metrics.lower() if no_metrics else None - if input_no_metrics == 'yes': - no_metrics_bool = True - elif input_no_metrics == 'no': - no_metrics_bool = False + if no_metrics is not None: + no_metrics_bool = no_metrics.lower() == 'yes' else: - no_metrics_bool = bool(existing_config.get("no_metrics", "false") == "true") + no_metrics_bool = existing_config.get("no_metrics", "false") == "true" - # Default token to existing token if None provided + # Fetch existing token if None provided if token is None: token = existing_config.get("token", "") - # Provide default logging level for NOTICE if not in LEVELS - notice_level = LEVELS.get("NOTICE", 20) # Assuming 20 is a reasonable default - - if not token and not no_metrics: - notice_message = """ - You can find your token at https://hub.guardrailsai.com/tokens - """ - logger.log(level=notice_level, msg=notice_message) - - try: - # If token or no_metrics was updated, save the configuration - token_was_updated = token and token != existing_config.get("token", "") - no_metrics_was_updated = no_metrics_bool != (existing_config.get("no_metrics", "false") == "true") - - if token_was_updated or no_metrics_was_updated: - logger.info("Configuring...") - save_configuration_file(token, no_metrics_bool) - - # Authenticate with the Hub if token was updated - if token_was_updated: - logger.info("Validating credentials...") - get_auth() - success_message = """ - Login successful. - - Get started by installing our RegexMatch validator: - https://hub.guardrailsai.com/validator/guardrails_ai/regex_match - - You can install it by running: - guardrails hub install hub://guardrails/regex_match - - Find more validators at https://hub.guardrailsai.com - """ - logger.log(level=LEVELS.get("SUCCESS", 25), msg=success_message) # Assuming 25 is the SUCCESS level - elif not token: - print("No token provided. Skipping authentication.") + # Only save configuration if both token and no_metrics are valid + if token and no_metrics is not None: + save_configuration_file(token, no_metrics_bool) + logger.info("Configuration saved.") - if not (token_was_updated or no_metrics_was_updated) and not (token and no_metrics): - print("Existing configuration found. Skipping re-authentication.") + # Authenticate with the Hub if token was updated + if token != existing_config.get("token", ""): + logger.info("Validating credentials...") + get_auth() + success_message = """ + Login successful. - except AuthenticationError as auth_error: - logger.error(auth_error) - logger.error( - """ - Check that your token is correct and try again. + Get started by installing our RegexMatch validator: + https://hub.guardrailsai.com/validator/guardrails_ai/regex_match - If you don't have your token credentials you can find them here: + You can install it by running: + guardrails hub install hub://guardrails/regex_match - https://hub.guardrailsai.com/tokens + Find more validators at https://hub.guardrailsai.com """ - ) - sys.exit(1) - except Exception as e: - logger.error("An unexpected error occurred!") - logger.error(e) - sys.exit(1) + logger.log(level=LEVELS.get("SUCCESS", 25), msg=success_message) # Assuming 25 is the SUCCESS level + + else: + if not token: + print("No token provided. Skipping authentication.") + if no_metrics is None: + print("No metrics preference provided. Skipping configuration update.") + + # Log an information message if neither token nor no_metrics provided + if not token and no_metrics is None: + logger.info("No updates to configuration required.") \ No newline at end of file From c50d617dc11b95ad9cdc478a4d1cee42efd7a929 Mon Sep 17 00:00:00 2001 From: Aarav Navani <38411399+oofmeister27@users.noreply.github.com> Date: Sun, 12 May 2024 20:21:01 -0700 Subject: [PATCH 6/7] test --- guardrails/cli/configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guardrails/cli/configure.py b/guardrails/cli/configure.py index 8d01c7db4..2f20dd535 100644 --- a/guardrails/cli/configure.py +++ b/guardrails/cli/configure.py @@ -75,7 +75,7 @@ def configure( # Authenticate with the Hub if token was updated if token != existing_config.get("token", ""): logger.info("Validating credentials...") - get_auth() + #get_auth() success_message = """ Login successful. From 47514ac561c7f6110bae58a35589016ab0f59bce Mon Sep 17 00:00:00 2001 From: Aarav Navani <38411399+oofmeister27@users.noreply.github.com> Date: Thu, 16 May 2024 23:30:57 -0700 Subject: [PATCH 7/7] lint --- guardrails/cli/configure.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/guardrails/cli/configure.py b/guardrails/cli/configure.py index 2f20dd535..58d803453 100644 --- a/guardrails/cli/configure.py +++ b/guardrails/cli/configure.py @@ -1,5 +1,4 @@ import os -import sys import uuid from os.path import expanduser from typing import Optional @@ -8,7 +7,6 @@ from guardrails.cli.guardrails import guardrails from guardrails.cli.logger import LEVELS, logger -from guardrails.cli.server.hub_client import AuthenticationError, get_auth def save_configuration_file(token: str, no_metrics: bool) -> None: @@ -59,7 +57,7 @@ def configure( # Normalize no_metrics to bool if no_metrics is not None: - no_metrics_bool = no_metrics.lower() == 'yes' + no_metrics_bool = no_metrics.lower() == "yes" else: no_metrics_bool = existing_config.get("no_metrics", "false") == "true" @@ -75,7 +73,7 @@ def configure( # Authenticate with the Hub if token was updated if token != existing_config.get("token", ""): logger.info("Validating credentials...") - #get_auth() + # get_auth() success_message = """ Login successful. @@ -87,7 +85,7 @@ def configure( Find more validators at https://hub.guardrailsai.com """ - logger.log(level=LEVELS.get("SUCCESS", 25), msg=success_message) # Assuming 25 is the SUCCESS level + logger.log(level=LEVELS.get("SUCCESS", 25), msg=success_message) else: if not token: @@ -97,4 +95,4 @@ def configure( # Log an information message if neither token nor no_metrics provided if not token and no_metrics is None: - logger.info("No updates to configuration required.") \ No newline at end of file + logger.info("No updates to configuration required.")