Python_Jupyter_自动执行jupyter

4,819 阅读13分钟

最近有业务需求,用户通过写jupyter文档,需要我们每天定时执行,并将执行结果已图片的方式,发送给用户。

解决方案

  • 1.每天读取源文件.ipynb 生成 new.ipynb
  • 2.通过pythonApi 或 命令行 jupyter nbconvert --ExecutePreprocessor.timeout=600 --to notebook --execute mynotebook.ipynb 方式执行jupyter 文件
  • 3.通过 nbconvert --to html命令,将执行成功的jupyter文件转成html
  • 4.Selenium+PhantomJS 读取html文件,保存成图片
  • 5.通过钉钉API发送给用户
  • 6.以上调度 通过jenkins 执行。

Python_Jupyter_Nbconvert

jupyter nbconver文档

nbconvert:将jupyter 转成其他格式

  • 使用nbconvert可以做:
    • 以熟悉的格式(如PDF)呈现信息。
    • 使用LaTeX 发布研究并打开了将笔记本嵌入纸张的大门。
    • 协作与其他人谁可能不会在工作中使用笔记本。
    • 使用HTML通过网络与许多人分享内容。

nbconvert工具主要可以将Jupyter ipynb 笔记文档转成另外一个种静态格式,包括Html ,LaTex,PDF,Maketdown,reStructuredText等。nbconvert当用于以编程方式执行笔记本时,还可以为您的工作流程增加工作效率。

命令行工具

运行nbconvert脚本的命令行语法是:

$ jupyter nbconvert --to FORMAT notebook.ipynb

将jupyter笔记本文件notebook.ipynb 转换成 FORMAT字符串给出的输出格式。

默认输出格式 html

默认输出格式为HTML ,--to 可省略参数

$ jupyter nbconvert notebook.ipynb

支持的输出格式

  • 当前支持的输出格式:
    • HTML
    • LaTeX
    • PDF
    • Reveal.js HTML slideshow
    • Markdown
    • Ascii
    • reStructruredText
    • executable script
    • notebook

HTML

  • --to html
    • --tempplate full (默认) : 笔记本的完整静态HTML渲染。这看起来分成类似于交互视图
    • --template basic :简化的HTML,适用于嵌入网页、博客等。这不包含HTML表头

LaTex

  • --to latex Latex export. This generates NOTEBOOK_NAME.texfile, ready for export. Images are output as .png files in a folder.
    • --template article (default) Latex article, derived from Sphinx’s howto template.
    • --template report Latex report, providing a table of contents and chapters.

nbconvert uses pandoc to convert between various markup languages, so pandoc is a dependency when converting to latex or reStructuredText.

PDF

  • --to pdf
  • 通过LaTex生成PDF。支持相同的模板。--to latex

Reveal.js HTML幻灯片

  • --to slides 这会生成Reveal.js HTML幻灯片。

运行此幻灯片需要一份reveal.js(版本3.x)的副本。

默认情况下,这将在html中包含一个脚本标记,它将直接从公共CDN加载reveal.js。

这意味着如果您将幻灯片包含在网页上,它们应该按预期工作。但是,某些功能(特别是演讲者备注和计时器)不适用于网站,因为它们需要访问reveal.js的本地副本。

演讲者笔记需要reveal.js的本地副本。然后,您需要告诉 nbconvert如何找到本地副本。

定时器仅在您已有发言人注释时才有效,但也需要本地https服务器。您可以在ServePostProcessorExample中阅读有关此内容的更多信息。

为了更清楚,让我们看一个如何使用reveal.js的本地副本获取演讲者笔记的示例:SlidesWithNotesExample。

注意

要从Jupyter笔记本中指定从笔记本单元格到Reveal.js幻灯片的映射,请选择菜单项View - > Cell Toolbar - > Slideshow。这将显示每个单元格右上角的下拉菜单。从中,可以选择“幻灯片”,“子幻灯片”,“片段”,“跳过”和“注释”。在转换时,将不包括指定为“跳过”的单元格,将包含“注释”只在演示者笔记等

示例:创建your_talk.ipynb的幻灯片

假设您有一个your_talk.ipynb要转换为幻灯片的笔记本。对于此示例,我们假设您在与要转换的笔记本相同的目录中工作(即,当您运行时, 显示在文件列表中)。ls .your_talk.ipynb

首先,我们需要与幻灯片位于同一目录中的reveal.js副本。一种方法是在终端中使用以下命令:

git clone https://github.com/hakimel/reveal.js.git
cd reveal.js
git checkout 3.5.0
cd ..

然后我们需要告诉nbconvert指向这个本地副本。为此,我们使用--reveal-prefix命令行标志指向本地副本。

jupyter nbconvert your_talk.ipynb --to slides --reveal-prefix reveal.js

这将创建your_talk.slides.html您应该能够访问的文件。要访问演讲者备注,请在载入幻灯片后按,然后 在新窗口中打开。open your_talk.slides.html

注意:这不会启用完全脱机运行的幻灯片。虽然您有reveal.js的本地副本,但默认情况下,幻灯片需要通过公共CDN访问mathjax,require和jquery。解决这个用例是一个悬而未决的问题,并且总是鼓励PR。

使用https服务器提供幻灯片:--post serve

一旦你有说话笔记工作,你可能会注意到你的计时器不起作用。定时器需要更多的基础设施; 您需要从本地https服务器提供reveal.js的本地副本。

幸运的是,nbconvert通过使用它,这使得相当简单ServePostProcessor。要激活此服务器,我们将命令行标志附加到我们对nbconvert的调用。--post serve

jupyter nbconvert your_talk.ipynb --to slides --reveal-prefix reveal.js --post serve

这将运行服务器,它将占用您运行命令的终端,直到您停止它。您可以按 两次停止服务器。ctrl C

Markdown

  • --to markdown

简单的降价输出。Markdown单元格不受影响,代码单元格缩进4个空格。图像以.png文件形式输出到文件夹中。

ASCII

  • --to asciidoc

Ascii输出。图像以.png文件形式输出到文件夹中。

reStructuredText

  • --to rst

基本的reStructuredText输出。有用作为在Sphinx文档中嵌入笔记本的起点。图像以.png文件形式输出到文件夹中。

注意

nbconvert使用pandoc在各种标记语言之间进行转换,因此pandoc是转换为LaTeX或reStructuredText时的依赖项。

Executable script

  • --to script

将笔记本转换为可执行脚本。这是从笔记本中获取Python(或其他语言,取决于内核)脚本的最简单方法。如果Jupyter笔记本中有任何魔法,这可能只能在Jupyter会话中执行。

例如,要将Julia笔记本转换为Julia可执行脚本:

jupyter nbconvert --to script my_julia_notebook.ipynb

Notebook and preprocessors

  • --to notebook

3.0版中的新功能。

这不会将笔记本转换为不同的格式本身,而是允许在笔记本上运行nbconvert预处理器,和/或转换为其他笔记本格式。例如:

jupyter nbconvert --to notebook --execute mynotebook.ipynb

这将打开笔记本,执行它,捕获新输出,并保存结果mynotebook.nbconvert.ipynb。指定--inplace将覆盖输入文件而不是写入新文件。默认情况下,nbconvert如果在执行单元格期间发生任何异常, 则将中止转换。如果指定--allow-errors(除 -execute`标志外),则转换将继续,并且任何异常的输出都将包含在单元格输出中。

以下命令:

jupyter nbconvert --to notebook --nbformat 3 mynotebook

将 在笔记本格式的第3版中创建mynotebook.ipynbin 的副本mynotebook.v3.ipynb

如果要就地转换笔记本,可以将输出文件指定为与输入文件相同:

jupyter nbconvert --to notebook mynb --output mynb

要小心,因为它将替换输入文件。

注意

nbconvert使用pandoc在各种标记语言之间进行转换,因此pandoc是转换为latex或reStructuredText时的依赖项。

创建的输出文件nbconvert将具有与笔记本相同的基本名称,并将放在当前工作目录中。任何支持文件(图形等)都将放在一个与笔记本具有相同基本名称的新目录中,后缀为_files:

$ jupyter nbconvert notebook.ipynb
$ ls
notebook.ipynb   notebook.html    notebook_files/

对于简单的单文件输出,例如html,markdown等,输出可以通过以下方式发送到标准输出:

$ jupyter nbconvert --to markdown notebook.ipynb --stdout

转换多个笔记本

可以从命令行指定多个笔记本:

$ jupyter nbconvert notebook*.ipynb
$ jupyter nbconvert notebook1.ipynb notebook2.ipynb

或者通过配置文件中的列表,例如mycfg.py,包含文本:

c = get_config()
c.NbConvertApp.notebooks = ["notebook1.ipynb", "notebook2.ipynb"]

并使用命令:

$ jupyter nbconvert --config mycfg.py

删除单元格,输入或输出

将笔记本电脑转换为其他格式时,可以使用预处理器删除单元格的一部分或整个单元格。笔记本将保持不变,但输出将删除某些部分。以下是实现此目的的两种主要方法。

使用单元格标签删除单元格

控制哪些单元格被移除的最直接的方法是使用细胞标签。这些是存储在每个单元格“tag”字段中的单字符串元数据片段。的 TagRemovePreprocessor可用于除去输入,输出,或整个单元格。

例如,这是一个使用不同标记来移除HTMLExporter的单元格的每个部分的配置。在这种情况下,我们演示使用nbconvert Python API

from traitlets.config import Config
import nbformat as nbf
from nbconvert.exporters import HTMLExporter

c = Config()

# 配置我们的标签移除
c.TagRemovePreprocessor.remove_cell_tags = ("remove_cell",)
c.TagRemovePreprocessor.remove_all_outputs_tags = ('remove_output',)
c.TagRemovePreprocessor.remove_input_tags = ('remove_input',)

# Configure and run out exporter
c.HTMLExporter.preprocessors = ["TagRemovePreprocessor"]
HTMLExporter(config=c).from_filename("path/to/mynotebook.ipynb")

使用单元格内容上的正则表达式删除单元格

有时您宁愿根据_content_而不是标签来删除单元格。在这种情况下,您可以使用RegexRemovePreprocessor

您可以使用单个模式配置来初始化此预处理器,这是一个字符串列表。对于每个单元,此预处理器检查单元格内容是否与模式中提供的任何字符串匹配。如果内容与任何模式匹配,则从笔记本中移除单元格。

例如,执行以下命令将笔记本转换为html并删除仅包含空格的单元格:

jupyter nbconvert --RegexRemovePreprocessor.patterns="['\s*\Z']" mynotebook.ipynb 命令行参数将模式列表设置为's * Z',它匹配任意数量的空白字符,后跟字符串的结尾。

有关正则表达式的交互式指南,请参阅https://regex101.com/(确保选择python风格)。有关 python中的官方正则表达式文档,请参阅https://docs.python.org/library、re.html

执行jupyter

Jupyter笔记本通常与已清除的输出单元一起保存。nbconvert提供了一种方便的方法来执行.ipynb笔记本文件的输入单元格,并将结果(输入和输出单元格)保存为.ipynb文件。

在本节中,我们将展示如何执行.ipynb笔记本文档,以笔记本格式保存结果。如果需要将笔记本导出为其他格式,例如reStructured Text或Markdown(可选择执行它们),请参阅使用nbconvert作为库。

执行笔记本非常有用,例如,可以一步在Python库中运行所有笔记本,或者作为在涉及多个笔记本的项目中自动执行数据分析的方法。

从命令行执行笔记本

执行笔记本的相同功能通过命令行界面或Python API接口公开 。例如,可以从命令行执行笔记本:

jupyter nbconvert --to notebook --execute mynotebook.ipynb

使用Python API接口执行笔记本

本节将说明Python API接口。

示例

让我们从一个完整的快速示例开始,给出以下部分的详细说明。

导入:首先我们导入nbconvertExecutePreprocessor 类:

import nbformat
from nbconvert.preprocessors import ExecutePreprocessor

加载:假设notebook_filename包含笔记本的路径,我们可以加载它:

with open(notebook_filename) as f:
    nb = nbformat.read(f, as_version=4)

配置:接下来,我们配置笔记本执行模式:

ep = ExecutePreprocessor(timeout=600, kernel_name='python3')

我们指定的两个(可选的)参数timeoutkernel_name,分别定义单元格执行超时和执行内核。

指定kernel_name的选项是nbconvert 4.2中的新选项。未指定或使用nbconvert <4.2时,将选择默认的Python内核。

执行/运行(预处理):要实际运行笔记本,我们调用方法 preprocess

ep.preprocess(nb, {'metadata': {'path': 'notebooks/'}})

希望我们在笔记本执行期间不会出现任何错误(请参阅最后一节的错误处理)。请注意,path指定在哪个文件夹中执行笔记本。

保存:最后,保存生成的笔记本:

with open('executed_notebook.ipynb', 'w', encoding='utf-8') as f:
    nbformat.write(nb, f)

就这样。您执行的笔记本将保存在文件的当前文件夹中executed_notebook.ipynb。

执行参数(traitlets)

传递给的参数ExecutePreprocessor是名为traitlets的配置选项。关于traitlets有很多很酷的事情。例如,它们强制执行输入类型,并且可以作为类属性访问/修改它们。此外,每个traitlet都会自动作为命令行选项公开。例如,我们可以从命令行传递超时,如下所示:

jupyter nbconvert --ExecutePreprocessor.timeout=600 --to notebook --execute mynotebook.ipynb

现在让我们更详细地讨论我们使用的两个特征。

所述timeout traitlet定义最大时间(秒)每笔记本cell允许运行,如果执行需要较长的时间,则将会引发。默认值为30秒,因此在长时间运行的单元格中,您可能需要指定更高的值。该timeout选项也可以设置为None 或-1删除对执行时间的任何限制。

第二个traitlet kernel_name允许指定要用于执行的内核的名称。默认情况下,内核名称是从笔记本元数据中获取的。traitlet kernel_name允许指定用户定义的内核,覆盖笔记本元数据中的值。一个常见的用例是Python 2/3库,其中包括文档/测试笔记本。这些笔记本将在其元数据中指定python2python3内核(取决于上次保存笔记本时使用的内核)。实际上,这些笔记本将适用于Python 2Python 3,并且,为了进行测试,能够在两个版本上以编程方式执行它们非常重要。这里的traitletkernel_name有助于简化和保持一致性:我们可以运行两次笔记本,首先指定“python2”,然后指定“python3”作为内核名称。

处理错误和异常

在前面的部分中,我们看到了如何保存已执行的笔记本,假设没有执行错误。但是,如果有错误怎么办?

执行到第一次错误

默认情况下,笔记本执行期间的错误将停止执行并引发CellExecutionError。方便地,还打印导致错误的源单元和原始错误名称和消息。发生错误后,我们仍然可以像以前一样保存笔记本:

with open('executed_notebook.ipynb', mode='w', encoding='utf-8') as f:
    nbformat.write(nb, f)

保存的笔记本包含直到出现故障的单元格的输出,并包含完整的堆栈跟踪和错误(可以帮助调试)。

处理错误

处理错误时执行笔记本的有用模式如下:

from nbconvert.preprocessors import CellExecutionError

try:
    out = ep.preprocess(nb, {'metadata': {'path': run_path}})
except CellExecutionError:
    out = None
    msg = 'Error executing the notebook "%s".\n\n' % notebook_filename
    msg += 'See notebook "%s" for the traceback.' % notebook_filename_out
    print(msg)
    raise
finally:
    with open(notebook_filename_out, mode='w', encoding='utf-8') as f:
        nbformat.write(nb, f)

无论执行错误如何,这都将保存已执行的笔记本。但是,如果出现错误,则会打印一条附加消息并CellExecutionError引发该消息 。该消息将用户指向已保存的笔记本以供进一步检查。

执行并保存所有错误

作为最后一种情况,执行引发异常的笔记本有时很有用,例如显示错误情况。在这种情况下,我们可以使用traitlet继续执行笔记本,而不是在第一个错误上停止执行allow_errors(默认为False)。使用 allow_errors=True时,无论执行过程中遇到任何错误,笔记本都会执行到最后。输出笔记本将包含所有引发异常的单元格的堆栈跟踪和错误消息。

小部件状态

如果您的笔记本包含任何 Jupyter小部件,则所有小部件的状态可以存储在笔记本的元数据中。这允许在例如nbviewer上或在转换为html时呈现实时小部件。

我们可以告诉nbconvert不使用store_widget_state 参数存储状态:

jupyter nbconvert --ExecutePreprocessor.store_widget_state=False --to notebook --execute mynotebook.ipynb

在执行期间不会对浏览器执行此窗口小部件呈现,因此在执行期间将仅计算窗口小部件默认状态或通过用户代码操纵的状态。%% javascript单元格将在笔记本呈现时执行,使复杂的交互在UI查看时按预期运行。

如果在执行后无法查看窗口小部件结果,则可能需要在“ 文件”菜单下选择“ 信任笔记本 ”