执行并缓存#

MyST-NB 可以通过 [jupyter-cache] 自动运行并缓存项目中包含的笔记本。笔记本可以在每次构建文档时运行,也可以在本地缓存,以便仅在代码单元格发生变化时重新运行。

执行和缓存行为可以通过全局或文件级别的配置进行控制,如 配置部分 所述。请参阅以下部分,了解每个配置选项及其作用的详细说明。

笔记本执行模式#

要触发笔记本页面的执行,可以使用全局的 nb_execution_mode 配置项,或针对单个文件的 execution_mode 配置项:

模式

描述

off

不执行笔记本

force

始终执行笔记本(在解析之前)

auto

执行缺少输出的笔记本(在解析之前)

cache

执行笔记本并从缓存中存储/检索输出

inline

在解析期间执行笔记本(允许变量评估)

默认情况下,此项设置为:

nb_execution_mode = "auto"

这只会执行至少缺少一个输出的笔记本。如果笔记本的 所有 输出都已填充,则不会执行它。

要强制执行所有笔记本,无论其输出如何,请将上述配置值更改为:

nb_execution_mode = "force"

要使用 [jupyter-cache] 缓存执行输出,请将上述配置值更改为:

nb_execution_mode = "cache"

查看 缓存执行结果 了解更多信息。

要在解析期间内联执行笔记本,请将上述配置值更改为:

nb_execution_mode = "inline"

这允许使用 eval 角色/指令来嵌入变量,这些变量从执行内核中评估,并内联到 Markdown 中。

查看 内联变量评估(eval) 了解更多信息。

要关闭笔记本执行,请将上述配置值更改为:

nb_execution_mode = "off"

排除笔记本不执行#

要排除某些文件模式不执行,请使用以下配置:

nb_execution_excludepatterns = ['list', 'of', '*patterns']

任何与 nb_execution_excludepatterns 中某一项匹配的文件都不会被执行。

缓存执行结果#

如上所述,您可以通过设置以下选项来缓存执行笔记本页面的结果:

nb_execution_mode = "cache"

在这种情况下,当页面被执行时,其输出将存储在本地数据库中。这可以确保文档中的输出是最新的,同时通过避免不必要的重新执行来节省时间。它还允许您将 .ipynb 文件(或其等效的 .md 文件)存储在 git 仓库中 而不包含其输出,但在构建站点时仍然可以利用缓存来节省时间。

小技巧

您应仅在笔记本具有确定性执行输出时使用此选项:

  • 您使用相同的环境来运行它们(例如,安装的软件包相同)

  • 它们不运行非确定性代码(例如,随机数)

  • 它们不依赖于随时间变化的外部资源(例如,文件或网络连接)

当您重新构建站点时,将会发生以下情况:

  • 自上次构建以来,代码单元格元数据 未发生变化的笔记本将不会重新执行。相反,它们的输出将从缓存中提取并插入到您的站点中。

  • 代码单元格发生任何变化 的笔记本将被重新执行,缓存将更新为新的输出。

默认情况下,缓存将放置在构建文件夹的父目录中。通常,它位于 _build/.jupyter_cache 中,并且也会在构建日志中指定,例如:

Using jupyter-cache at: ./docs/_build/.jupyter_cache

您还可以指定要使用的 jupyter 缓存位置的路径:

nb_execution_cache_path = "path/to/mycache"

该路径应指向空文件夹,或者已存在 jupyter 缓存的文件夹。

运行文档构建后,您可以使用以下命令检查缓存的内容:

$ jcache notebook -p docs/_build/.jupyter_cache list

阅读 [jupyter-cache] 了解更多信息。

使用不同的内核名称执行#

如果您需要笔记本使用与实际文件中指定的不同的内核运行,您可以设置全局别名,例如:

nb_kernel_rgx_aliases = {"oth.*": "python3"}

映射键是正则表达式,因此例如 oth.* 将匹配任何以 oth 开头的内核名称。

在临时文件夹中执行#

默认情况下,笔记本运行的命令工作目录(cwd)将是其所在的目录。但是,您可以在 conf.py 中设置 nb_execution_in_temp=True,以更改此行为,使得每次执行时都会创建临时目录并将其用作 cwd。

执行超时#

笔记本的执行由 nbclient 管理。

nb_execution_timeout sphinx 选项定义了每个笔记本单元格允许运行的最长时间(以秒为单位)。如果执行时间超过此限制,将引发异常。默认值为 30 秒,因此在长时间运行的单元格情况下,您可能需要指定更高的值。超时选项也可以设置为 None 或 -1,以取消对执行时间的任何限制。

此全局值也可以通过将此添加到笔记本元数据中,针对每个笔记本进行覆盖:

{
 "metadata": {
  "execution": {
      "timeout": 30
  }
}

在代码单元格中引发错误#

在某些情况下,您可能希望故意展示无法运行的代码(例如,为了显示错误信息)。您可以通过“三个级别”实现这一点:

全局层面,通过在 conf.py 中设置 nb_execution_allow_errors=True

针对每个笔记本(覆盖全局设置),通过将此添加到笔记本元数据中:

{
"metadata": {
  "execution": {
      "allow_errors": true
  }
}

针对每个单元格,通过向代码单元格添加 raises-exception 标签。这可以通过 Jupyter 界面完成,或者通过 {code-cell} 指令实现,如下所示:

```{code-cell}
:tags: [raises-exception]

print(thisvariabledoesntexist)
```

这将生成:

print(thisvariabledoesntexist)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[1], line 1
----> 1 print(thisvariabledoesntexist)

NameError: name 'thisvariabledoesntexist' is not defined

错误报告:警告与失败#

当在 nb_execution_allow_errors=False 的上下文中发生错误时,默认行为是将其报告为警告。此警告将仅被记录,不会导致构建失败,除非使用 -W 选项 运行 sphinx-build。如果您希望意外的执行错误导致构建失败而不是警告,无论是否使用 -W 选项,您可以通过在 conf.py 中设置 nb_execution_raise_on_error=True 来实现这一点。

执行统计信息#

当笔记本被执行时,某些统计信息会存储在字典中,并保存在 sphinx 环境对象env.metadata[docname] 中。

您可以在自己的 sphinx 扩展中的后转换中访问此信息,或使用内置的 nb-exec-table 指令:

```{nb-exec-table}
```

这将生成:

Document

Modified

Method

Run Time (s)

Status

authoring/custom-formats

2024-12-27 08:45

cache

1.81

authoring/jupyter-notebooks

2024-12-27 08:46

cache

2.11

authoring/text-notebooks

2024-12-27 08:46

cache

1.09

computation/coconut-lang

2024-12-27 08:46

cache

4.0

computation/execute

2024-12-27 08:46

cache

1.12

render/format_code_cells

2024-12-27 08:46

cache

2.16

render/glue

2024-12-27 08:46

cache

2.78

render/hiding

2024-12-27 08:46

cache

2.06

render/inline

2024-12-27 08:46

inline

1.5

render/interactive

2024-12-27 08:46

cache

2.59

render/orphaned_nb

2024-12-27 08:46

cache

0.84