?)
如何把 Bokeh server 应用嵌入 Flask 网站server_session 与 pull_session【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh如果你的页面需要展示的不是静态图表而是带 Python 回调的交互式应用拖动滑块触发服务器端计算、实时刷新的曲线等就需要把运行在 Bokeh server 上的应用嵌进现有的 Flask 网站。bokeh.embed模块提供两个入口函数完成这件事server_document在每次页面加载时嵌入一个新会话server_session嵌入一个指定的已有会话配合bokeh.client的pull_session可以在渲染前对会话内容做用户级定制。本文给出两条路径的具体代码、运行命令和验证方式。先选对嵌入函数函数行为适用情况server_document(url)接收 Bokeh server 应用的 URL返回一个script标签脚本每执行一次就嵌入该 server 的一个新会话每次页面加载都显示全新会话无需预先定制server_session(session_id..., url...)接收要嵌入的 model或整个会话文档、会话 ID 和应用 URL返回加载该特定会话的script先拉取一个会话、修改它例如按登录用户定制标题/数据再把定制后的会话交给浏览器文档给出的典型场景Flask 为已认证用户渲染页面希望拉取一个新会话、为该用户做定制再输出定制后的 Bokeh server 会话。两条路径最终都通过 Flask 模板把返回的script渲染进页面。仓库中examples/server/api/templates/embed.html就是配套模板核心一行是{{ script|safe }}。方式一server_document 单进程嵌入最短可验证路径仓库提供了完整可运行的示例 flask_embed.py它把 Bokeh server 跑在 Flask 进程的线程里单进程即可验证整个链路应用函数bkapp(doc)用sea_surface_temperature示例数据画一条时间序列折线图加一个Slider控件回调slider.on_change(value, callback)在服务器端做滚动均值计算后更新ColumnDataSourcebk_worker()在线程中创建Server({/bkapp: bkapp}, io_loopIOLoop(), allow_websocket_origin[localhost:8000])并启动Flask 路由/调用server_document(http://localhost:5006/bkapp)生成脚本交给模板渲染。allow_websocket_origin[localhost:8000]不是可省略的细节浏览器请求 Bokeh server 时携带的Origin头是宿主页面的地址这里是 Flask 的localhost:8000不在允许列表中的来源会被服务器以 HTTP 403 拒绝。注意脚本中doc.theme Theme(filenametheme.yaml)用的是相对路径theme.yaml位于 examples/server/api/theme.yaml所以必须在该目录下运行脚本。运行并验证python flask_embed.py在examples/server/api目录下执行即示例 README 的说明run withpython flask_embed.py。脚本打印Opening single process Flask app with embedded Bokeh application on http://localhost:8000/ Multiple connections may block the Bokeh app in this configuration! See flask_gunicorn_embed.py for one way to run multi-process在浏览器打开http://localhost:8000/页面中应出现由 Bokeh server 驱动的滑块和温度曲线拖动滑块时回调在服务器端执行、曲线随之更新。这就是server_document路径的完成标志。示例源码注释同时给出了该配置的两个限制此配置下不能传num_procs 1且多个并发连接可能阻塞 Bokeh 应用——需要多进程时见下文的 gunicorn 变体。方式二pull_session server_session 嵌入指定会话当目标是先定制、再展示时使用这条路径。前提条件是目标应用已经作为一个 Bokeh server 应用在运行server_document/server_session的 URL 参数指向它。如果 server 是独立进程启动的用bokeh serve yourapp.py应用默认可在http://localhost:5006/下按应用名访问例如文档 nginx 示例中bokeh serve myapp.py对应 URL.../myapp并像前面一样用--allow-websocket-origin放行 Flask 宿主页面的来源否则 WebSocket 握手会以 403 失败。Flask 端代码来自用户指南的原文示例from flask import Flask, render_template from bokeh.client import pull_session from bokeh.embed import server_session app Flask(__name__) app.route(/, methods[GET]) def bkapp_page(): # pull a new session from a running Bokeh server with pull_session(urlhttp://localhost:5006/sliders) as session: # update or customize that session session.document.roots[0].children[1].title.text Special sliders for a specific user! # generate a script to load the customized session script server_session(session_idsession.id, urlhttp://localhost:5006/sliders) # use the script in the rendered page return render_template(embed.html, scriptscript, templateFlask) if __name__ __main__: app.run(port8080)按执行顺序拆解这三步pull_session(url...)是上下文管理器从运行中的 Bokeh server 拉取一个会话退出with块时连接关闭在with块内修改session.document。示例中的路径roots[0].children[1].title是针对 sliders 应用布局写的——换成你自己的应用时按自己文档的 root 结构改成对应 model 的访问路径server_session(session_idsession.id, url...)用刚才那个会话的 ID 生成加载脚本浏览器加载的是这个已被定制过的现有会话而不是新会话。验证方式运行 Flask上例端口 8080在浏览器访问该页面。嵌入的视图连接到既有会话图标题显示为定制后的文本上例即Special sliders for a specific user!。如果标题仍是应用默认值说明页面连接到了新会话或定制未生效可检查pull_session与server_session传入的 URL 是否指向同一个应用实例。注意这里的两个来源要一致pull_session连接的是 server 端端口 5006而页面浏览器连接时携带的 Origin 是localhost:8080两者都要放行。部署到生产环境时的文档明确项以下四条来自部署章节直接影响嵌入式部署能否工作协议必须一致。不要在父服务走 HTTPS 时让 Bokeh server 走 HTTP或反过来。Bokeh 的加载脚本在客户端用window.location.protocol决定资源加载协议两侧协议不匹配时加载脚本向 Bokeh server 的请求会失败。CSP 配置。要让宿主页面显示嵌入的 Bokeh 视图必须把 Bokeh server 的公网主机名和端口加入父服务内容安全策略的script-src和connect-src指令覆盖 HTTP(S) 与 WS(S) 两种协议。具体写法取决于父服务使用的框架文档提到的最后手段是由反向代理重写 CSP 头。签名会话 ID。Bokeh server 本身没有认证设施。嵌入到大型组织或公网时文档建议只让你的 Web 应用能发起有效请求先用bokeh secret生成密钥并导出为BOKEH_SECRET_KEY启动 server 时设置BOKEH_SIGN_SESSIONSyesFlask 端改用签名会话 IDexport BOKEH_SECRET_KEYbokeh secret BOKEH_SIGN_SESSIONSyes bokeh serve --allow-websocket-originacme.com myapp.pyfrom bokeh.util.token import generate_session_id script server_session(urlhttp://localhost:5006/bkapp, session_idgenerate_session_id())BOKEH_SECRET_KEY必须在 Bokeh server 进程和 Flask 进程两处设置相同的值。文档同时提醒签名会话 ID 即访问令牌token 体系的安全性取决于密钥保密还应让 server 位于终止 SSL 的代理之后或自行终止 SSL以安全地把会话 ID 传给浏览器。多进程运行。单进程线程嵌入的配置无法承受多进程扩展仓库给出的替代方案是 flask_gunicorn_embed.py。它用bind_sockets(localhost, 0)让每个 gunicorn worker 监听自己的端口路由中server_document(fhttp://localhost:{port}/bkapp)使用各自进程的动态端口gunicorn -w 4 flask_gunicorn_embed:app示例 README 明确该脚本需要 UNIX 环境才能运行。边界说明以上路径都要求被嵌入的是Bokeh 应用依赖 Bokeh server 运行若只是无需 server 的静态文档文档建议改用file_html、components、json_item等独立文档嵌入方式不需要本文的会话机制。server_document/server_session对非 Python 父服务同样可用但需要通过一个长驻 Python 脚本以 IPC 方式返回这两个函数的文本结果——对 Flask 这类 Python 父服务不需要绕这一层。完整的可运行示例见 examples/server/api/flask_embed.py、flask_gunicorn_embed.py 与 templates/embed.html运行说明在 examples/server/api/README.md函数语义见 embed.rst 的 Bokeh applications 一节部署与安全问题见 deploy.rst。【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考