- 后端
- 微服务
【免费下载链接】jupyterhub
Multi-user server for Jupyter notebooks
本文基于 JupyterHub 仓库中的贡献者文档页(docs/source/contributing/docs.md)展开,讲清楚 JupyterHub 文档的完整技术栈——Sphinx 构建、MyST 格式源码、docs/source目录结构——并给出在本地复现官方文档站的两套构建方式(nox一键实时预览、Makefile/sphinx-build手动构建)以及仓库实际使用的配置细节。读完后你可以独立在本地搭建文档构建环境、修改并验证文档渲染效果,并遵循项目既定的书写约定。
文档技术栈:Sphinx 构建 + MyST 源码
JupyterHub 的文档用 Sphinx 构建。文档源码以 MyST(Markedly Structured Text)格式编写,统一存放在docs/source目录下,再由 Sphinx 转换为人可读的多种输出格式。这一结构可以从三处源码直接印证:
- docs/source/index.md 是文档根页,conf.py 中设置了
root_doc = "index"; source_suffix = [".md"]表明整个文档站只接受 Markdown(MyST)源文件,不混用 reST 源文件,但default_role = "literal"保留了 reST 中单反引号表示行内代码的习惯写法;- docs/source/conf.py 中的
myst_heading_anchors = 2会为 H1/H2 标题自动生成锚点,myst_enable_extensions额外开启了attrs_inline、colon_fence、deflist、fieldlist、substitution等 MyST 扩展语法(如{ref}、{class}角色和:::{note}围栏)。
构建扩展一览
从 conf.py 的extensions列表看,文档构建依赖以下扩展,其安装由 docs/requirements.txt 统一声明:
| 扩展 / 依赖 | 作用 |
|---|---|
sphinx.ext.autodoc | 从 Python 源码自动生成 API 文档(见docs/source/reference/api/各页) |
sphinx.ext.intersphinx | 跨项目引用外部 API 文档(python、tornado、jupyter-server、nbgitpuller、aiohttp) |
sphinx.ext.napoleon | 解析 Google/NumPy 风格 docstring |
autodoc_traits(autodoc-traits) | 自动文档化 JupyterHub 基于 traitlets 的配置属性 |
sphinx_copybutton | 为代码块添加"复制"按钮 |
sphinx-jsonschema | 渲染 REST API 的 JSON Schema 内容 |
sphinxext.opengraph | 生成社交分享用的 OpenGraph 元数据 |
sphinxext.rediraffe | 文档移动/改名后的自动重定向,防止链接失效 |
jupyterhub_sphinx_theme | Jupyter 统一风格主题 |
myst_parser(>=0.19) | 解析 MyST 语法 |
docs/requirements.txt 中还有一个值得注意的约定:文件头注释明确说明文档构建"要求 jupyterhub 本身已安装,但不在这里声明该依赖,因为这往往会导致重复安装",构建工具版本约束为sphinx>=4,<9,低版本 Python 下通过tomli兜底解析pyproject.toml。
本地构建文档
官方建议:在你撰写或修改的文档合入前,先在本地构建并验证渲染结果。前提是系统已安装 Python 和 Git(开发环境完整要求见 开发环境搭建指南;从pyproject.toml看,当前项目要求 Python >= 3.10,而文档中的{{python_min}}/{{node_min}}占位符正是由 conf.py 从该值与硬编码值动态替换而来)。
方式一:用nox构建并实时预览
仓库使用nox命令行工具统一管理文档构建。核心命令是:
nox -s docs -- live这一条命令会安装文档依赖、构建文档,并启动一个带实时刷新的预览服务器。其背后逻辑全部体现在 noxfile.py 的docs会话中:
@nox.session(default=False) def docs(session): """ Build the documentation and, optionally with '-- live', run a web server. """ docs_dir = "docs" source_dir = os.path.join(docs_dir, "source") # where conf.py is located data_dir = os.path.join(source_dir, "_data") output_dir = os.path.join(docs_dir, "_build") session.install("--editable", ".") session.install("-r", os.path.join(docs_dir, "requirements.txt")) doc_build_default_args = ["-b", "dirhtml", source_dir, output_dir] if "live" in session.posargs: # For live preview, sphinx-autobuild is used. ... session.install("sphinx-autobuild") cmd = ["sphinx-autobuild"] autobuild_ignore = [output_dir, os.path.join(data_dir, "generated")] for folder in autobuild_ignore: cmd.extend(["--ignore", f"*/{folder}/*"]) cmd.extend(doc_build_default_args) session.run(*cmd) else: session.run("sphinx-build", *doc_build_default_args)从源码结构看,nox -s docs会话做了四件事:
- 以可编辑模式安装 JupyterHub 本体,再安装
docs/requirements.txt; - 固定使用
dirhtml构建器,输出目录为docs/_build; - 追加
-- live参数时,额外安装sphinx-autobuild并启动监视器,保存.md文件即自动重建刷新; - 实时模式会把
docs/_build输出目录和docs/source/_data/generated加入忽略清单(--ignore),避免构建产物变化反过来触发无限重建。
此外nox.options.reuse_existing_virtualenvs = True使 nox 复用已创建的虚拟环境,二次构建不必重复安装依赖。不传live参数时(nox -s docs),行为等同于直接执行sphinx-build -b dirhtml docs/source docs/_build。
方式二:不用nox手动构建
不依赖 nox 时,先在仓库根目录安装文档所需包:
python3 -m pip install --editable . python3 -m pip install -r docs/requirements.txt然后有两种构建入口。
入口 A:sphinx-build直接构建。安装完成后即可运行与 nox 会话相同的底层命令:
python3 -m sphinx -b html docs/source docs/_build/html入口 B:docs/下的 Makefile。docs/Makefile 是 sphinx-quickstart 生成的标准 Makefile,并加入了本项目自定义目标。关键配置:
SPHINXOPTS ?= --color -W --keep-going SPHINXBUILD ?= sphinx-build SOURCEDIR = source BUILDDIR = _build注意SPHINXOPTS中的-W --keep-going:-W把文档构建中的警告提升为错误,因此任何失效的链接、拼写问题(若启用拼写检查)都会让构建失败——这就是 JupyterHub 文档保持零警告纪律的机制来源。
Makefile 的目标分两类:
- 通用目标(
%: Makefile捕获规则):任意未显式定义的目标都转发给sphinx-build -M <目标>,例如make html、make clean、make linkcheck(全站外链检查)、make spelling(拼写检查); - 自定义目标:
html: metrics $(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS) ... metrics: source/includes/metrics_table.md source/includes/metrics_table.md: python3 generate-metrics.pymake html依赖metrics目标:它先运行 docs/generate-metrics.py 生成指标文档页所需的source/includes/metrics_table.md,再执行 Sphinx 构建。docs/Makefile 中还定义了devenv目标——在make html之上启动sphinx-autobuild -b html --open-browser,自动打开浏览器并在文件变化时热重建,适合长时间写作。
从源码结构看,Makefile 与 conf.py 之间存在一条隐藏依赖链:conf.py 中有一段 Read The Docs 适配代码
if os.environ.get("READTHEDOCS"): subprocess.check_call(["make", "metrics", "scopes"], cwd=str(docs))即云端构建(RTD 直接跑sphinx-build而不经过make html)会由 conf.py 手动补跑make metrics和make scopes(后者对应 docs/source/rbac/generate-scope-table.py 生成 RBAC scope 表格)。Makefile 注释也提醒:若修改了html目标的前置步骤,必须同步更新 conf.py 中的这段 RTD 代码,否则本地构建与云端构建行为会分叉。
文档站的关键配置机制
以下机制虽然不在贡献者文档页中展开,但直接影响文档作者需要知道的行为,均出自 docs/source/conf.py。
自定义指令:让文档内容与代码版本保持同步
conf.py 定义并注册了三个 Sphinx 自定义指令(app.add_directive(...)),它们在实际构建时调用 JupyterHub 代码动态生成内容,避免手写文档与代码漂移:
jupyterhub-generate-config(ConfigDirective):实例化JupyterHub()后调用generate_config_file(),把当前版本的完整配置文件生成内容嵌入文档(用于 配置参考页),并把输出中的$HOME路径脱敏;jupyterhub-help-all(HelpAllDirective):捕获--help-all的完整输出作为代码块嵌入文档;jupyterhub-rest-api-links(RestAPILinksDirective):解析 docs/source/_static/rest-api.yml,为每个 REST 操作的operationId生成可被{ref}引用的锚点,供文档正文精确链接到 Redoc 渲染的 API 文档。
文档重定向:rediraffe
为避免移动文档后旧链接 404,项目启用了sphinxext.rediraffe。conf.py 中的配置为:
rediraffe_branch = os.environ.get("REDIRAFFE_BRANCH", "main") rediraffe_redirects = "redirects.txt" rediraffe_auto_redirect_perc = 80重定向记录全部集中在 docs/source/redirects.txt,例如"changelog.md" "reference/changelog.md"、"admin/upgrading.md" "howto/upgrading.md",文件末尾还留有 "add future redirects below" 的维护提示。conf.py 注释中给出了三种添加重定向的工作流:手动维护redirects.txt、make rediraffecheckdiff分析差异后人工补充,或make rediraffewritediff自动写入(自动识别阈值为 80% 相似)。
外链检查与拼写检查
linkcheck_ignore列表(conf.py 第 304 行起)列出了linkcheck目标跳过的一批正则:GitHub 锚点、changelog 中大量 PR 链接、example.com示例链接、localhost 等,减少误报噪音;- 拼写检查是可选扩展:conf.py 用
try: import sphinxcontrib.spelling探测,安装后才启用,词表为 docs/source/spelling_wordlist.txt。
文档相关的质量校验测试
docs/test_docs.py 用 pytest 对文档产物做两项硬校验,是文档正确性的自动化防线:
test_rest_api_version_is_updated:断言 jupyterhub/_version.py 中的__version__与rest-api.yml中info.version完全一致,防止 REST API 定义文件版本滞后;test_rest_api_rbac_scope_descriptions_are_updated:重新执行 docs/source/rbac/generate-scope-table.py,然后用git diff --exit-code确认rest-api.yml中 RBAC scope 描述与生成结果零差异,即该文件不允许出现手改漂移。
文档书写约定(Documentation conventions)
贡献者文档页将"约定"声明为一份持续生长的活文档,并欢迎社区补充修订。当前已确立的明确约定如下。
pip调用方式
调用pip有多种写法,JupyterHub 文档中统一推荐:
python3 -m pip这样能显式地使用你当前正在用的python3可执行文件对应的 pip,是"最不容易出问题的调用方式",因为它几乎不会遇到python3与pip来自不同环境的错配(例如系统pip指向 Python 2,或 venv 未激活时误装到别处)。项目自身文档也一贯遵守该约定,例如上文给出的安装命令均写作python3 -m pip install --editable .。
其他可观察到的隐性约定
结合docs/source的实际用法,以下惯例在现有文档中普遍存在,修改文档时保持一致即可:
- 源码文件统一为
.md(MyST);标题锚点由myst_heading_anchors = 2生成,页内引用使用 MyST 角色如{ref}、{class}而非手写锚点; - 目录组织按迪克森(Diátaxis)风格分为
tutorial/、howto/、explanation/、reference/、faq/、contributing/六类,见 docs/source/index.md; - 构建警告视为错误(
-W),新文档应确保零警告、通过make linkcheck与拼写检查。
小结
贡献 JupyterHub 文档的完整本地工作流为:按 开发环境搭建指南 装好 Python 与 Git → 执行nox -s docs -- live启动实时预览(或python3 -m pip install --editable . && python3 -m pip install -r docs/requirements.txt后走 docs/Makefile /sphinx-build)→ 在docs/source下用 MyST 编写、遵守python3 -m pip等书写约定 → 依赖-W严格构建、make linkcheck/make spelling与 docs/test_docs.py 的自动化校验保证质量。核心源码文件为 docs/source/conf.py(构建配置)、noxfile.py(构建自动化)与 docs/Makefile(构建入口),三处均可作为进一步深入文档构建机制的入口。
- 后端
- 微服务
【免费下载链接】jupyterhub
Multi-user server for Jupyter notebooks
相关推荐
PyPTO 文档贡献实战指南:写作规范、目录注册与 Sphinx 本地构建全流程
PyPTO 文档贡献实战指南:写作规范、目录注册与 Sphinx 本地构建全流程 PyPTO(Parallel Tensor/Tile Operation)是
人工智能编译器模型编译深度学习高性能计算CANNAscendpython-guide 文档贡献指南:Sphinx 构建、本地预览与写作风格规范全解析
python guide 文档贡献指南:Sphinx 构建、本地预览与写作风格规范全解析 导读 本文基于 CONTRIBUTING.md https://lin
文档教程Cutter 文档贡献指南:Sphinx 文档体系、写作方向与本地构建全流程
Cutter 文档贡献指南:Sphinx 文档体系、写作方向与本地构建全流程 Cutter(基于 Rizin 的开源逆向工程平台)的官方文档长期面临内容不完善的
应用安全桌面应用开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考