session.Session

session.Session()

Interface definition for Session-like classes, like AppSession, SessionProxy, and ExpressStubSession.

Methods

Name Description
close Close the session.
download Deprecated. Please use download instead.
dynamic_route Register a function to call when a dynamically generated, session-specific, route is requested.
is_stub_session Returns whether this is a stub session.
on_ended Registers a function to be called after the client has disconnected.
on_flush Register a function to call before the next reactive flush.
on_flushed Register a function to call after the next reactive flush.
send_custom_message Send a message to the client.
send_input_message Send an input message to the session.
set_message_handler Set a client message handler.

close

session.Session.close(code=1001)

Close the session.

Examples

#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400

## file: app.py
from datetime import datetime

from shiny import reactive
from shiny.express import input, session, ui

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 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()

download

session.Session.download(
    id=None,
    filename=None,
    media_type=None,
    encoding='utf-8',
)

Deprecated. Please use download instead.

Parameters

id : Optional[str] = None

The name of the download.

filename : Optional[str | Callable[[], str]] = None

The filename of the download.

media_type : None | str | Callable[[], str] = None

The media type of the download.

encoding : str = 'utf-8'

The encoding of the download.

Returns

: Callable[[DownloadHandler], None]

The decorated function.

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 a starlette.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 reactive
from shiny.express import input, session, ui

ui.input_action_button("serve", "Click to serve")

ui.div(id="messages")


@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",
    )

is_stub_session

session.Session.is_stub_session()

Returns whether this is a stub session.

In the UI-rendering phase of Shiny Express apps, the session context has a stub session. This stub session is not a real session; it is there only so that code which expects a session can run without raising errors.

on_ended

session.Session.on_ended(fn)

Registers a function to be called after the client has disconnected.

Parameters

fn : Callable[[], None] | Callable[[], Awaitable[None]]

The function to call.

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 reactive
from shiny.express import input, session, ui

ui.input_action_button("close", "Close the 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()

on_flush

session.Session.on_flush(fn, once=True)

Register a function to call before the next reactive flush.

Parameters

fn : Callable[[], None] | Callable[[], Awaitable[None]]

The function to call.

once : bool = True

Whether to call the function only once or on every flush.

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.express import input, render, session, ui

ui.input_action_button("flush", "Trigger flush")


@render.ui
def n_clicks():
    return "Number of clicks: " + str(input.flush())


ui.div(id="flush_time")


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",
    )


if hasattr(session, "on_flush"):
    _ = session.on_flush(log, once=False)

on_flushed

session.Session.on_flushed(fn, once=True)

Register a function to call after the next reactive flush.

Parameters

fn : Callable[[], None] | Callable[[], Awaitable[None]]

The function to call.

once : bool = True

Whether to call the function only once or on every flush.

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.express import input, render, session, ui

ui.input_action_button("flush", "Trigger flush")


@render.ui
def n_clicks():
    return "Number of clicks: " + str(input.flush())


ui.div(id="flush_time")


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",
    )


if hasattr(session, "on_flushed"):
    _ = session.on_flushed(log, once=False)

send_custom_message

session.Session.send_custom_message(type, message)

Send a message to the client.

Parameters

type : str

The type of message to send.

message : dict[str, object]

The message to send.

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 reactive
from shiny.express import input, session, ui

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");
        });
    });
    """
)


@reactive.effect
@reactive.event(input.submit)
async def _():
    await session.send_custom_message("append_msg", {"msg": input.msg()})

send_input_message

session.Session.send_input_message(id, 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

id : str

An id matching the id of an input to update.

message : dict[str, object]

The message to send.

set_message_handler

session.Session.set_message_handler(name, handler, *, _handler_session=None)

Set a client message handler.

Sets a method that can be called by the client via Shiny.shinyapp.makeRequest(). Shiny.shinyapp.makeRequest() makes a request to the server and waits for a response. By using makeRequest() (JS) and set_message_handler() (python), you can have a much richer communication interaction than just using Input values and re-rendering outputs.

For example, @render.data_frame can have many cells edited. While it is possible to set many input values, if makeRequest() did not exist, the data frame would be updated on the first cell update. This would cause the data frame to be re-rendered, cancelling any pending cell updates. makeRequest() allows for individual cell updates to be sent to the server, processed, and handled by the existing data frame output.

When the message handler is executed, it will be executed within an isolated reactive context and the session context that set the message handler.

Parameters

name : str

The name of the message handler.

handler : Callable[…, Jsonifiable] | Callable[…, Awaitable[Jsonifiable]] | None

The handler function to be called when the client makes a message for the given name. The handler function should take any number of arguments that are provided by the client and return a JSON-serializable object. If the value is None, then the handler at name will be removed.

**_handler_session** : Optional[Session] = None

For internal use. This is the session which will be used as the session context when calling the handler.

Returns

: str

The key under which the handler is stored (or removed). This value will be namespaced when used with a session proxy.