ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如何在 JupyterHub 的 notebook 中运行 Bokeh server 应用(JUPYTER_BOKEH_EXTERNAL_URL 与 notebook_url)?

如何在 JupyterHub 的 notebook 中运行 Bokeh server 应用(JUPYTER_BOKEH_EXTERNAL_URL 与 notebook_url)? 如何在 JupyterHub 的 notebook 中运行 Bokeh server 应用JUPYTER_BOKEH_EXTERNAL_URL 与 notebook_url【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh你在自建的 JupyterHub 上打开 notebook想在单元格里嵌入一个完整的 Bokeh server 应用——滑块、事件绑定等 Python 回调代码运行在 notebook 的 Python 环境中而不是只渲染成静态图。直接运行往往连不上Bokeh server 在 notebook 会话内监听一个端口而 JupyterHub 在浏览器与你的 JupyterLab 容器之间充当反向代理浏览器必须通过 Hub 的公网地址加proxy/端口路径才能到达该端口。Bokeh 提供两条解决路径二者最终都指向同一个结果浏览器拿到一个能穿过 JupyterHub 代理的 URL。方式一管理员在 notebook 运行环境中设置JUPYTER_BOKEH_EXTERNAL_URLURL 生成全自动同一份 notebook 在 JupyterHub 和独立 JupyterLab 会话中都能不改代码运行方式二用户自己写一个notebook_url回调函数并传给show适用于 Hub 上没有设置该环境变量的场景。以下内容整理自 Bokeh 用户指南的 Jupyter 章节 docs/bokeh/source/docs/user_guide/output/jupyter.rst。准备完成 JupyterLab 环境并安装 jupyter-server-proxy先按 JupyterLab而非 JupyterHub的常规步骤把 Bokeh 跑起来JupyterLab 至少 3.0 版本并安装jupyter_bokeh扩展conda install jupyter_bokeh # 或 pip install jupyter_bokeh然后安装jupyter-server-proxy包并启用服务端扩展这一步是 JupyterHub 场景特有的必需项pip install jupyter-server-proxy jupyter server extension enable --py jupyter-server-proxy如果你要在 JupyterLab 界面中使用还需要安装对应的前端扩展也可以从 GUI 安装jupyter labextension install jupyterlab/server-proxy方式一管理员设置 JUPYTER_BOKEH_EXTERNAL_URL作为 JupyterHub 管理员在 notebook 环境中设置一个环境变量值为 Hub 的公网 URL。文档给出的 JupyterHub Helm chart 配置 YAML 示例如下文档示例值替换为你的 Hub 域名hub: single_user: extraEnv: JUPYTER_BOKEH_EXTERNAL_URLhttps://our-public-hub-name.edu文档同时给出 shell 形式export JUPYTER_BOKEH_EXTERNAL_URLhttps//our-hub.science.edu注意原文示例中https后缺少冒号属于文档笔误实际写入时请使用你 Hub 的标准 URL 格式。设置后bokeh 会自动按 JupyterHub 代理规则生成 URLnotebook_url不再需要手动指定也不再需要其他操作。其优势是同一份 notebook 无需修改即可在 JupyterHub 和独立 JupyterLab 会话中运行。这一机制在源码 src/bokeh/io/notebook.py 中实现show的notebook_url参数可以是字符串或可调用对象——字符串会被解析出 origin 和完整 server URL可调用对象接收一个参数端口号或None传入端口时须返回 server URL传入None时须返回 origin URL。当检测到JUPYTER_BOKEH_EXTERNAL_URL时bokeh 用内置的_remote_jupyter_proxy_url覆盖你传入的notebook_url此时若你仍显式传了非默认的notebook_url会输出警告日志Environment var JUPYTER_BOKEH_EXTERNAL_URL is defined. Ignoring notebook_url parameter.看到这个警告说明环境变量已生效显式传入的notebook_url会被忽略。自动路径依赖JUPYTERHUB_SERVICE_PREFIX环境变量JupyterHub 默认注入指向当前用户的代理路径前缀源码中通过os.environ[JUPYTERHUB_SERVICE_PREFIX]读取。方式二用户自己定义 notebook_url 回调如果 Hub 上没有设置JUPYTER_BOKEH_EXTERNAL_URL在 notebook 中定义一个回调函数帮助构造浏览器连接 Bokeh server 的 URL以下实现为文档给出的参考实现import os import urllib.parse def remote_jupyter_proxy_url(port): Callable to configure Bokehs show method when a proxy must be configured. If port is None were asking about the URL for the origin header. base_url os.environ[EXTERNAL_URL] host urllib.parse.urlparse(base_url).netloc # If port is None were asking for the URL origin # so return the public hostname. if port is None: return host service_url_path os.environ[JUPYTERHUB_SERVICE_PREFIX] proxy_url_path proxy/%d % port user_url urllib.parse.urljoin(base_url, service_url_path) full_url urllib.parse.urljoin(user_url, proxy_url_path) return full_url执行前必须替换/设置两个环境值EXTERNAL_URL在 notebook 环境中设置为你的 JupyterHub 安装的公网 URL文档明确要求修改这段代码或把 Hub URL 赋给EXTERNAL_URLJUPYTERHUB_SERVICE_PREFIX由 JupyterHub 默认提供无需手动设置。函数逻辑port为None时只返回公网主机名用于 origin否则拼出Hub URL 服务前缀 proxy/端口的完整地址。URL 拼接结果可以对照仓库单元测试 tests/unit/bokeh/io/test_notebook__io.py 中的示例值文档示例仅用于说明 URL 形态不是固定预期当JUPYTER_BOKEH_EXTERNAL_URLhttps://our-hub.edu、JUPYTERHUB_SERVICE_PREFIX/user/homerdonuts.edu/时端口1234生成https://our-hub.edu/user/homerdonuts.edu/proxy/1234None生成our-hub.edu。然后把函数作为notebook_url关键字参数传给show。Bokeh 在建立 server、生成加载图表的 URL 时会调用它from bokeh.io import show show(obj, notebook_urlremote_jupyter_proxy_url)其中obj是你要展示的对象如figure返回的图或应用定义即文档中show(obj, notebook_url...)的形式。在 notebook 中运行 Bokeh server 应用仓库提供了完整的 notebook 嵌入示例 examples/server/api/notebook_embed.ipynb用bkapp(doc)函数定义应用show会自动用FunctionHandler把它包成ApplicationBokeh server 会为每个新打开的会话调用bkapp构建新文档。核心代码在示例基础上略去了doc.theme设置import yaml from bokeh.layouts import column from bokeh.models import ColumnDataSource, Slider from bokeh.plotting import figure from bokeh.themes import Theme from bokeh.io import show, output_notebook from bokeh.sampledata.sea_surface_temperature import sea_surface_temperature output_notebook() def bkapp(doc): df sea_surface_temperature.copy() source ColumnDataSource(datadf) plot figure(x_axis_typedatetime, y_range(0, 25), y_axis_labelTemperature (Celsius), titleSea Surface Temperature at 43.18, -70.43) plot.line(time, temperature, sourcesource) def callback(attr, old, new): if new 0: data df else: data df.rolling(f{new}D).mean() source.data ColumnDataSource.from_df(data) slider Slider(start0, end30, value0, step1, titleSmoothing by N Days) slider.on_change(value, callback) doc.add_root(column(slider, plot)) show(bkapp) # 独立 notebook 且不在默认 URL 时按示例改为notebook_urlhttp://localhost:8888两个默认值来自源码决定 URL 如何解析见 src/bokeh/io/notebook.pynotebook_url的默认值是localhost:8888port默认为0即 server 监听一个随机动态端口这也是回调函数需要接收端口参数的原因。在 JupyterHub 场景下notebook_url由上面的方式一或方式二提供示例中注释掉的notebook_urlhttp://localhost:8888只在独立 notebook 且不在默认 URL 时才需要。验证结果与排查文档给出的成功判定是配置完成后可能需要重启 serverYou may need to restart your server after this随后Bokeh 内容应当加载并在 Jupyter 环境中执行你定义的 Python 回调。也就是说移动滑块、触发事件时callback等 Python 代码真实被执行、图形随之更新即为打通。如果 notebook 关闭后重新打开时 Bokeh 图形不重新渲染取决于你使用的 notebook 版本可能需要信任该 notebookFile菜单下的Trust Notebook选项排查时注意两条边界JUPYTER_BOKEH_EXTERNAL_URL与显式notebook_url同时存在时环境变量优先、参数被忽略并产生上述警告——此时不要再去改notebook_url方式一和方式二的自动 URL 拼接都依赖JUPYTERHUB_SERVICE_PREFIX这是 JupyterHub 为每个用户会话注入的前缀路径若该变量缺失JUPYTER_BOKEH_EXTERNAL_URL自动路径与方式二代码都会取不到服务前缀。完整的 notebook 嵌入写法可继续参考 examples/server/api/notebook_embed.ipynb环境变量覆盖逻辑的源码见 src/bokeh/io/notebook.py。【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表