You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
help="Bind socket to this port. If 0, a random port will be used.",
58
57
show_default=True,
59
58
)
60
59
@click.option(
61
60
"--autoreload-port",
62
-
type=str,
63
-
default="+123",
64
-
help="Bind autoreload socket to this port number. If the value begins with + or -, it will be added to the value of --port. Ignored if --reload is not used.",
61
+
type=int,
62
+
default=0,
63
+
help="Bind autoreload socket to this port. If 0, a random port will be used. Ignored if --reload is not used.",
65
64
show_default=True,
66
65
)
67
66
@click.option(
@@ -97,17 +96,25 @@ def main() -> None:
97
96
help="Treat APP as an application factory, i.e. a () -> <ASGI app> callable.",
98
97
show_default=True,
99
98
)
99
+
@click.option(
100
+
"--launch-browser",
101
+
is_flag=True,
102
+
default=False,
103
+
help="Launch app browser after app starts, using the Python webbrowser module.",
104
+
show_default=True,
105
+
)
100
106
defrun(
101
107
app: Union[str, shiny.App],
102
108
host: str,
103
109
port: int,
104
-
autoreload_port: str,
110
+
autoreload_port: int,
105
111
debug: bool,
106
112
reload: bool,
107
113
ws_max_size: int,
108
114
log_level: str,
109
115
app_dir: str,
110
116
factory: bool,
117
+
launch_browser: bool,
111
118
) ->None:
112
119
returnrun_app(
113
120
app,
@@ -120,20 +127,22 @@ def run(
120
127
log_level=log_level,
121
128
app_dir=app_dir,
122
129
factory=factory,
130
+
launch_browser=launch_browser,
123
131
)
124
132
125
133
126
134
defrun_app(
127
135
app: Union[str, shiny.App] ="app:app",
128
136
host: str="127.0.0.1",
129
137
port: int=8000,
130
-
autoreload_port: str="",
138
+
autoreload_port: int=0,
131
139
debug: bool=False,
132
140
reload: bool=False,
133
141
ws_max_size: int=16777216,
134
142
log_level: Optional[str] =None,
135
143
app_dir: Optional[str] =".",
136
144
factory: bool=False,
145
+
launch_browser: bool=False,
137
146
) ->None:
138
147
"""
139
148
Starts a Shiny app. Press ``Ctrl+C`` (or ``Ctrl+Break`` on Windows) to stop.
@@ -152,7 +161,10 @@ def run_app(
152
161
host
153
162
The address that the app should listen on.
154
163
port
155
-
The port that the app should listen on.
164
+
The port that the app should listen on. Set to 0 to use a random port.
165
+
autoreload_port
166
+
The port that should be used for an additional websocket that is used to support
167
+
hot-reload. Set to 0 to use a random port.
156
168
debug
157
169
Enable debug mode.
158
170
reload
@@ -163,6 +175,10 @@ def run_app(
163
175
Log level.
164
176
app_dir
165
177
Look for ``app`` under this directory (by adding this to the ``PYTHONPATH``).
178
+
factory
179
+
Treat ``app`` as an application factory, i.e. a () -> <ASGI app> callable.
180
+
launch_browser
181
+
Launch app browser after app starts, using the Python webbrowser module.
166
182
167
183
Tip
168
184
---
@@ -189,6 +205,13 @@ def run_app(
189
205
run_app("myapp:my_app", app_dir="..")
190
206
"""
191
207
208
+
# If port is 0, randomize
209
+
ifport==0:
210
+
port=_utils.random_port(host=host)
211
+
212
+
os.environ["SHINY_HOST"] =host
213
+
os.environ["SHINY_PORT"] =str(port)
214
+
192
215
ifisinstance(app, str):
193
216
app, app_dir=resolve_app(app, app_dir)
194
217
@@ -202,25 +225,20 @@ def run_app(
202
225
else:
203
226
reload_dirs= []
204
227
205
-
ifreloadandautoreload_port!="":
206
-
m=re.search("^([+-]?)(\\d+)$", autoreload_port)
207
-
ifnotm:
208
-
sys.stderr.write(
209
-
"Error: Couldn't understand the provided value for --autoreload-port\n"
210
-
)
211
-
exit(1)
212
-
autoreload_port_num=int(m.group(2))
213
-
ifm.group(1) =="+":
214
-
autoreload_port_num+=port
215
-
elifm.group(1) =="-":
216
-
autoreload_port_num=port-autoreload_port_num
217
-
218
-
ifautoreload_port_num==port:
228
+
ifreload:
229
+
ifautoreload_port==0:
230
+
autoreload_port=_utils.random_port(host=host)
231
+
232
+
ifautoreload_port==port:
219
233
sys.stderr.write(
220
234
"Autoreload port is already being used by the app; disabling autoreload\n"
value. If it does not complete, then it will throw a `RuntimeError`.
164
213
165
214
What it means to be "in fact synchronous": the coroutine must not yield
166
-
control to the event loop. A coroutine may have an `await` expression in it,
167
-
and that may call another function that has an `await`, but the chain will
215
+
control to the event loop. A coroutine may have an `await` expression in it, and that may call another function that has an `await`, but the chain will
168
216
only yield control if a `yield` statement bubbles through `await`s all the
169
217
way up. For example, `await asyncio.sleep(0)` will have a `yield` which
170
218
bubbles up to the next level. Note that a `yield` in a generator used the
0 commit comments