Bokeh会话数据存储:如何为每个用户存储会话级临时数据?
在Bokeh中存储会话销毁时自动清除的用户本地数据
我之前也踩过这个坑!curdoc().session_context确实不是咱们想的那种可以直接塞数据的字典,不过Bokeh其实留了专门的路子来存会话级的临时数据——核心思路是用会话ID作为唯一标识,把数据存在全局容器里,再配合会话销毁回调自动清理。下面是具体的实现步骤:
1. 初始化全局存储容器
在你的Bokeh应用脚本最开头,定义一个全局字典,用来存放每个会话的专属数据:
# 全局字典,键是会话ID,值是任意自定义数据结构 session_specific_data = {}
2. 会话启动时存入初始数据
当用户打开新会话时,获取当前会话的ID,把你需要的初始数据存到全局字典里。比如在应用的初始化函数里:
from bokeh.plotting import curdoc def init_session(): # 获取当前会话的唯一ID current_session_id = curdoc().session_context.id # 这里可以自定义任意数据结构,比如用户输入状态、临时计算结果等 session_specific_data[current_session_id] = { "user_preferences": {"theme": "light"}, "temp_calculations": [], "interaction_count": 0 } # 会话启动时执行初始化 init_session()
3. 绑定会话销毁的清理回调
为了避免内存泄漏,必须在会话结束时自动删除对应的数据。给curdoc()添加一个on_session_destroyed回调,在会话关闭时清理全局字典里的条目:
def cleanup_session(session_context): session_id_to_remove = session_context.id if session_id_to_remove in session_specific_data: del session_specific_data[session_id_to_remove] # 注册销毁回调 curdoc().on_session_destroyed(cleanup_session)
4. 在应用交互中使用存储的数据
之后在你的各种交互回调(比如按钮点击、滑块更新、表单提交)里,就可以通过当前会话ID获取和修改专属数据了:
from bokeh.models import Button def handle_button_click(): session_id = curdoc().session_context.id user_data = session_specific_data[session_id] # 更新数据 user_data["interaction_count"] += 1 user_data["temp_calculations"].append(f"Clicked {user_data['interaction_count']} times") print("当前会话数据:", user_data) # 创建按钮并绑定回调 action_button = Button(label="点击测试数据存储") action_button.on_click(handle_button_click) # 添加到文档根节点 curdoc().add_root(action_button)
注意事项
- 如果你的Bokeh Server是多进程部署(比如用
--num-procs参数启动),全局字典只能在单个进程内共享,这种情况下建议用Redis之类的分布式存储来跨进程共享会话数据。 - 存储的数据尽量保持轻量化,避免存大对象导致内存占用过高。
内容的提问来源于stack exchange,提问作者Tommy
相关产品推荐
相关产品推荐

