diff --git a/guardrails/cli/configure.py b/guardrails/cli/configure.py index c1acd612b..f1b9a8d08 100644 --- a/guardrails/cli/configure.py +++ b/guardrails/cli/configure.py @@ -12,7 +12,7 @@ from guardrails.cli.hub.console import console from guardrails.cli.server.hub_client import AuthenticationError, get_auth from guardrails.cli.telemetry import trace_if_enabled - +from guardrails.cli.version import version_warnings_if_applicable DEFAULT_TOKEN = "" DEFAULT_ENABLE_METRICS = True @@ -78,6 +78,7 @@ def configure( help="Clear the existing token from the configuration file.", ), ): + version_warnings_if_applicable(console) trace_if_enabled("configure") existing_token = _get_default_token() last4 = existing_token[-4:] if existing_token else "" diff --git a/guardrails/cli/hub/install.py b/guardrails/cli/hub/install.py index 641bd2397..844b05a87 100644 --- a/guardrails/cli/hub/install.py +++ b/guardrails/cli/hub/install.py @@ -5,7 +5,9 @@ from guardrails.cli.hub.hub import hub_command from guardrails.cli.logger import logger +from guardrails.cli.hub.console import console from guardrails.cli.telemetry import trace_if_enabled +from guardrails.cli.version import version_warnings_if_applicable @hub_command.command() @@ -40,6 +42,8 @@ def confirm(): " local models for local inference?", ) + version_warnings_if_applicable(console) + install_multiple( package_uris, install_local_models=local_models, diff --git a/guardrails/cli/start.py b/guardrails/cli/start.py index 21183b835..d29bbf03d 100644 --- a/guardrails/cli/start.py +++ b/guardrails/cli/start.py @@ -5,6 +5,8 @@ from guardrails.cli.hub.utils import pip_process from guardrails.cli.logger import logger from guardrails.cli.telemetry import trace_if_enabled +from guardrails.cli.version import version_warnings_if_applicable +from guardrails.cli.hub.console import console def api_is_installed() -> bool: @@ -39,5 +41,6 @@ def start( from guardrails_api.cli.start import start # type: ignore logger.info("Starting Guardrails server") + version_warnings_if_applicable(console) trace_if_enabled("start") start(env, config, port) diff --git a/guardrails/cli/version.py b/guardrails/cli/version.py new file mode 100644 index 000000000..f82f3793f --- /dev/null +++ b/guardrails/cli/version.py @@ -0,0 +1,31 @@ +import contextlib +import requests +import semver +from importlib.metadata import version +from rich.console import Console + + +GUARDRAILS_PACKAGE_NAME = "guardrails-ai" + + +def get_guardrails_version(): + return version(GUARDRAILS_PACKAGE_NAME) + + +def version_warnings_if_applicable(console: Console): + current_version = get_guardrails_version() + + with contextlib.suppress(Exception): + res = requests.get(f"https://pypi.org/pypi/{GUARDRAILS_PACKAGE_NAME}/json") + version_info = res.json() + info = version_info.get("info", {}) + latest_version = info.get("version") + + is_update_available = semver.compare(latest_version, current_version) > 0 + + if is_update_available: + console.print( + "[yellow]There is a newer version of Guardrails " + f"available {latest_version}. Your current version " + f"is {current_version}[/yellow]!" + ) diff --git a/poetry.lock b/poetry.lock index 24b48dec6..4d5e43f7f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -6823,6 +6823,17 @@ files = [ cryptography = ">=2.0" jeepney = ">=0.6" +[[package]] +name = "semver" +version = "3.0.2" +description = "Python helper for Semantic Versioning (https://semver.org)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "semver-3.0.2-py3-none-any.whl", hash = "sha256:b1ea4686fe70b981f85359eda33199d60c53964284e0cfb4977d243e37cf4bf4"}, + {file = "semver-3.0.2.tar.gz", hash = "sha256:6253adb39c70f6e51afed2fa7152bcd414c411286088fb4b9effb133885ab4cc"}, +] + [[package]] name = "send2trash" version = "1.8.3" @@ -8419,4 +8430,4 @@ vectordb = ["faiss-cpu", "numpy"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "6253610141bb5686330057ae658550f9257aabe83ee7b279b783a7f4418a26a6" +content-hash = "25d043e207ef2c57ecc4c4cb6fb288ecccea69cc1f2e7894f3c56e7919f17a43" diff --git a/pyproject.toml b/pyproject.toml index 7d0c1eb91..12c3cceef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,6 +61,7 @@ diff-match-patch = "^20230430" guardrails-api = ">=0.0.1" mlflow = {version = ">=2.0.1", optional = true} uvloop = {version = "^0.20.0", optional = true} +semver = "^3.0.2" [tool.poetry.extras] sql = ["sqlvalidator", "sqlalchemy", "sqlglot"]