设置开发环境#
Bokeh项目由两个主要组件组成:用Python编写的Bokeh包源代码,以及用TypeScript编写的BokehJS客户端库。
因此,您需要设置两个环境来为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 主仓库的分支。在创建分支时,请确保取消选中限制复制到特定分支的复选框(例如“仅复制 branch-3.2 分支”)。有关创建分支的更多信息,请参阅Fork a repo在GitHub 帮助中。
接下来,将您想要使用的Bokeh仓库版本克隆到硬盘上的本地文件夹中。使用git clone
或按照克隆分叉仓库的说明在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
来设置环境并安装所有必要的包。“test”环境文件按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/
。每当测试环境中的依赖项发生变化时,更新您的本地环境是必要的。这可能在主Bokeh存储库中的环境文件更新时发生,或者当您切换分支以处理不同问题时发生,例如。
4. 安装Node包#
构建 BokehJS 还需要使用 Node Package Manager (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. 设置预提交#
Bokeh 使用 pre-commit 来帮助你在提交时防止一些常见的错误。
要在本地设置预提交,请从您的源代码检出目录的顶层运行以下命令:
python scripts/hooks/install.py
这将配置 pre-commit 使用两个 Git 钩子,每当您向 Bokeh 的 GitHub 仓库推送提交时,这些钩子将检查您的代码:
- Codebase tests
git-commit 将运行 Bokeh 的 代码库测试 来检查 代码库质量问题,例如空格和导入。这包括 使用 Ruff、ESLint 和 isort 进行测试。
- Protected branches
git-commit 将确保您不会意外地将提交推送到 Bokeh 的受保护分支
main
和branch-x.y
在 GitHub 上。
注意
根据您的系统,运行这些测试可能需要几十秒。如果有任何测试失败,请检查控制台的输出。在大多数情况下,这是您将找到有关需要通过测试所需更改的必要信息的地方。
要卸载 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:
- Use
absolute-dev
将
BOKEH_RESOURCES
设置为absolute-dev
以从本地安装的 Bokeh 库的静态目录加载 JavaScript 资源。这样,Bokeh 还将使用未压缩的 BokehJS 资源以提高可读性。export BOKEH_RESOURCES=absolute-dev
$Env:BOKEH_RESOURCES = "absolute-dev"
set BOKEH_RESOURCES=absolute-dev
- Use
inline
将
BOKEH_RESOURCES
设置为inline
以直接在生成的 HTML 文件中包含所有必要的本地 JavaScript 资源。export BOKEH_RESOURCES=inline
$Env:BOKEH_RESOURCES = "inline"
set BOKEH_RESOURCES=inline
- Use
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
这样,您可以访问更多的开发功能,例如 source maps 来帮助调试原始的 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。在源代码检出目录中,运行
以下命令:
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
。当你在网页浏览器中打开这个文件时,它应该显示以下可视化内容:

运行Bokeh服务器#
另一种使用Bokeh的方法是作为服务器。设置
环境变量
BOKEH_DEV=false
并在源代码检出目录中运行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
选项会打开一个网页浏览器。Bokeh 服务器的默认 URL 是 localhost:5006
。
故障排除#
更新现有的开发环境并不总是如预期那样工作。作为一般规则,请确保您的 conda 环境, Node 包, 和 本地构建 始终保持最新。
以下列表包含在设置开发环境时可能遇到的常见问题的解决方案:
Git tags missing (KeyError: '0.0.1'
)
有时,如果Bokeh仓库的标签没有被克隆到本地目录,您可能会遇到问题。例如,您可能会在控制台输出中看到KeyError: '0.0.1'
。
要检查必要的标签是否存在,请运行以下命令:
git tag -l | tail
git tag -l
git tag -l
如果没有标签存在,请确保您按照以下步骤操作 将Bokeh仓库设置为额外的上游。
Git commit fails due to line endings (test_code_quality.py
, File contains carriage returns
)
在Windows系统上,当您尝试将本地分支推送到GitHub上的远程分支时,可能会遇到File contains carriage returns at end of line:
错误。这是因为Bokeh只允许LF行尾,而一些基于Windows的工具可能会添加CR LF行尾。
如果你看到这个错误,尝试运行以下命令:
git config --global core.autocrlf false
。运行此命令后,删除并
重新克隆你的分叉仓库(参见 2. 分叉并克隆仓库)
Errors after updating from an older version
如果在更新旧环境后仍然遇到错误,请使用
conda remove --name bkdev --all
,删除本地的 bokeh
文件夹,
并按照本指南中的步骤从头开始重新安装开发环境
the beginning。
Slow network connections when cloning
如果您在尝试克隆我们的仓库时遇到网络连接缓慢或超时问题,请考虑执行浅克隆。这种方法下载的提交较少,从而加快了克隆过程并减少了数据传输量。
使用浅克隆可以成为带宽有限或克隆速度较慢的贡献者的有效解决方案。然而,请注意其局限性,并知道如何在必要时将其转换回完整克隆。
要创建存储库的浅克隆,请运行:
git clone --depth <number-of-commits> git@github.com:bokeh/bokeh.git
git clone --depth <number-of-commits> https://github.com/bokeh/bokeh.git
将
替换为您希望克隆的提交次数。
例如,仅克隆最新的提交:
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上提问。