from shiny.input_handler import input_handlers
@input_handlers.add("mypackage.intify")
def _(value, name, session):
return int(value)
Session
session.get_current_session
session.get_current_session()
Get the current user session.
Returns
Note
Shiny apps should not need to call this function directly. Instead, it is intended to be used by Shiny developers who wish to create new functions that should only be called from within an active Shiny session.
See Also
session.require_active_session
session.require_active_session(session)
Raise an exception if no Shiny session is currently active.
Parameters
session : Optional[Session]
-
A Session instance. If not provided, the session is inferred via get_current_session.
Returns
: Session
-
The session.
Note
Shiny apps should not need to call this function directly. Instead, it is intended to be used by Shiny developers who wish to create new functions that should only be called from within an active Shiny session.
Raises
: ValueError
-
If session is not active.
See Also
session.session_context
session.session_context(session)
A context manager for current session.
Parameters
session : Optional[Session]
-
A Session instance. If not provided, the instance is inferred via get_current_session.
reactive.get_current_context
reactive.get_current_context()
Get the current reactive context.
Returns
: Context
-
A
~shiny.reactive.Context
class.
Raises
: RuntimeError
-
If called outside of a reactive context.
session.Session.send_custom_message
type, message) session.Session.send_custom_message(
Send a message to the client.
Parameters
Note
Sends messages to the client which can be handled in JavaScript with Shiny.addCustomMessageHandler(type, function(message){...})
. Once the message handler is added, it will be invoked each time send_custom_message()
is called on the server.
Examples
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400
## file: app.py
from shiny import App, Inputs, Outputs, Session, reactive, ui
app_ui = ui.page_fluid(
ui.input_text("msg", "Enter a message"),
ui.input_action_button("submit", "Submit the message"),
# It'd be better to use ui.insert_ui() in order to implement this kind of
# functionality...this is just a basic demo of how custom message handling works.
ui.tags.div(id="messages"),
ui.tags.script(
"""
$(function() {
Shiny.addCustomMessageHandler("append_msg", function(message) {
$("<p>").text(message.msg).appendTo("#messages");
});
});
"""
),
)
def server(input: Inputs, output: Outputs, session: Session):
@reactive.effect
@reactive.event(input.submit)
async def _():
await session.send_custom_message("append_msg", {"msg": input.msg()})
app = App(app_ui, server, debug=True)
session.Session.send_input_message
id, message) session.Session.send_input_message(
Send an input message to the session.
Sends a message to an input on the session's client web page; if the input is present and bound on the page at the time the message is received, then the input binding object's receiveMessage(el, message)
method will be called. This method should generally not be called directly from Shiny apps, but through friendlier wrapper functions like ui.update_text()
.
Parameters
session.Session.on_flush
=True) session.Session.on_flush(fn, once
Register a function to call before the next reactive flush.
Parameters
Returns
: Callable[[], None]
-
A function that can be used to cancel the registration.
Examples
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400
## file: app.py
from datetime import datetime
from shiny import App, Inputs, Outputs, Session, render, ui
app_ui = ui.page_fluid(
ui.input_action_button("flush", "Trigger flush"),
ui.output_ui("n_clicks"),
ui.div(id="flush_time"),
)
def server(input: Inputs, output: Outputs, session: Session):
def log():
msg = "A reactive flush occurred at " + datetime.now().strftime("%H:%M:%S:%f")
print(msg)
ui.insert_ui(
ui.p(msg),
selector="#flush_time",
)
session.on_flush(log, once=False)
@render.ui
def n_clicks():
return "Number of clicks: " + str(input.flush())
app = App(app_ui, server)
session.Session.on_flushed
=True) session.Session.on_flushed(fn, once
Register a function to call after the next reactive flush.
Parameters
Returns
: Callable[[], None]
-
A function that can be used to cancel the registration.
Examples
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400
## file: app.py
from datetime import datetime
from shiny import App, Inputs, Outputs, Session, render, ui
app_ui = ui.page_fluid(
ui.input_action_button("flush", "Trigger flush"),
ui.output_ui("n_clicks"),
ui.div(id="flush_time"),
)
def server(input: Inputs, output: Outputs, session: Session):
def log():
msg = "A reactive flush occurred at " + datetime.now().strftime("%H:%M:%S:%f")
print(msg)
ui.insert_ui(
ui.p(msg),
selector="#flush_time",
)
session.on_flushed(log, once=False)
@render.ui
def n_clicks():
return "Number of clicks: " + str(input.flush())
app = App(app_ui, server)
session.Session.on_ended
session.Session.on_ended(fn)
Registers a function to be called after the client has disconnected.
Parameters
Returns
: Callable[[], None]
-
A function that can be used to cancel the registration.
Examples
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400
## file: app.py
from datetime import datetime
from shiny import App, Inputs, Outputs, Session, reactive, ui
app_ui = ui.page_fluid(
ui.input_action_button("close", "Close the session"),
)
def server(input: Inputs, output: Outputs, session: Session):
def log():
print("Session ended at: " + datetime.now().strftime("%H:%M:%S"))
session.on_ended(log)
@reactive.effect
@reactive.event(input.close)
async def _():
await session.close()
app = App(app_ui, server)
session.Session.dynamic_route
session.Session.dynamic_route(name, handler)
Register a function to call when a dynamically generated, session-specific, route is requested.
Provides a convenient way to serve-up session-dependent values for other clients/applications to consume.
Parameters
name : str
-
A name for the route (used to determine part of the URL path).
handler :
DynamicRouteHandler
-
The function to call when a request is made to the route. This function should take a single argument (a
starlette.requests.Request
object) and return astarlette.types.ASGIApp
object.
Returns
: str
-
The URL path for the route.
Examples
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400
## file: app.py
from starlette.requests import Request
from starlette.responses import JSONResponse
from shiny import App, Inputs, Outputs, Session, reactive, ui
app_ui = ui.page_fluid(
ui.input_action_button("serve", "Click to serve"), ui.div(id="messages")
)
def server(input: Inputs, output: Outputs, session: Session):
@reactive.effect
@reactive.event(input.serve)
def _():
async def my_handler(request: Request) -> JSONResponse:
return JSONResponse({"n_clicks": input.serve()}, status_code=200)
path = session.dynamic_route("my_handler", my_handler)
print("Serving at: ", path)
ui.insert_ui(
ui.tags.script(
f"""
fetch('{path}')
.then(r => r.json())
.then(x => {{ $('#messages').text(`Clicked ${{x.n_clicks}} times`); }});
"""
),
selector="body",
)
app = App(app_ui, server)
input_handler.input_handlers
input_handler.input_handlers
Manage Shiny input handlers.
Add and/or remove input handlers of a given type
. Shiny uses these handlers to pre-process input values from the client (after being deserialized) before passing them to the input
argument of an App's server
function.
The type
is based on the getType()
JavaScript method on the relevant Shiny input binding. See this article <https://shiny.posit.co/articles/js-custom-input.html>
_ for more information on how to create custom input bindings. (The article is about Shiny for R, but the JavaScript and general principles are the same.)
Methods
add(type: str, force: bool = False) -> Callable[[InputHandlerType], None] Register an input handler. This method returns a decorator that registers the decorated function as the handler for the given type
. This handler should accept three arguments: - the input value
- the input name
- the Session object remove(type: str) Unregister an input handler.
Note
add()
ing an input handler will make it persist for the duration of the Python process (unless Shiny is explicitly reloaded). For that reason, verbose naming is encouraged to minimize the risk of colliding with other Shiny input binding(s) which happen to use the same type
(if the binding is bundled with a package, we recommend the format of "packageName.widgetName").
Example
On the Javascript side, the associated input binding must have a corresponding getType
method:
getType: function(el) {return "mypackage.intify";
}