From 94bb453ebed927f5b3ed67a718f8a188ff1e0ed1 Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Tue, 9 Apr 2024 11:53:50 -0500 Subject: [PATCH] Add dev_mode param to App() --- shiny/_app.py | 23 +++++++++++++++++------ shiny/html_dependencies.py | 6 ++---- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/shiny/_app.py b/shiny/_app.py index fb8dd2f50..aa054e7d2 100644 --- a/shiny/_app.py +++ b/shiny/_app.py @@ -52,10 +52,9 @@ class App: ---------- ui The UI definition for the app (e.g., a call to :func:`~shiny.ui.page_fluid` or - similar, with layouts and controls nested inside). You can - also pass a function that takes a :class:`~starlette.requests.Request` and - returns a UI definition, if you need the UI definition to be created dynamically - for each pageview. + similar, with layouts and controls nested inside). You can also pass a function + that takes a :class:`~starlette.requests.Request` and returns a UI definition, + if you need the UI definition to be created dynamically for each pageview. server A function which is called once for each session, ensuring that each session is independent. @@ -66,6 +65,12 @@ class App: that mount point. debug Whether to enable debug mode. + dev_mode + Whether to enable development mode. This enables an error console in the client + which displays JavaScript errors. If ``None`` (the default), then the default is + to check if the environment variable ``SHINY_DEV_MODE`` is set to `"1"` and if + so, enable dev mode. If ``True`` or ``False``, then that value will be used and + the environment variable will be ignored. Examples -------- @@ -115,6 +120,7 @@ def __init__( *, static_assets: Optional[str | Path | Mapping[str, str | Path]] = None, debug: bool = False, + dev_mode: bool | None = None, ) -> None: # Used to store callbacks to be called when the app is shutting down (according # to the ASGI lifespan protocol) @@ -134,6 +140,9 @@ def __init__( ) self._debug: bool = debug + if dev_mode is None: + dev_mode = os.getenv("SHINY_DEV_MODE") == "1" + self._dev_mode: bool = dev_mode # Settings that the user can change after creating the App object. self.lib_prefix: str = LIB_PREFIX @@ -438,7 +447,9 @@ def _render_page(self, ui: Tag | TagList, lib_prefix: str) -> RenderedHTML: ui_res = copy.copy(ui) # Make sure requirejs, jQuery, and Shiny come before any other dependencies. # (see require_deps() for a comment about why we even include it) - ui_res.insert(0, [require_deps(), jquery_deps(), *shiny_deps()]) + ui_res.insert( + 0, [require_deps(), jquery_deps(), *shiny_deps(dev_mode=self._dev_mode)] + ) rendered = HTMLDocument(ui_res).render(lib_prefix=lib_prefix) self._ensure_web_dependencies(rendered["dependencies"]) return rendered @@ -449,7 +460,7 @@ def _render_page_from_file(self, file: Path, lib_prefix: str) -> RenderedHTML: doc = HTMLTextDocument( page_html, - deps=[require_deps(), jquery_deps(), *shiny_deps()], + deps=[require_deps(), jquery_deps(), *shiny_deps(dev_mode=self._dev_mode)], deps_replace_pattern='', ) diff --git a/shiny/html_dependencies.py b/shiny/html_dependencies.py index 4c0867932..48c327b1c 100644 --- a/shiny/html_dependencies.py +++ b/shiny/html_dependencies.py @@ -1,11 +1,9 @@ from __future__ import annotations -import os - from htmltools import HTMLDependency -def shiny_deps() -> list[HTMLDependency]: +def shiny_deps(dev_mode: bool = False) -> list[HTMLDependency]: deps = [ HTMLDependency( name="shiny", @@ -15,7 +13,7 @@ def shiny_deps() -> list[HTMLDependency]: stylesheet={"href": "shiny.min.css"}, ) ] - if os.getenv("SHINY_DEV_MODE") == "1": + if dev_mode: deps.append( HTMLDependency( "shiny-devmode",