Skip to content

Commit 30ef70e

Browse files
Gordon Shotwellschloerke
andauthored
Kwargs to uvicorn run (#780)
Co-authored-by: Barret Schloerke <[email protected]>
1 parent fee9752 commit 30ef70e

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
## [UNRELEASED]
1010

1111
### New features
12-
12+
* `shiny run` now takes `reload-includes` and `reload-excludes` to allow you to define which files trigger a reload (#780).
13+
* `shiny.run` now passes keyword arguments to `uvicorn.run` (#780).
1314
* 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).
1415
* Added support for integration with Quarto (#746).
1516
* Added `shiny.render.renderer_components` decorator to help create new output renderers (#621).
@@ -59,6 +60,9 @@ Methods still under consideration in `shiny.experimental.ui`:
5960
* `card(wrapper=)`, `card_body()`, `card_image()`, `card_header()`
6061

6162

63+
### Bug fixes
64+
* `shiny run` now respects the user provided `reload-dir` argument (#765).
65+
6266
#### API removals
6367

6468
* `shiny.experimental.ui.FillingLayout` has been removed. (#481)
@@ -75,6 +79,9 @@ Methods still under consideration in `shiny.experimental.ui`:
7579

7680
### Other changes
7781

82+
### Breaking Changes
83+
* `shiny.run` only allows positional arguments for `app`, `host`, and `port`, all other arguments must be specified with keywords.
84+
7885

7986
## [0.5.1] - 2023-08-08
8087

shiny/_main.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def main() -> None:
3131
stop_shortcut = "Ctrl+C"
3232

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

3536

3637
@main.command(
@@ -95,6 +96,13 @@ def main() -> None:
9596
help="File glob(s) to indicate which files should be monitored for changes. Defaults"
9697
f' to "{",".join(RELOAD_INCLUDES_DEFAULT)}".',
9798
)
99+
@click.option(
100+
"--reload-excludes",
101+
"reload_excludes",
102+
default=",".join(RELOAD_EXCLUDES_DEFAULT),
103+
help="File glob(s) to indicate which files should be excluded from file monitoring. Defaults"
104+
f' to "{",".join(RELOAD_EXCLUDES_DEFAULT)}".',
105+
)
98106
@click.option(
99107
"--ws-max-size",
100108
type=int,
@@ -137,17 +145,21 @@ def run(
137145
app: str | shiny.App,
138146
host: str,
139147
port: int,
148+
*,
140149
autoreload_port: int,
141150
reload: bool,
142151
reload_dirs: tuple[str, ...],
143152
reload_includes: str,
153+
reload_excludes: str,
144154
ws_max_size: int,
145155
log_level: str,
146156
app_dir: str,
147157
factory: bool,
148158
launch_browser: bool,
159+
**kwargs: object,
149160
) -> None:
150161
reload_includes_list = reload_includes.split(",")
162+
reload_excludes_list = reload_excludes.split(",")
151163
return run_app(
152164
app,
153165
host=host,
@@ -156,27 +168,32 @@ def run(
156168
reload=reload,
157169
reload_dirs=list(reload_dirs),
158170
reload_includes=reload_includes_list,
171+
reload_excludes=reload_excludes_list,
159172
ws_max_size=ws_max_size,
160173
log_level=log_level,
161174
app_dir=app_dir,
162175
factory=factory,
163176
launch_browser=launch_browser,
177+
**kwargs,
164178
)
165179

166180

167181
def run_app(
168182
app: str | shiny.App = "app:app",
169183
host: str = "127.0.0.1",
170184
port: int = 8000,
185+
*,
171186
autoreload_port: int = 0,
172187
reload: bool = False,
173188
reload_dirs: Optional[list[str]] = None,
174189
reload_includes: list[str] | tuple[str, ...] = RELOAD_INCLUDES_DEFAULT,
190+
reload_excludes: list[str] | tuple[str, ...] = RELOAD_EXCLUDES_DEFAULT,
175191
ws_max_size: int = 16777216,
176192
log_level: Optional[str] = None,
177193
app_dir: Optional[str] = ".",
178194
factory: bool = False,
179195
launch_browser: bool = False,
196+
**kwargs: object,
180197
) -> None:
181198
"""
182199
Starts a Shiny app. Press ``Ctrl+C`` (or ``Ctrl+Break`` on Windows) to stop.
@@ -206,7 +223,10 @@ def run_app(
206223
will trigger app reloading.
207224
reload_includes
208225
List or tuple of file globs to indicate which files should be monitored for
209-
changes.
226+
changes. Can be combined with `reload_excludes`.
227+
reload_excludes
228+
List or tuple of file globs to indicate which files should be excluded from
229+
reload monitoring. Can be combined with `reload_includes`
210230
ws_max_size
211231
WebSocket max size message in bytes.
212232
log_level
@@ -217,6 +237,9 @@ def run_app(
217237
Treat ``app`` as an application factory, i.e. a () -> <ASGI app> callable.
218238
launch_browser
219239
Launch app browser after app starts, using the Python webbrowser module.
240+
**kwargs
241+
Additional keyword arguments which are passed to ``uvicorn.run``. For more
242+
information see [Uvicorn documentation](https://www.uvicorn.org/).
220243
221244
Tip
222245
---
@@ -261,10 +284,12 @@ def run_app(
261284

262285
if reload_dirs is None:
263286
reload_dirs = []
287+
if app_dir is not None:
288+
reload_dirs = [app_dir]
264289

265290
if reload:
266291
# Always watch the app_dir
267-
if app_dir:
292+
if app_dir and app_dir not in reload_dirs:
268293
reload_dirs.append(app_dir)
269294
# For developers of Shiny itself; autoreload the app when Shiny package changes
270295
if os.getenv("SHINY_PKG_AUTORELOAD"):
@@ -284,16 +309,12 @@ def run_app(
284309

285310
reload_args: ReloadArgs = {}
286311
if reload:
287-
reload_dirs = []
288-
if app_dir is not None:
289-
reload_dirs = [app_dir]
290-
291312
reload_args = {
292313
"reload": reload,
293314
# Adding `reload_includes` param while `reload=False` produces an warning
294315
# https://github.com/encode/uvicorn/blob/d43afed1cfa018a85c83094da8a2dd29f656d676/uvicorn/config.py#L298-L304
295316
"reload_includes": list(reload_includes),
296-
"reload_excludes": [".*", "*.py[cod]", "__pycache__", "env", "venv"],
317+
"reload_excludes": list(reload_excludes),
297318
"reload_dirs": reload_dirs,
298319
}
299320

@@ -312,6 +333,7 @@ def run_app(
312333
app_dir=app_dir,
313334
factory=factory,
314335
**reload_args,
336+
**kwargs,
315337
)
316338

317339

0 commit comments

Comments
 (0)