From ced225879932ee73e1165ae868644da7c77b17a0 Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Wed, 20 Mar 2024 16:22:22 -0500 Subject: [PATCH 1/4] For Express, emit message if need to upgrade rsconnect-python --- shiny/_main.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/shiny/_main.py b/shiny/_main.py index bf61f6899..544fd671d 100644 --- a/shiny/_main.py +++ b/shiny/_main.py @@ -10,7 +10,7 @@ import sys import types from pathlib import Path -from typing import Any, Optional +from typing import Any, Literal, Optional import click import uvicorn @@ -288,6 +288,9 @@ def run_app( # is "shiny.express.app:_2f_path_2f_to_2f_app_2e_py". app = "shiny.express.app:" + escape_to_var_name(str(app_path)) app_dir = str(app_path.parent) + + # Express apps need min version of rsconnect-python to deploy correctly. + _verify_rsconnect_version() else: app, app_dir = resolve_app(app, app_dir) @@ -626,3 +629,47 @@ class ReloadArgs(TypedDict): reload_includes: NotRequired[list[str]] reload_excludes: NotRequired[list[str]] reload_dirs: NotRequired[list[str]] + + +# Check that the version of rsconnect supports Shiny Express; can be removed in the +# future once this version of rsconnect is widely used. (Added 2024-03) +def _verify_rsconnect_version() -> None: + PACKAGE_NAME = "rsconnect-python" + MIN_VERSION = "1.22.0" + + from importlib.metadata import PackageNotFoundError, version + + def _safe_int(x: str) -> int: + try: + return int(x) + except ValueError: + return 0 + + def _compare_package_versions(version1: str, version2: str) -> Literal[-1, 0, 1]: + parts1 = [_safe_int(x) for x in version1.split(".")] + parts2 = [_safe_int(x) for x in version2.split(".")] + + max_length = max(len(parts1), len(parts2)) + parts1 += [0] * (max_length - len(parts1)) + parts2 += [0] * (max_length - len(parts2)) + + for part1, part2 in zip(parts1, parts2): + if part1 > part2: + return 1 + elif part1 < part2: + return -1 + + return 0 + + try: + package_version = version(PACKAGE_NAME) + print(package_version) + if _compare_package_versions(package_version, MIN_VERSION) < 0: + print( + f"Warning: rsconnect-python {package_version} is installed, but it does not support deploying Shiny Express applications. " + f"Please upgrade to at least version {MIN_VERSION}. " + "If you are using pip, you can run `pip install --upgrade rsconnect-python`", + file=sys.stderr, + ) + except PackageNotFoundError: + pass From c8524d057e0f13954056f1a69a1a78bcb80a92fc Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Thu, 21 Mar 2024 16:25:50 -0500 Subject: [PATCH 2/4] Remove debugging code --- shiny/_main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/shiny/_main.py b/shiny/_main.py index 544fd671d..68da84e33 100644 --- a/shiny/_main.py +++ b/shiny/_main.py @@ -663,7 +663,6 @@ def _compare_package_versions(version1: str, version2: str) -> Literal[-1, 0, 1] try: package_version = version(PACKAGE_NAME) - print(package_version) if _compare_package_versions(package_version, MIN_VERSION) < 0: print( f"Warning: rsconnect-python {package_version} is installed, but it does not support deploying Shiny Express applications. " From 8664d93f4fcc839e2dd3101c46c32eee85694f63 Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Thu, 21 Mar 2024 16:35:56 -0500 Subject: [PATCH 3/4] Use packaging.version to compare versions --- setup.cfg | 1 + shiny/_main.py | 32 +++++++------------------------- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/setup.cfg b/setup.cfg index 617a42393..fc44c5531 100644 --- a/setup.cfg +++ b/setup.cfg @@ -48,6 +48,7 @@ install_requires = linkify-it-py>=1.0 appdirs>=1.4.4 asgiref>=3.5.2 + packaging>=20.9 watchfiles>=0.18.0;platform_system!="Emscripten" questionary>=2.0.0;platform_system!="Emscripten" # This is needed to address a DoS issue. In the future, when we are able to upgrade diff --git a/shiny/_main.py b/shiny/_main.py index 68da84e33..60987ada1 100644 --- a/shiny/_main.py +++ b/shiny/_main.py @@ -632,40 +632,22 @@ class ReloadArgs(TypedDict): # Check that the version of rsconnect supports Shiny Express; can be removed in the -# future once this version of rsconnect is widely used. (Added 2024-03) +# future once this version of rsconnect is widely used. The dependency on "packaging" +# can also be removed then, because it is only used here. (Added 2024-03) def _verify_rsconnect_version() -> None: PACKAGE_NAME = "rsconnect-python" MIN_VERSION = "1.22.0" from importlib.metadata import PackageNotFoundError, version - def _safe_int(x: str) -> int: - try: - return int(x) - except ValueError: - return 0 - - def _compare_package_versions(version1: str, version2: str) -> Literal[-1, 0, 1]: - parts1 = [_safe_int(x) for x in version1.split(".")] - parts2 = [_safe_int(x) for x in version2.split(".")] - - max_length = max(len(parts1), len(parts2)) - parts1 += [0] * (max_length - len(parts1)) - parts2 += [0] * (max_length - len(parts2)) - - for part1, part2 in zip(parts1, parts2): - if part1 > part2: - return 1 - elif part1 < part2: - return -1 - - return 0 + from packaging.version import parse try: - package_version = version(PACKAGE_NAME) - if _compare_package_versions(package_version, MIN_VERSION) < 0: + installed_version = parse(version(PACKAGE_NAME)) + required_version = parse(MIN_VERSION) + if installed_version < required_version: print( - f"Warning: rsconnect-python {package_version} is installed, but it does not support deploying Shiny Express applications. " + f"Warning: rsconnect-python {installed_version} is installed, but it does not support deploying Shiny Express applications. " f"Please upgrade to at least version {MIN_VERSION}. " "If you are using pip, you can run `pip install --upgrade rsconnect-python`", file=sys.stderr, From bfd72a59508ff908b8ec9db2b62a92058e6eb47b Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Thu, 21 Mar 2024 16:49:47 -0500 Subject: [PATCH 4/4] Remove unused import --- shiny/_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shiny/_main.py b/shiny/_main.py index 60987ada1..0e384e879 100644 --- a/shiny/_main.py +++ b/shiny/_main.py @@ -10,7 +10,7 @@ import sys import types from pathlib import Path -from typing import Any, Literal, Optional +from typing import Any, Optional import click import uvicorn