pydeck 文档生成管线:从示例脚本到 Sphinx 文档画廊的三层自动化流程
2026/9/14 8:20:52 网站建设 项目流程

pydeck 文档生成管线:从示例脚本到 Sphinx 文档画廊的三层自动化流程

【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl

本文以 bindings/pydeck/docs/scripts/README.md 为核心,系统讲解 pydeck 官方文档站中“示例画廊”的自动化生成机制:embed_examples.py如何把示例脚本转成内嵌源码与交互画面的 .rst 页面、generate_grid_html.py如何聚合生成画廊落地页、snap_thumbnails.py如何为每个示例截取缩略图。读完本文,你可以独立复现整套文档构建流程,并按 README 给出的标准步骤把一个新的示例图层加入 pydeck 画廊。

1. 管线概览:三层脚本与目录约定

bindings/pydeck/docs/scripts/README.md 开篇即点明定位:这是一个“为生成 pydeck 文档服务的辅助脚本集”。整套管线由三个阶段组成,每个阶段对应一个脚本:

阶段脚本产物
1. 页面嵌入embed_examples.py一组 .rst 文件,每个文件同时内嵌示例源码与可交互的 HTML 实例(点击画廊单元格后看到的页面)
2. 画廊网格generate_grid_html.pygrid.html,以缩略图为单元、按分组组织的链接网格,即 pydeck 文档站的落地页
3. 缩略图snap_thumbnails.py画廊中使用的 .png 缩略图,从示例的实际渲染结果截图生成

目录约定集中定义在 const.py,理解它是理解整条管线的前提:

  • EXAMPLES_DIR:pydeck 示例目录 bindings/pydeck/examples(L7);
  • EXAMPLE_GLOB:递归收集examples/下(含子目录)的全部*.py示例文件(L13)。子目录会成为画廊上的分组标签,而网格、页面、缩略图的命名仍以每个文件的基本名为键,因此按子文件夹组织示例只影响分组、不破坏命名体系(L9-L12 的注释说明了这一设计);
  • GALLERY_DIR:画廊 .rst 页面目录docs/gallery/(L50);
  • HTML_DIR:画廊 HTML 文件目录docs/gallery/html/(L52);
  • LOCAL_IMAGE_DIR:缩略图目录docs/gallery/images/(L54);
  • DECKGL_URL_BASE:deck.gl API 参考文档基址,用于给图层示例页挂回链(L58)。

此外,const.py 还定义了网格分组逻辑:DEFAULT_GROUP = "Layers"表示直接放在examples/根下的示例归入 “Layers” 分组;GROUP_ORDER = ["Layers", "Extensions"]固定前两个分区的顺序,其余分组按字母序排列。grouped_examples()据此返回有序(section_label, [snake_case 名称])列表——例如仓库中的 extensions 子目录(含 8 个扩展示例)与 post_processing 子目录(19 个示例)就各自形成独立分区。

还有一处 README 未提及但同样重要的环节:update_images_rst.py 会基于EXAMPLE_NAMES重新渲染 docs/images.rst。该文件头部注释表明其职责是“把示例缩略图注册进_static目录,并把示例页面登记进一个隐藏 toctree”——这正是 Sphinx 能收录gallery/images/*.pnggallery/*.rst的依据,当前仓库中的 images.rst 即为该脚本的产物(含a5_layerarc_layerbinary_transport等条目的.. image::注册与.. toctree::列表)。

2. 第一阶段:embed_examples.py——示例脚本到 .rst 页面

embed_examples.py 的模块 docstring 说明了它的作用:“这些文件就是你在 pydeck 画廊页点击某个网格单元格后看到的页面”。核心函数create_rst()(L18-L47)对每个示例文件做四件事:

  1. 命名规范化to_snake_case_string()去掉路径与扩展名得到 snake_case 资产名(utils.py L13-L15);若名称中含layer,则拼出 deck.gl 文档回链(L21-L25)。源码注释坦承这一判断“相当粗糙”,后续计划扩展以支持 views 等对象——因此回链只对图层示例生效;
  2. 运行示例并归档 HTML:通过subprocess执行python {示例文件}; mv {html} {HTML_DIR}(L29-L34)。示例脚本本身在顶层目录生成同名.html(deck 前端由 Jupyter widget 的write_notebook等机制导出),随后被移入docs/gallery/html/
  3. 渲染 .rst 页面:读取示例 Python 源码,用 templates.py 中的DOC_TEMPLATE(L46-L84)生成文档源。该模板的结构值得注意:
    • 可选的 deck.gl 文档外链(.. raw:: html中的<a id="deck-link">);
    • .. raw:: html :file: ./html/{snake_name}.html——把上一步归档的 HTML 文件原样内嵌,实现“文档页里直接运行示例”;
    • 内联样式约束:#deck-container { height: 50vh; width: 100% }以及让.wy-nav-content撑满宽度的max-width: 100% !important,保证交互实例在 Sphinx 布局中有足够画幅;
    • “Source” 小节,以.. code-block:: python输出完整示例源码;
  4. 写盘:输出到docs/gallery/{资产名}.rst

入口main()(L50-L56)使用multiprocessing.Pool(processes=4)并行处理EXAMPLE_GLOB中全部文件,并在转换前mkdir -p建好 HTML 输出目录;若一个示例文件都找不到会直接抛异常终止。页面标题由to_presentation_name()(utils.py L4-L10)生成:名称含layerview时做驼峰化处理(并特判把json显示为Json),其余情况做 title case。

对应的构建入口是 docs/Makefile 的html-embeds目标,它直接调用python scripts/embed_examples.py

3. 第二阶段:generate_grid_html.py——画廊落地页

generate_grid_html.py 逻辑非常薄:调用HTML_TEMPLATE.render(grouped_examples=grouped_examples(), ...)并把结果写入docs/gallery/grid.html(L10-L13)。复杂度都在模板侧,HTML_TEMPLATE(templates.py L3-L43)要点:

  • 外层用 CSS Grid 布局:grid-template-columns: repeat(3, 1fr)grid-gap: 20px,即三列卡片;
  • 按分组循环:每个分组输出<h2 class='gallery-section-title'>标题(分节顺序与标签即来自第 1 节所述grouped_examples());
  • 每个单元格链接到./gallery/{名称}.html,卡片内容是 200px 宽的缩略图./_images/{名称}.png加标题文本to_presentation_name(名称)
  • 还带了一个悬停特效filter: hue-rotate(3.142rad)

注意链接的相对关系:grid.html位于gallery/内,页面链接指向gallery/{name}.html、图片指向_images/(Sphinx 构建后_images为静态资源目录),与embed_examples.py归档的 HTML、snap_thumbnails.py产出的 PNG 在命名上完全对齐——“以文件基本名为键”的约定在这里收束。该阶段由 Makefile 的html-grid-page目标触发(Makefile L29-L31),它会先执行html-embeds再运行网格生成,保证页面与网格同步更新。

4. 第三阶段:snap_thumbnails.py——Playwright 截图管线

snap_thumbnails.py 为每个示例生成画廊缩略图,其 docstring 直接给出用法(L3-L10):

# 安装依赖(当前代码基线) uv pip install playwright Pillow playwright install chromium # 在 docs/ 目录下 make html-thumbnails # 为全部示例截图 python scripts/snap_thumbnails.py ../examples/widgets.py # 单个示例

关键实现细节:

  • 依赖切换:脚本在导入playwrightPIL失败时会打印安装提示并退出(L21-L28)。注意 README 中旧版步骤写的是pip install pyppeteer && pip install Image,而当前源码已迁移到 Playwright + Pillow,实操时应以 docstring 与源码为准;
  • 大示例白名单LARGE_EXAMPLES = ("bitmap_layer", "icon_layer", "heatmap_layer", "terrain_layer", "maplibre_globe")(L32)。这类示例数据集加载慢,截图时不做networkidle等待,改为固定gotowait_for_timeout(10000);其余示例用wait_until="networkidle", timeout=30000再额外等 3 秒让 deck.gl 完成渲染(L75-L91);
  • 截图流程snap()先经run_example()执行示例脚本、校验退出码与.html产物并移入HTML_DIR,再启动 Chromium(800×600 视口)加载file://页面、wait_for_selector("canvas")确认画布出现后落盘 PNG;外层snap_with_retries()提供 3 次重试(L60-L109);
  • 尺寸压缩shrink_image()用 Pillow 的Image.thumbnail((400, 300), Image.LANCZOS)原地压缩为 400×300 缩略图(L112-L121);
  • 失败语义main()汇总失败列表,只要有任何一个缩略图失败就以RuntimeError终止(L123-L140),保证画廊不出现“有格子无图”的半成品状态。

批量执行的构建入口是 docs/Makefile 的html-thumbnails目标(uv run python scripts/snap_thumbnails.py)。

5. 实操:按 README 步骤把新图层加入画廊

README 的 “Adding a new layer to the gallery” 一节给出了官方流程,结合当前源码可执行如下(以下均在bindings/pydeck/docs/目录下操作):

# 0) 安装截图依赖(README 原文:pip install pyppeteer && pip install Image; # 当前源码已迁移到 Playwright,请按 snap_thumbnails.py docstring 安装) uv pip install playwright Pillow && playwright install chromium # 1) 把新示例(如 examples/arc_layer.py)注册进 docs/images.rst # images.rst 由 update_images_rst.py 自动生成(注册缩略图 + 隐藏 toctree) python scripts/update_images_rst.py # 2) 生成内嵌页面与画廊网格 make html-grid-page # 3) 为新示例创建缩略图 python scripts/snap_thumbnails.py ../examples/arc_layer.py # 若需要为多个示例文件建缩略图: make html-thumbnails

各步骤与源码的对应关系:

  1. 注册images.rst:README 要求手工维护 docs/images.rst,而该文件实际由 update_images_rst.py 从EXAMPLE_NAMES重新渲染,新增示例后重新生成即可保证图片注册与 toctree 条目齐全;
  2. make html-grid-page:等价于先跑embed_examples.py(新示例获得gallery/{名称}.rstgallery/html/{名称}.html)再跑generate_grid_html.py(网格出现新单元格);
  3. 缩略图:单个示例走python scripts/snap_thumbnails.py ../examples/{名称}.py,批量走make html-thumbnails;产物落入docs/gallery/images/{名称}.png,与网格模板中./_images/{名称}.png的引用同名对齐。

6. 小结:管线约定与扩展点

整条管线的可维护性建立在几条严格约定之上:

  • 命名即契约:示例文件基本名(snake_case)贯穿 HTML、.rst、PNG 与 toctree 四个产物,to_snake_case_string/to_presentation_name只负责展示层转换;
  • 分组即目录examples/子目录名(下划线转空格后 title-case)决定画廊分区,GROUP_ORDER固定 “Layers”“Extensions” 的展示顺序;
  • 失败即终止embed_examples.py对“无示例文件”抛异常,snap_thumbnails.py对任何缩略图失败抛RuntimeError,避免文档站以不完整状态发布。

常见扩展点:为大数据集示例加长等待时间(修改LARGE_EXAMPLES元组)、调整缩略图尺寸(THUMBNAIL_SIZE = (400, 300))、调整网格列数(HTML_TEMPLATE中的repeat(3, 1fr)),以及把embed_examples.py中粗糙的layer字符串判断扩展为按视图等对象类型挂 deck.gl 回链。所有相关脚本集中在 docs/scripts/ 目录,配合 docs/Makefile 的三个html-*目标即可完成一次完整的文档画廊再生成。

【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询