From a587d280e4149b0c37981e86f32ffcf52031ac0f Mon Sep 17 00:00:00 2001 From: "Maarten A. Breddels" Date: Mon, 29 Jan 2024 15:32:18 +0100 Subject: [PATCH 1/4] fix: support altair in vscode and colab (and more) By setting SOLARA_ASSETS_PROXY=False, the JS assets will be fetched directly from the CDN, and not the proxy. This is the default setting for colab and vscode now, such that Altair works out of the box. --- solara/server/telemetry.py | 14 +++----------- solara/settings.py | 8 +++++++- solara/util.py | 13 +++++++++++++ solara/widgets/vue/vegalite.vue | 2 +- solara/widgets/widgets.py | 8 ++++++++ 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/solara/server/telemetry.py b/solara/server/telemetry.py index c69e059da..d553fa247 100644 --- a/solara/server/telemetry.py +++ b/solara/server/telemetry.py @@ -15,6 +15,7 @@ import requests import solara +import solara.util from . import settings @@ -44,15 +45,6 @@ _compute_platform = "unknown" -def is_running_in_colab(): - try: - import google.colab # noqa - - return True - except ImportError: - return False - - def is_running_on_domino(): return "DOMINO_PROJECT_OWNER" in os.environ @@ -65,7 +57,7 @@ def is_running_on_azure(): return "AZURE_NOTEBOOKS_VM" in os.environ or "AZUREML_RUN_ID" in os.environ -if is_running_in_colab(): +if solara.util.is_running_in_colab(): _compute_platform = "colab" elif is_running_on_domino(): _compute_platform = "domino" @@ -74,7 +66,7 @@ def is_running_on_azure(): elif is_running_on_azure(): _compute_platform = "azure" -_vscode = any(k for k in os.environ if k.upper().startswith("VSCODE_")) +_vscode = solara.util.is_running_in_vscode() try: path = "/proc/self/cgroup" diff --git a/solara/settings.py b/solara/settings.py index 98349bac6..49835df7b 100644 --- a/solara/settings.py +++ b/solara/settings.py @@ -1,6 +1,8 @@ import os from typing import Optional +import solara.util + from .minisettings import BaseSettings, Field from .util import get_solara_home @@ -36,9 +38,13 @@ class Config: env_file = ".env" +# in colab or vscode there is not solara cdn proxy available +_should_not_use_proxy = solara.util.is_running_in_colab() or solara.util.is_running_in_vscode() + + class Assets(BaseSettings): cdn: str = "https://cdn.jsdelivr.net/npm/" - proxy: bool = True + proxy: bool = not _should_not_use_proxy class Config: env_prefix = "solara_assets_" diff --git a/solara/util.py b/solara/util.py index bf2cbc097..bb1434b1e 100644 --- a/solara/util.py +++ b/solara/util.py @@ -267,3 +267,16 @@ def get_file_hash(path: Path, algorithm="md5") -> Tuple[bytes, str]: h = hashlib.new(algorithm, usedforsecurity=False) # type: ignore h.update(data) return data, h.hexdigest() + + +def is_running_in_colab(): + try: + import google.colab # noqa + + return True + except ImportError: + return False + + +def is_running_in_vscode(): + return "VSCODE_PID" in os.environ or "VSCODE_CWD" in os.environ diff --git a/solara/widgets/vue/vegalite.vue b/solara/widgets/vue/vegalite.vue index ad9f09a7d..87fa0c557 100644 --- a/solara/widgets/vue/vegalite.vue +++ b/solara/widgets/vue/vegalite.vue @@ -108,7 +108,7 @@ module.exports = { return base }, getCdn() { - return (typeof solara_cdn !== "undefined" && solara_cdn) || `${this.getBaseUrl()}_solara/cdn`; + return this.cdn || (typeof solara_cdn !== "undefined" && solara_cdn) || `${this.getBaseUrl()}_solara/cdn`; } }, } diff --git a/solara/widgets/widgets.py b/solara/widgets/widgets.py index b4e2533b3..1f6eeda37 100644 --- a/solara/widgets/widgets.py +++ b/solara/widgets/widgets.py @@ -20,6 +20,7 @@ class VegaLite(v.VuetifyTemplate): listen_to_hover = traitlets.Bool(False).tag(sync=True) on_click = traitlets.traitlets.Callable(None, allow_none=True) on_hover = traitlets.traitlets.Callable(None, allow_none=True) + cdn = traitlets.Unicode(None, allow_none=True).tag(sync=True) def vue_altair_click(self, *args): if self.on_click: @@ -29,6 +30,13 @@ def vue_altair_hover(self, *args): if self.on_hover: self.on_hover(*args) + @traitlets.default("cdn") + def _cdn(self): + import solara.settings + + if not solara.settings.assets.proxy: + return solara.settings.assets.cdn + class Navigator(v.VuetifyTemplate): template_file = os.path.realpath(os.path.join(os.path.dirname(__file__), "vue/navigator.vue")) From f035b5a34e4340cd159ac9d80e568050c68038e9 Mon Sep 17 00:00:00 2001 From: Maarten Breddels Date: Tue, 30 Jan 2024 09:45:22 +0100 Subject: [PATCH 2/4] Update solara/settings.py Co-authored-by: Iisakki Rotko --- solara/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solara/settings.py b/solara/settings.py index 49835df7b..6fd6a63a7 100644 --- a/solara/settings.py +++ b/solara/settings.py @@ -39,7 +39,7 @@ class Config: # in colab or vscode there is not solara cdn proxy available -_should_not_use_proxy = solara.util.is_running_in_colab() or solara.util.is_running_in_vscode() +_should_use_proxy = not (solara.util.is_running_in_colab() or solara.util.is_running_in_vscode()) class Assets(BaseSettings): From 19628ee9b11846e6ea4f8ff7c6b6053292099a42 Mon Sep 17 00:00:00 2001 From: Maarten Breddels Date: Tue, 30 Jan 2024 09:45:27 +0100 Subject: [PATCH 3/4] Update solara/settings.py Co-authored-by: Iisakki Rotko --- solara/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solara/settings.py b/solara/settings.py index 6fd6a63a7..af4f28098 100644 --- a/solara/settings.py +++ b/solara/settings.py @@ -44,7 +44,7 @@ class Config: class Assets(BaseSettings): cdn: str = "https://cdn.jsdelivr.net/npm/" - proxy: bool = not _should_not_use_proxy + proxy: bool = _should_use_proxy class Config: env_prefix = "solara_assets_" From 1eaa6be5fc3cd4761e9e5733e341bf3bf5fd1fd7 Mon Sep 17 00:00:00 2001 From: "Maarten A. Breddels" Date: Tue, 30 Jan 2024 09:55:05 +0100 Subject: [PATCH 4/4] fix: altair now works in voila Fixes #486 We now default to not using the CDN proxy when we detect we are running in voila. --- solara/settings.py | 2 +- solara/util.py | 4 ++++ tests/integration/cdn_test.py | 3 --- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/solara/settings.py b/solara/settings.py index af4f28098..36f3fbdc2 100644 --- a/solara/settings.py +++ b/solara/settings.py @@ -39,7 +39,7 @@ class Config: # in colab or vscode there is not solara cdn proxy available -_should_use_proxy = not (solara.util.is_running_in_colab() or solara.util.is_running_in_vscode()) +_should_use_proxy = not (solara.util.is_running_in_colab() or solara.util.is_running_in_vscode() or solara.util.is_running_in_voila()) class Assets(BaseSettings): diff --git a/solara/util.py b/solara/util.py index bb1434b1e..84f32c826 100644 --- a/solara/util.py +++ b/solara/util.py @@ -280,3 +280,7 @@ def is_running_in_colab(): def is_running_in_vscode(): return "VSCODE_PID" in os.environ or "VSCODE_CWD" in os.environ + + +def is_running_in_voila(): + return os.environ.get("SERVER_SOFTWARE", "").startswith("voila") diff --git a/tests/integration/cdn_test.py b/tests/integration/cdn_test.py index 2fa801753..a0a8dd1a6 100644 --- a/tests/integration/cdn_test.py +++ b/tests/integration/cdn_test.py @@ -10,9 +10,6 @@ def test_cdn_via_altair(ipywidgets_runner, page_session: playwright.sync_api.Page, request, assert_solara_snapshot): if request.node.callspec.params["ipywidgets_runner"] != "solara" and request.node.callspec.params["solara_server"] != SERVERS[0]: pytest.skip("No need to run this test for all servers.") - if request.node.callspec.params["ipywidgets_runner"] == "voila": - # see https://github.com/widgetti/solara/issues/486 - pytest.skip("Does not work with Voila.") # this function (or rather its lines) will be executed in the kernel # voila, lab, classic notebook and solara will all execute it