Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [UNRELEASED]

### New features

* `shiny run` now takes `reload-includes` and `reload-excludes` to allow you to define which files trigger a reload.
* `shiny.run` now passes keyword arguments to `uvicorn.run`
* The `@output` decorator is no longer required for rendering functions; `@render.xxx` decorators now register themselves automatically. You can still use `@output` explicitly if you need to set specific output options (#747).
* Added support for integration with Quarto (#746).
* Added `shiny.render.renderer_components` decorator to help create new output renderers (#621).
Expand Down Expand Up @@ -59,6 +60,9 @@ Methods still under consideration in `shiny.experimental.ui`:
* `card(wrapper=)`, `card_body()`, `card_image()`, `card_header()`


### Bug fixes
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this section be combined with ### Bug fixes below?

* `shiny run` now respects the user provided `reload-dir` argument (#765)

#### API removals

* `shiny.experimental.ui.FillingLayout` has been removed. (#481)
Expand Down
36 changes: 29 additions & 7 deletions shiny/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def main() -> None:
stop_shortcut = "Ctrl+C"

RELOAD_INCLUDES_DEFAULT = ("*.py", "*.css", "*.js", "*.htm", "*.html", "*.png")
RELOAD_EXCLUDES_DEFAULT = (".*", "*.py[cod]", "__pycache__", "env", "venv")


@main.command(
Expand Down Expand Up @@ -95,6 +96,13 @@ def main() -> None:
help="File glob(s) to indicate which files should be monitored for changes. Defaults"
f' to "{",".join(RELOAD_INCLUDES_DEFAULT)}".',
)
@click.option(
"--reload-excludes",
"reload_excludes",
default=",".join(RELOAD_EXCLUDES_DEFAULT),
help="File glob(s) to indicate which files should be excluded from file monitoring. Defaults"
f' to "{",".join(RELOAD_EXCLUDES_DEFAULT)}".',
)
@click.option(
"--ws-max-size",
type=int,
Expand Down Expand Up @@ -137,17 +145,21 @@ def run(
app: str | shiny.App,
host: str,
port: int,
*,
autoreload_port: int,
reload: bool,
reload_dirs: tuple[str, ...],
reload_includes: str,
reload_excludes: str,
ws_max_size: int,
log_level: str,
app_dir: str,
factory: bool,
launch_browser: bool,
**kwargs: object,
) -> None:
reload_includes_list = reload_includes.split(",")
reload_excludes_list = reload_excludes.split(",")
return run_app(
app,
host=host,
Expand All @@ -156,27 +168,32 @@ def run(
reload=reload,
reload_dirs=list(reload_dirs),
reload_includes=reload_includes_list,
reload_excludes=reload_excludes_list,
ws_max_size=ws_max_size,
log_level=log_level,
app_dir=app_dir,
factory=factory,
launch_browser=launch_browser,
**kwargs,
)


def run_app(
app: str | shiny.App = "app:app",
host: str = "127.0.0.1",
port: int = 8000,
*,
autoreload_port: int = 0,
reload: bool = False,
reload_dirs: Optional[list[str]] = None,
reload_includes: list[str] | tuple[str, ...] = RELOAD_INCLUDES_DEFAULT,
reload_excludes: list[str] | tuple[str, ...] = RELOAD_EXCLUDES_DEFAULT,
ws_max_size: int = 16777216,
log_level: Optional[str] = None,
app_dir: Optional[str] = ".",
factory: bool = False,
launch_browser: bool = False,
**kwargs: object,
) -> None:
"""
Starts a Shiny app. Press ``Ctrl+C`` (or ``Ctrl+Break`` on Windows) to stop.
Expand Down Expand Up @@ -206,7 +223,10 @@ def run_app(
will trigger app reloading.
reload_includes
List or tuple of file globs to indicate which files should be monitored for
changes.
changes. Can be combined with `reload_excludes`.
reload_excludes
List or tuple of file globs to indicate which files should be excluded from
reload monitoring. Can be combined with `reload_includes`
ws_max_size
WebSocket max size message in bytes.
log_level
Expand All @@ -217,6 +237,9 @@ def run_app(
Treat ``app`` as an application factory, i.e. a () -> <ASGI app> callable.
launch_browser
Launch app browser after app starts, using the Python webbrowser module.
**kwargs
Additional keyword arguments which are passed to ``uvicorn.run``. For more
information see [Uvicorn documentation](https://www.uvicorn.org/).

Tip
---
Expand Down Expand Up @@ -261,10 +284,12 @@ def run_app(

if reload_dirs is None:
reload_dirs = []
if app_dir is not None:
reload_dirs = [app_dir]

if reload:
# Always watch the app_dir
if app_dir:
if app_dir and app_dir not in reload_dirs:
reload_dirs.append(app_dir)
Comment on lines +292 to 293
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

app_dir is added to reload_dirs above iff reload_dirs is its default value and app_dir is supplied.
So, we should remove this enhancement.

Suggested change
if app_dir and app_dir not in reload_dirs:
reload_dirs.append(app_dir)

# For developers of Shiny itself; autoreload the app when Shiny package changes
if os.getenv("SHINY_PKG_AUTORELOAD"):
Expand All @@ -284,16 +309,12 @@ def run_app(

reload_args: ReloadArgs = {}
if reload:
reload_dirs = []
if app_dir is not None:
reload_dirs = [app_dir]

reload_args = {
"reload": reload,
# Adding `reload_includes` param while `reload=False` produces an warning
# https://github.com/encode/uvicorn/blob/d43afed1cfa018a85c83094da8a2dd29f656d676/uvicorn/config.py#L298-L304
"reload_includes": list(reload_includes),
"reload_excludes": [".*", "*.py[cod]", "__pycache__", "env", "venv"],
"reload_excludes": list(reload_excludes),
"reload_dirs": reload_dirs,
}

Expand All @@ -312,6 +333,7 @@ def run_app(
app_dir=app_dir,
factory=factory,
**reload_args,
**kwargs,
)


Expand Down