执行并缓存#
MyST-NB 可以通过 [jupyter-cache] 自动运行并缓存项目中包含的笔记本。笔记本可以在每次构建文档时运行,也可以在本地缓存,以便仅在代码单元格发生变化时重新运行。
执行和缓存行为可以通过全局或文件级别的配置进行控制,如 配置部分 所述。请参阅以下部分,了解每个配置选项及其作用的详细说明。
笔记本执行模式#
要触发笔记本页面的执行,可以使用全局的 nb_execution_mode
配置项,或针对单个文件的 execution_mode
配置项:
模式 |
描述 |
---|---|
|
不执行笔记本 |
|
始终执行笔记本(在解析之前) |
|
执行缺少输出的笔记本(在解析之前) |
|
执行笔记本并从缓存中存储/检索输出 |
|
在解析期间执行笔记本(允许变量评估) |
默认情况下,此项设置为:
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 |
---|---|---|---|---|
2024-12-27 08:45 |
cache |
1.81 |
✅ |
|
2024-12-27 08:46 |
cache |
2.11 |
✅ |
|
2024-12-27 08:46 |
cache |
1.09 |
✅ |
|
2024-12-27 08:46 |
cache |
4.0 |
✅ |
|
2024-12-27 08:46 |
cache |
1.12 |
✅ |
|
2024-12-27 08:46 |
cache |
2.16 |
✅ |
|
2024-12-27 08:46 |
cache |
2.78 |
✅ |
|
2024-12-27 08:46 |
cache |
2.06 |
✅ |
|
2024-12-27 08:46 |
inline |
1.5 |
✅ |
|
2024-12-27 08:46 |
cache |
2.59 |
✅ |
|
2024-12-27 08:46 |
cache |
0.84 |
✅ |