Skip to content

Commit 82b11e7

Browse files
committed
Add --reload-dir command line option
1 parent a306257 commit 82b11e7

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### New features
1111

12+
* `shiny run` now takes zero or more `--reload-dir` arguments that can be used with `--reload` to indicate what directories should be (recursively) monitored for reload. If zero such arguments are passed, then the directory containing the app will be recursively monitored.
1213

1314
### Bug fixes
1415

shiny/_main.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import copy
22
import importlib
33
import importlib.util
4+
import inspect
45
import os
56
import shutil
67
import sys
78
import types
89
from pathlib import Path
9-
from typing import Any, Dict, Optional, Tuple, Union
10+
from typing import Any, Dict, List, Optional, Tuple, Union
1011

1112
import click
1213
import uvicorn
@@ -67,6 +68,14 @@ def main() -> None:
6768
"--debug", is_flag=True, default=False, help="Enable debug mode.", hidden=True
6869
)
6970
@click.option("--reload", is_flag=True, default=False, help="Enable auto-reload.")
71+
@click.option(
72+
"--reload-dir",
73+
"reload_dirs",
74+
multiple=True,
75+
help="Set reload directories explicitly, instead of using the current working"
76+
" directory.",
77+
type=click.Path(exists=True),
78+
)
7079
@click.option(
7180
"--ws-max-size",
7281
type=int,
@@ -110,6 +119,7 @@ def run(
110119
autoreload_port: int,
111120
debug: bool,
112121
reload: bool,
122+
reload_dirs: Tuple[str, ...],
113123
ws_max_size: int,
114124
log_level: str,
115125
app_dir: str,
@@ -123,6 +133,7 @@ def run(
123133
autoreload_port=autoreload_port,
124134
debug=debug,
125135
reload=reload,
136+
reload_dirs=list(reload_dirs),
126137
ws_max_size=ws_max_size,
127138
log_level=log_level,
128139
app_dir=app_dir,
@@ -138,6 +149,7 @@ def run_app(
138149
autoreload_port: int = 0,
139150
debug: bool = False,
140151
reload: bool = False,
152+
reload_dirs: Optional[List[str]] = None,
141153
ws_max_size: int = 16777216,
142154
log_level: Optional[str] = None,
143155
app_dir: Optional[str] = ".",
@@ -220,11 +232,16 @@ def run_app(
220232

221233
log_config: Dict[str, Any] = copy.deepcopy(uvicorn.config.LOGGING_CONFIG)
222234

223-
if reload and app_dir is not None:
224-
reload_dirs = [app_dir]
225-
else:
235+
if reload_dirs is None:
226236
reload_dirs = []
227237

238+
if reload and len(reload_dirs) == 0 and app_dir is not None:
239+
reload_dirs.append(app_dir)
240+
241+
if reload and os.getenv("SHINY_PKG_AUTORELOAD"):
242+
shinypath = Path(inspect.getfile(shiny)).parent
243+
reload_dirs.append(str(shinypath))
244+
228245
if reload:
229246
if autoreload_port == 0:
230247
autoreload_port = _utils.random_port(host=host)
@@ -242,6 +259,15 @@ def run_app(
242259

243260
maybe_setup_rsw_proxying(log_config)
244261

262+
if "WEB_CONCURRENCY" in os.environ:
263+
# WEB_CONCURRENCY is one way to set uvicorn's worker count; we don't support
264+
# this, let's make that perfectly clear.
265+
wc = os.environ["WEB_CONCURRENCY"]
266+
if wc != "1":
267+
sys.stderr.write(
268+
f"Ignoring WEB_CONCURRENCY value of {wc}. Shiny does not support gunicorn-style concurrency; instead, run multiple Shiny processes behind a load balancer that supports sticky sessions.\n"
269+
)
270+
245271
uvicorn.run( # pyright: ignore[reportUnknownMemberType]
246272
app, # pyright: ignore[reportGeneralTypeIssues]
247273
host=host,
@@ -254,6 +280,7 @@ def run_app(
254280
log_config=log_config,
255281
app_dir=app_dir,
256282
factory=factory,
283+
workers=1,
257284
)
258285

259286

0 commit comments

Comments
 (0)