Skip to content

feat(session): Add session.user_data for arbitrary per-session data - #2543

Open
cpsievert wants to merge 2 commits into
mainfrom
feat/session-user-data
Open

cpsievert wants to merge 2 commits into
mainfrom
feat/session-user-data

Conversation

@cpsievert

Copy link
Copy Markdown
Collaborator

Ports session$userData from Shiny for R: a plain dict, created per session
and shared with module sessions, for session-specific state that isn't
reactive.

Why

Code that only has a session (a helper, a package, a module) has had nowhere
to keep per-session state. Some things it unlocks:

  • Authentication. Stash a user's OAuth access token or viewer credentials
    once, and any module or helper can call an API on their behalf. It doesn't
    need to be passed through every signature, and it never triggers
    invalidation or lands in a bookmark the way a reactive.Value would.
  • Per-session resources. Open a DB connection or API client lazily, once
    per session, and close it in session.on_ended.
  • Non-reactive caches. Memoize an expensive per-user lookup or model
    without creating reactive dependencies.
  • Run-once setup. Guard per-session initialization with
    if "x" not in session.user_data.
def server(input, output, session):
    session.user_data["token"] = fetch_token(session.http_conn.headers)

@module.server
def orders(input, output, session):
    client = ApiClient(token=session.user_data["token"])

Use a reactive.Value instead if the data should drive the UI.

Behavior

  • Not reactive; released with the session, and still readable in on_ended.
  • Modules share the root session's dict.
  • Mutate in place. Assigning a new dict raises AttributeError, as R forbids
    reassigning userData.

Also adds a section to the bundled shiny-for-python agent skill.

A plain dict for session-specific state that is not reactive, such as
credentials. The dict is shared with module sessions (SessionProxy reads
and writes the root session's dict) and is discarded when the session
ends. This is the Python equivalent of Shiny for R's session$userData.
…n the agent skill

Assigning session.user_data from a module used to silently detach the
proxy from the root session's dict, as R's session$userData forbids.
user_data is now a read-only property on every Session, and SessionProxy
reads it live from the root session.

Adds tests for the reassignment error and for reading user_data inside
on_ended callbacks, and a user_data section in the bundled agent skill.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant