from shiny.input_handler import input_handlers
@input_handlers.add("mypackage.intify")
def _(value, name, session):
return int(value)
Session
Tools for managing user sessions and accessing session-related information.
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 viaget_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 viaget_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.ClientData
self, session) session.ClientData(
Access (client-side) information from the browser.
Provides access to client-side information, such as the URL components, the pixel ratio of the device, and the properties of outputs.
Each method in this class reads a reactive input value, which means that the method will error if called outside of a reactive context.
Raises
: RuntimeError
-
If a method is called outside of a reactive context.
Examples
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400
## file: app.py
import textwrap
# pyright: reportUnknownMemberType=false, reportUnknownVariableType=false
import matplotlib.pyplot as plt
import numpy as np
from shiny import App, Inputs, Outputs, Session, render, ui
app_ui = ui.page_sidebar(
ui.sidebar(
ui.input_slider("obs", "Number of observations:", min=0, max=1000, value=500),
open="closed",
),
ui.markdown(
"""
#### `session.clientdata` values
The following methods are available from the `session.clientdata` object and allow you
to reactively read the client data values from the browser.
"""
),
ui.output_text_verbatim("clientdatatext"),
ui.output_plot("myplot"),
)
def server(input: Inputs, output: Outputs, session: Session):
@render.code
def clientdatatext():
return textwrap.dedent(
f"""
.url_hash() -> {session.clientdata.url_hash()}
.url_hash_initial() -> {session.clientdata.url_hash_initial()}
.url_hostname() -> {session.clientdata.url_hostname()}
.url_pathname() -> {session.clientdata.url_pathname()}
.url_port() -> {session.clientdata.url_port()}
.url_protocol() -> {session.clientdata.url_protocol()}
.url_search() -> {session.clientdata.url_search()}
.pixelratio() -> {session.clientdata.pixelratio()}
.output_height("myplot") -> {session.clientdata.output_height("myplot")}
.output_width("myplot") -> {session.clientdata.output_width("myplot")}
.output_hidden("myplot") -> {session.clientdata.output_hidden("myplot")}
.output_bg_color("myplot") -> {session.clientdata.output_bg_color("myplot")}
.output_fg_color("myplot") -> {session.clientdata.output_fg_color("myplot")}
.output_accent_color("myplot") -> {session.clientdata.output_accent_color("myplot")}
.output_font("myplot") -> {session.clientdata.output_font("myplot")}
"""
)
@render.plot
def myplot():
plt.figure()
plt.hist(np.random.normal(size=input.obs())) # type: ignore
plt.title("This is myplot")
app = App(app_ui, server)
Methods
Name | Description |
---|---|
output_accent_color | Reactively read the accent color of an output. |
output_bg_color | Reactively read the background color of an output. |
output_fg_color | Reactively read the foreground color of an output. |
output_font | Reactively read the font(s) of an output. |
output_height | Reactively read the height of an output. |
output_hidden | Reactively read whether an output is hidden. |
output_width | Reactively read the width of an output. |
pixelratio | Reactively read the pixel ratio of the device. |
url_hash | Reactively read the hash part of the URL. |
url_hash_initial | Reactively read the initial hash part of the URL. |
url_hostname | Reactively read the hostname part of the URL. |
url_pathname | The pathname part of the URL. |
url_port | Reactively read the port part of the URL. |
url_protocol | Reactively read the protocol part of the URL. |
url_search | Reactively read the search part of the URL. |
output_accent_color
id) session.ClientData.output_accent_color(
Reactively read the accent color of an output.
Parameters
id : str
-
The id of the output.
Returns
: str | None
-
The accent color of the output, or None if the output does not exist (or does not report its accent color).
output_bg_color
id) session.ClientData.output_bg_color(
Reactively read the background color of an output.
Parameters
id : str
-
The id of the output.
Returns
: str | None
-
The background color of the output, or None if the output does not exist (or does not report its bg color).
output_fg_color
id) session.ClientData.output_fg_color(
Reactively read the foreground color of an output.
Parameters
id : str
-
The id of the output.
Returns
: str | None
-
The foreground color of the output, or None if the output does not exist (or does not report its fg color).
output_font
id) session.ClientData.output_font(
Reactively read the font(s) of an output.
Parameters
id : str
-
The id of the output.
Returns
: str | None
-
The font family of the output, or None if the output does not exist (or does not report its font styles).
output_height
id) session.ClientData.output_height(
Reactively read the height of an output.
Parameters
id : str
-
The id of the output.
Returns
: float | None
-
The height of the output, or None if the output does not exist (or does not report its height).
output_width
id) session.ClientData.output_width(
Reactively read the width of an output.
Parameters
id : str
-
The id of the output.
Returns
: float | None
-
The width of the output, or None if the output does not exist (or does not report its width).
pixelratio
session.ClientData.pixelratio()
Reactively read the pixel ratio of the device.
url_hash
session.ClientData.url_hash()
Reactively read the hash part of the URL.
url_hash_initial
session.ClientData.url_hash_initial()
Reactively read the initial hash part of the URL.
url_hostname
session.ClientData.url_hostname()
Reactively read the hostname part of the URL.
url_pathname
session.ClientData.url_pathname()
The pathname part of the URL.
url_port
session.ClientData.url_port()
Reactively read the port part of the URL.
url_protocol
session.ClientData.url_protocol()
Reactively read the protocol part of the URL.
url_search
session.ClientData.url_search()
Reactively read the search part of the URL.
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)
session.Session.close
=1001) session.Session.close(code
Close the session.
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"),
ui.p(
"""If this example is running on the browser (i.e., via shinylive),
closing the session will log a message to the JavaScript console
(open the browser's developer tools to see it).
"""
),
)
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)
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";
}