Skip to content

Commit aaa9c6e

Browse files
updated annotations; make server async regardless of function passed in
1 parent 04bf6b8 commit aaa9c6e

File tree

3 files changed

+12
-14
lines changed

3 files changed

+12
-14
lines changed

shiny/_app.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from ._connection import Connection, StarletteConnection
3030
from ._error import ErrorMiddleware
3131
from ._shinyenv import is_pyodide
32-
from ._utils import guess_mime_type, is_async_callable, sort_keys_length
32+
from ._utils import guess_mime_type, is_async_callable, sort_keys_length, wrap_async
3333
from .html_dependencies import jquery_deps, require_deps, shiny_deps
3434
from .http_staticfiles import FileResponse, StaticFiles
3535
from .session._session import AppSession, Inputs, Outputs, Session, session_context
@@ -104,7 +104,7 @@ def server(input: Inputs, output: Outputs, session: Session):
104104
"""
105105

106106
ui: RenderedHTML | Callable[[Request], Tag | TagList]
107-
server: Callable[[Inputs, Outputs, Session], Awaitable[None] | None]
107+
server: Callable[[Inputs, Outputs, Session], Awaitable[None]]
108108

109109
def __init__(
110110
self,
@@ -123,13 +123,13 @@ def __init__(
123123
self._exit_stack = AsyncExitStack()
124124

125125
if server is None:
126-
self.server = noop_server_fn
126+
self.server = wrap_async(noop_server_fn)
127127
elif len(signature(server).parameters) == 1:
128128
self.server = wrap_server_fn_with_output_session(
129-
cast(Callable[[Inputs], None], server)
129+
wrap_async(cast(Callable[[Inputs], Awaitable[None] | None], server))
130130
)
131131
elif len(signature(server).parameters) == 3:
132-
self.server = cast(Callable[[Inputs, Outputs, Session], None], server)
132+
self.server = wrap_async(cast(Callable[[Inputs, Outputs, Session], Awaitable[None] | None], server))
133133
else:
134134
raise ValueError(
135135
"`server` must have 1 (Inputs) or 3 parameters (Inputs, Outputs, Session)"
@@ -522,10 +522,10 @@ def noop_server_fn(input: Inputs, output: Outputs, session: Session) -> None:
522522

523523

524524
def wrap_server_fn_with_output_session(
525-
server: Callable[[Inputs], None],
526-
) -> Callable[[Inputs, Outputs, Session], None]:
527-
def _server(input: Inputs, output: Outputs, session: Session):
525+
server: Callable[[Inputs], Awaitable[None]],
526+
) -> Callable[[Inputs, Outputs, Session], Awaitable[None]]:
527+
async def _server(input: Inputs, output: Outputs, session: Session):
528528
# Only has 1 parameter, ignore output, session
529-
server(input)
529+
await server(input)
530530

531531
return _server

shiny/_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,15 +262,15 @@ def private_seed() -> Generator[None, None, None]:
262262

263263

264264
def wrap_async(
265-
fn: Callable[P, R] | Callable[P, Awaitable[R]],
265+
fn: Callable[P, R] | Callable[P, Awaitable[R]] | Callable[P, Awaitable[R] | R],
266266
) -> Callable[P, Awaitable[R]]:
267267
"""
268268
Given a synchronous function that returns R, return an async function that wraps the
269269
original function. If the input function is already async, then return it unchanged.
270270
"""
271271

272272
if is_async_callable(fn):
273-
return fn
273+
return cast(Callable[P, Awaitable[R]], fn)
274274

275275
fn = cast(Callable[P, R], fn)
276276

shiny/session/_session.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -633,9 +633,7 @@ def verify_state(expected_state: ConnectionState) -> None:
633633
self._manage_inputs(message_obj["data"])
634634

635635
with session_context(self):
636-
result = self.app.server(self.input, self.output, self)
637-
if isinstance(result, Awaitable):
638-
await result
636+
await self.app.server(self.input, self.output, self)
639637

640638
elif message_obj["method"] == "update":
641639
verify_state(ConnectionState.Running)

0 commit comments

Comments
 (0)