Closed T4rk1n closed 2 years ago
Added Session value/Component sync & session callbacks.
Session values used in the layout will automatically be synced with the frontend component prop it was inserted in. Meaning if you do dcc.Input(value=session.my_input_value)
, session.my_input_value
will be updated to the value of the input, no id required, works with multi page.
In addition, you can add callbacks to trigger when a session value is updated to output to component props. This only works with SessionInput
and SessionState
, cannot mix regular inputs/states.
For session values that are synced with layout components, session callbacks are automatically triggered.
Example:
from dash import Dash, html, dcc, Output
from dash_labs.session import session, setup_sessions, SessionInput, SessionState
from dash_labs.session.backends.redis import RedisSessionBackend
app = Dash(__name__)
setup_sessions(app, RedisSessionBackend())
session.my_value = "Hello Dash"
session.times = 0
app.layout = html.Div(
[
# No id required for sync & session callbacks.
dcc.Input(value=session.my_value),
html.Div(id="session-output"),
html.Div(id="session-output2"),
]
)
@session.callback(
[Output("session-output", "children"), Output("session-output2", "children")],
SessionInput("my_value"),
SessionState("times"),
)
def on_session_value(value, times):
session.times = times + 1
return f"From session: {value}", f"Times: {times + 1}"
if __name__ == "__main__":
app.run(debug=True)
New example showcase most sync features & callback, save personal posts using session:
import datetime
from dash import Dash, html, dcc, Output
from dash_labs.session.backends.diskcache import DiskcacheSessionBackend
from dash_labs.session import session, setup_sessions, SessionInput, SessionState
app = Dash(__name__)
setup_sessions(app, DiskcacheSessionBackend())
# Set default values in the global scope.
session.guest_name = 'guest'
session.posts = []
session.num_posts = 0
app.layout = html.Div([
html.H2('Enter a guest name'),
#
# eg: session.guess_name will be synced with the input value.
dcc.Input(value=session.guest_name),
html.Div([
dcc.Input(value=session.current_post, id='new-post'),
html.Button('New post', n_clicks=session.num_posts),
]),
html.Div(id='session-stats'),
# Put all the posts in reverse order for last posted first.
html.Div(session.posts, style={'display': 'flex', 'flexDirection': 'column-reverse'}),
])
@session.callback(
Output('session-stats', 'children'),
SessionInput('num_posts'),
SessionState('posts')
)
def on_new_post(_, posts):
# Can save components as session values
session.posts = posts + [
html.Div([
# Use the session.current_post current value, reset later
html.Div(session.current_post()),
html.Div(
f'Posted at: {datetime.datetime.now().isoformat()}',
style={'fontWeight': 'bold', 'fontStyle': 'italic'}
)
])
]
# Reset the current post input
session.current_post = ''
# To use session values inside f-string or format you
# need to call to get the actual value.
return f'Thank you for submitting your {session.num_posts()} post'
if __name__ == '__main__':
app.run(debug=True)
The session
now always returns SessionValue
objects, to get the actual value in callbacks for operations you need to call the key: value = f'Hello {session.guest_name()}'
Introduce a session system for Dash to store data on the backend scoped to each visitor of the application.
Features:
Example app
Backends
To use the session system, install the backend dependencies:
pip install dash_labs[diskcache]
pip install dash_labs[redis]
pip install dash_labs[postgres]