设置开发环境#
Bokeh 项目由两个主要组件构成:Bokeh 包源代码(使用 Python 编写)和 BokehJS 客户端库(使用 TypeScript 编写)。
因此,您需要设置两个环境才能为 Bokeh 做出贡献:Python 环境和 TypeScript 环境。本章将引导您完成设置完整开发环境的所有必要步骤。
1. 检查基本要求#
安装或更新 Git#
Bokeh 源代码存储在 Git 源代码控制仓库中。使用 Bokeh 的第一步是在您的系统上安装或更新 Git。
根据您使用的是 Windows、OSX 还是 Linux,有不同的方法可以执行此操作。要在任何平台上安装 Git,请参阅 安装 Git 部分,该部分位于 Pro Git Book 中。
如果您以前从未使用过 Git,可以在 Git 文档 中找到一些初学者教程和资源的链接。
安装或更新 conda#
处理 Bokeh 代码库需要安装几个非 Python 包的软件包。例如,用于 TypeScript 开发的 Node.js 或用于测试和导出的 Selenium。
为了能够在一个地方管理 Python 和非 Python 依赖项,Bokeh 使用 conda 包管理器。conda
是免费 Anaconda Python 发行版的一部分,适用于 Windows、macOS 和 Linux。Conda 为您创建和管理虚拟环境。因此,您不需要像 venv
、virtualenv
或 pipenv
这样的工具。虽然从技术上讲,可以在没有 conda
的情况下手动安装所有依赖项,但本指南将假定您已安装 conda
。
要在您的系统上安装或更新 Conda,请参阅 安装,该部分位于 Conda 文档 中。
注意
如果您的系统上已安装 conda
,请通过运行以下命令确保它是最新的
conda update -n base -c defaults conda
2. Fork 和克隆仓库#
Bokeh 项目的源代码托管在 GitHub 上,地址为 bokeh/bokeh。
除非您是 @bokeh/dev 开发团队成员,否则您首先需要创建 Bokeh 主仓库的一个 fork。在 fork 时,请确保取消选中将复制限制为特定分支的复选框(例如“仅复制 branch-3.2 分支”)。有关创建 fork 的更多信息,请参阅 Fork 一个仓库,该部分位于 GitHub 帮助 中。
接下来,将您要处理的 Bokeh 仓库版本克隆到您硬盘驱动器上的本地文件夹。使用 git clone
或按照 克隆 fork 仓库 中的说明进行操作,该部分位于 GitHub 帮助 中。
克隆仓库会在您的文件系统位置创建一个 bokeh
目录。此本地 bokeh
目录在本文档的其余部分中称为源代码检出。
在继续之前,有必要使用以下命令将 Bokeh 仓库添加为额外的上游仓库
git remote add upstream git@github.com:bokeh/bokeh.git
git fetch upstream
git remote add upstream https://github.com/bokeh/bokeh.git
git fetch upstream
3. 创建 conda 环境#
您刚刚克隆到本地硬盘驱动器的 Bokeh 仓库在 conda 文件夹中包含 测试环境文件。这些文件中包含自动创建基本开发环境所需的所有信息。
在您的源代码检出目录的根级别使用 conda env create
来设置环境并安装所有必要的软件包。“测试”环境文件按 Python 版本进行版本控制。
例如,要为 Python 3.10 安装环境,请调用
conda env create -n bkdev -f conda/environment-test-3.10.yml
注意
使用 conda -n bkdev
选项将 bkdev
设置为您的环境名称。本章的其余部分和本指南中的所有其他章节都假定这是您的环境名称。
然后,激活环境
conda activate bkdev
注意
要更新您的本地环境,请使用 conda env update --name bkdev -f conda/<environment file>
。每当测试环境中的依赖项发生更改时,都需要更新您的本地环境。例如,当主 Bokeh 仓库中的环境文件更新时,或者当您切换分支以处理不同的 issue 时,可能会发生这种情况。
4. 安装 Node 包#
构建 BokehJS 还需要使用 Node 包管理器 (npm) 安装 JavaScript 依赖项。如果您已按照上面的说明进行操作,则 conda
已经将必要的 npm
和 node.js
包安装到您的系统中。
Bokeh 通常需要最新主要版本的 npm
。要全局安装最新版本,请从源代码检出目录的顶层开始,然后运行以下命令
cd bokehjs
npm install --location=global npm
如果您不想全局安装 npm,请省略 --location=global
标志。在这种情况下,您需要调整所有后续的 npm
命令,以使用在 bokehjs/node_modules
下安装的本地版本。
接下来,仍然在 bokehjs
子目录中,运行以下命令来安装 BokehJS 的所有 JavaScript 依赖项
npm ci
此命令将必要的包安装到 node_modules
子目录中。
注意
通常,您只需在首次设置本地环境时执行此操作一次。但是,如果添加或更改了依赖项,则需要重复这些步骤来安装和更新相应的包。
5. 设置 pre-commit#
Bokeh 使用 pre-commit 来帮助您防止提交中出现一些常见错误。
要在本地设置 pre-commit,请从您的源代码检出目录的顶层运行以下命令
python scripts/hooks/install.py
这将 pre-commit 配置为使用两个 Git 钩子,每当您将提交推送到 Bokeh 的 GitHub 仓库时,它们都会检查您的代码
- 代码库测试
git-commit 将运行 Bokeh 的 代码库测试,以检查代码库质量问题,例如空格和导入。这包括使用 Ruff、ESLint 和 isort 进行测试。
- 受保护分支
git-commit 将确保您不会意外地将提交推送到 Bokeh 的受保护分支
main
和branch-x.y
上。
注意
根据您的系统,运行这些测试可能需要几十秒钟。如果任何测试失败,请检查控制台的输出。在大多数情况下,您可以在这里找到有关需要更改哪些内容才能通过测试的必要信息。
要卸载 Git 钩子,请从您的源代码检出目录的顶层运行以下命令
python scripts/hooks/uninstall.py
6. 本地构建和安装#
安装完所有必需的依赖项后,构建和安装 Bokeh 和 BokehJS 的最简单方法是使用 pip。pip
是 Python 的包安装程序,当您 设置 conda 环境 时会自动安装。在运行 pip
之前,请确保您已激活 bkdev
环境。
有两种使用 pip
安装 Bokeh 本地开发版本的方法
pip install -e .
Bokeh 将被安装为引用您的本地源目录。您对 Python 源代码所做的任何更改都将立即生效,而无需任何其他步骤。这是处理 Bokeh 代码库时推荐的模式。
pip install .
Bokeh 将安装在您的本地 Python
site-packages
目录中。在这种模式下,对 Python 源代码的任何更改都不会生效,直到您再次运行pip install .
。
运行这两个命令中的任何一个也会构建和安装本地版本的 BokehJS。如果您想跳过构建新版本的 BokehJS 而改用不同的本地版本,请设置 BOKEHJS_ACTION
环境变量:BOKEHJS_ACTION="install" pip install -e .
注意
您需要每次 BokehJS 源代码更改时都重建 BokehJS。这可能是必要的,因为您自己进行了更改,或者因为您从 GitHub 拉取了更新的代码。重新运行 pip install -e .
以构建和安装 BokehJS。
有时,JavaScript 依赖项列表也会更改。如果发生这种情况,您需要在重建 BokehJS 之前重新运行4. 安装 Node 包 部分中的说明。
7. 设置环境变量#
Bokeh 使用 环境变量 来控制库的不同部分如何操作和交互的几个方面。
要了解有关 Bokeh 中所有可用环境变量的信息,请参阅参考指南中的 bokeh.settings。
BOKEH_RESOURCES
#
在处理 Bokeh 的代码库时,需要注意的最重要的环境变量是 BOKEH_RESOURCES
。此变量控制要使用哪个版本的 BokehJS。
默认情况下,Bokeh 从内容分发网络 (CDN) 下载 BokehJS 的任何必要 JavaScript 代码。如果您修改了任何 BokehJS 代码并在本地构建了 BokehJS,则需要更改 Bokeh 加载这些 JavaScript 资源的方式。除非您将 Bokeh 配置为使用您的本地 BokehJS 版本而不是来自 CDN 的默认版本,否则您将看不到对 BokehJS 的本地更改的任何效果。
请注意,BOKEH_RESOURCES
仅应在运行示例时设置。当您运行测试或构建文档时,您不应设置此变量(或者如果已设置,则取消设置),否则可能会收到错误。
您可以使用以下三个选项来使用本地版本的 BokehJS
- 使用
absolute-dev
将
BOKEH_RESOURCES
设置为absolute-dev
以从本地安装的 Bokeh 库的 static 目录加载 JavaScript 资源。这样,Bokeh 还将使用未压缩的 BokehJS 资源,以提高可读性。export BOKEH_RESOURCES=absolute-dev
$Env:BOKEH_RESOURCES = "absolute-dev"
set BOKEH_RESOURCES=absolute-dev
- 使用
inline
将
BOKEH_RESOURCES
设置为inline
以将所有必要的本地 JavaScript 资源直接包含在生成的 HTML 文件中。export BOKEH_RESOURCES=inline
$Env:BOKEH_RESOURCES = "inline"
set BOKEH_RESOURCES=inline
- 使用
server-dev
将
BOKEH_RESOURCES
设置为server-dev
以通过 Bokeh 服务器加载本地 BokehJS。首先,启动本地服务器。
BOKEH_DEV=true bokeh static
$Env:BOKEH_DEV = "true" bokeh.exe static
set BOKEH_DEV=true bokeh static
接下来,打开一个新的终端窗口,并将
BOKEH_RESOURCES
设置为server-dev
。export BOKEH_RESOURCES=server-dev
$Env:BOKEH_RESOURCES = "server-dev"
set BOKEH_RESOURCES=server-dev
这样,您就可以访问更多开发功能,例如源映射,以帮助调试原始 TypeScript 而不是编译后的 JavaScript。
有关更多详细信息,请参阅 Resources
。
BOKEH_DEV
#
在使用 Bokeh 代码库时,还有几个其他环境变量很有帮助。本地开发最常用的设置已组合在变量 BOKEH_DEV
中。
要启用开发设置,请将 BOKEH_DEV
设置为 true
export BOKEH_DEV=true
$Env:BOKEH_DEV = "true"
set BOKEH_DEV=true
将 BOKEH_DEV
设置为 true
意味着以下设置
BOKEH_BROWSER=none
BOKEH_LOG_LEVEL=debug
BOKEH_MINIFIED=false
BOKEH_PRETTY=true
BOKEH_PY_LOG_LEVEL=debug
BOKEH_RESOURCES=server
但并不完全等同于单独设置这些变量。
这样,Bokeh 将使用本地和未压缩的 BokehJS 资源,默认日志级别会提高,生成的 HTML 和 JSON 代码将更具可读性,并且每次调用 show()
时,Bokeh 都不会打开新的浏览器窗口。
注意
设置 BOKEH_DEV=true
会启用 BOKEH_RESOURCES=server
,这需要一个资源服务器。如果需要,用户可以通过单独运行 BOKEH_DEV=true bokeh static
(在 Linux 上) 命令(例如,在另一个终端或控制台中)来提供这样的服务器。
虽然使用服务器资源进行开发是最稳健的方法,但用户可以通过将 BOKEH_RESOURCES
设置为 inline
来稍微简化他们的设置。
8. 测试本地设置#
运行以下测试以检查所有内容是否已正确安装和设置
测试 Bokeh 核心#
首先,使用以下命令来测试 Bokeh 安装
python -m bokeh info
你应该看到类似于以下的输出
Python version : 3.12.3 | packaged by conda-forge | (main, Apr 15 2024, 18:38:13) [GCC 12.3.0]
IPython version : 8.19.0
Tornado version : 6.3.3
NumPy version : 2.0.0
Bokeh version : 3.5.1
BokehJS static path : /opt/anaconda/envs/test/lib/python3.12/site-packages/bokeh/server/static
node.js version : v20.12.2
npm version : 10.8.2
jupyter_bokeh version : (not installed)
Operating system : Linux-5.15.0-86-generic-x86_64-with-glibc2.35
运行示例#
接下来,运行一些 Bokeh 自带的独立示例。
确保 环境变量 BOKEH_RESOURCES
设置为 absolute-dev
或 inline
,以便使用本地版本的 BokehJS。在 *source checkout* 目录中,运行以下命令
BOKEH_RESOURCES=inline python examples/basic/data/transform_markers.py
$Env:BOKEH_RESOURCES = "inline"
python.exe .\examples\basic\data\transform_markers.py
set BOKEH_RESOURCES=inline
python examples\basic\data\transform_markers.py
这会在本地创建一个文件 transform_markers.html
。当你在 Web 浏览器中打开此文件时,它应该显示此可视化效果

运行 Bokeh 服务器#
使用 Bokeh 的另一种方式是作为 服务器。将 环境变量 BOKEH_DEV=false
设置为 false,并在 *source checkout* 目录中运行 bokeh serve
命令
BOKEH_DEV=false python -m bokeh serve --show examples/server/app/sliders.py
$Env:BOKEH_DEV = "False"
python.exe -m bokeh serve --show .\examples\server\app\sliders.py
set BOKEH_DEV=false
python -m bokeh serve --show examples\server\app\sliders.py
这应该会打开一个浏览器,其中包含一个交互式图形

所有滑块都允许对正弦波进行交互式控制,每次更新都会使用新参数重新绘制线条。--show
选项会打开一个 Web 浏览器。Bokeh 服务器的默认 URL 是 localhost:5006
。
故障排除#
更新现有的开发环境并不总是按预期工作。作为一般规则,请确保你的 conda 环境、Node 包 和 本地构建 始终是最新的。
以下列表包含你在设置开发环境时可能遇到的一些常见问题的解决方案
Git 标签丢失 (KeyError: '0.0.1'
)
有时,如果 Bokeh 仓库的标签尚未克隆到你的本地目录,你可能会遇到问题。例如,你可能会在控制台输出中看到 KeyError: '0.0.1'
。
要检查必要的标签是否存在,请运行以下命令
git tag -l | tail
git tag -l
git tag -l
如果没有标签存在,请确保你按照 将 Bokeh 仓库设置为额外的上游仓库 的步骤操作。
Git 提交由于行尾符失败 (test_code_quality.py
, File contains carriage returns
)
在 Windows 系统上,当你尝试将本地分支推送到 GitHub 上的远程分支时,可能会收到 File contains carriage returns at end of line: <file path>
错误。这是因为 Bokeh 仅允许 LF 行尾符,而某些基于 Windows 的工具可能会添加 CR LF 行尾符。
如果你看到此错误,请尝试运行以下命令:git config --global core.autocrlf false
。运行此命令后,删除并重新克隆你的 Fork 仓库(请参阅 2. Fork 和克隆仓库)
此命令将 git 配置为始终保留原始的仅 LF 的换行符。有关其他选项,请参阅 GitHub 文档 或 Git 配置文档。
从旧版本更新后出现错误
如果在更新旧环境后仍然不断收到错误,请使用 conda remove --name bkdev --all
,删除本地 bokeh
文件夹,并按照本指南中从 开头 开始的步骤重新安装开发环境。
克隆时网络连接缓慢
如果你在尝试克隆我们的仓库时遇到网络连接缓慢或超时的情况,请考虑执行**浅克隆**。此方法下载的提交较少,从而加快克隆过程并减少传输的数据量。
对于带宽有限或克隆速度缓慢的贡献者来说,使用浅克隆可能是一种有效的解决方法。但是,请注意其局限性,并了解如何在必要时将其转换回完整克隆。
要创建仓库的浅克隆,请运行
git clone --depth <number-of-commits> git@github.com:bokeh/bokeh.git
git clone --depth <number-of-commits> https://github.com/bokeh/bokeh.git
将 <number-of-commits>
替换为你希望克隆的提交数量。
例如,要仅克隆最新的提交
git clone --depth 1 git@github.com:bokeh/bokeh.git
git clone --depth 1 https://github.com/bokeh/bokeh.git
如果你只对特定分支的历史记录感兴趣,可以将 `--single-branch` 选项与 `--depth` 结合使用,以进一步将克隆限制为单个分支。运行
git clone --depth 1 --branch <branch-name> --single-branch git@github.com:bokeh/bokeh.git
git clone --depth 1 --branch <branch-name> --single-branch https://github.com/bokeh/bokeh.git
浅克隆的局限性
虽然浅克隆可能非常有用,但它也有一些局限性
Git 操作受限: 需要完整历史记录的操作(例如,某些合并策略、生成全面的日志)将不可用。
分支限制: 如果你没有克隆所有分支(--single-branch 选项),则在没有额外步骤的情况下,可能无法在分支之间切换。
不准确的版本信息: 当仓库被浅克隆时,通过
bokeh.__version__
检索的版本信息可能会显示不正确的数据,例如 ‘dev’ 标签。
将浅克隆转换为完整克隆
如果你发现你需要访问仓库的完整历史记录才能执行更复杂的任务,则可以通过获取剩余的历史记录将浅克隆转换为完整克隆
要将克隆深度增加特定数量的提交
git fetch --deepen=<additional-commits>
要将浅克隆完全转换为完整克隆(获取所有历史记录)
git fetch --unshallow
此命令将下载仓库的其余历史记录,将你的浅克隆转换为常规的完整克隆。
有关运行和安装 Bokeh 的更多信息,请查看 贡献者可用的其他资源。请随时在 Bokeh Discourse 或 Bokeh 的贡献者 Slack 上提问。