如何使用其标签以编程方式删除 Jupyter 笔记本输入单元格?



在我们最大的 ML 建模管道笔记本中,我们需要删除单个输入(代码(单元格(包含我们在自动执行时无法通过其他方式传递的敏感信息(。

该单元已由另一个笔记本(控制器(创建(注入(papermill.execute_notebook()并在另一个笔记本(控制器(中执行,并已使用injected-parameters标记自动标记。

解决方案(可能不是唯一的解决方案?(是在执行单元格后立即删除该单元。

如果搜索标签使其更加困难,那么让我们使用仅删除上一个输入单元格的解决方案(以编程方式(。

什么不起作用

隐藏输入单元格是不够的,因为它仍然会被保存到磁盘中(这包括造纸厂execute_notebook()中的report_only选项(。此外,使用nbconvert"转换"为 HTML(确实允许根据其标签选择要删除的单元格,如在此解决方案中(仍将保留带有编码密码的原始笔记本。

我假设您要删除该单元格,因为它包含敏感信息(密码(。

我的第一个建议是不要以纯文本形式传递敏感信息。一个(稍微(更好和更简单的选择是将密码存储在环境变量中,并使用os.environ从笔记本中读取密码。

以下是删除单元格的方法:

注意:我是即时编写此代码的,没有对其进行测试,可能需要进行少量编辑。

import nbformat
nb = nbformat.read('/path/to/your/notebook.ipynb')
index = None
# find index for the cell with the injected params
for i, c in enumerate(nb.cells):
cell_tags = c.metadata.get('tags')
if cell_tags:
if 'injected-parameters' in cell_tags:
index = i
# remove cell
if index is not None:
nb.cells.pop(index)
# save modified notebook
nbformat.write(nb,  '/path/to/your/notebook.ipynb')

答案似乎涉及nbformat并且它已经存在于此站点上,但是对于以这种技术语言提出的问题,我认为值得将该问题简化为我的简单英语版本以帮助/允许其他人发现它(我适当地投票支持另一个答案(。

def perform_post_exec_cleanup(output_nb_name, tag_to_del='injected-parameters'):
import json
from traitlets.config import Config
from nbconvert import NotebookExporter
import nbformat
c = Config()
c.TagRemovePreprocessor.enabled=True # to enable the preprocessor
c.TagRemovePreprocessor.remove_cell_tags = [tag_to_del]
c.preprocessors = ['TagRemovePreprocessor'] # previously: c.NotebookExporter.preprocessors
nb_body, resources = NotebookExporter(config=c).from_filename(output_nb_name)
nbformat.write(nbformat.from_dict(json.loads(nb_body)), output_nb_name, 4)

警告

通常可以在运行剥离代码的同一笔记本中就地执行此类笔记本转换/单元格剥离。在造纸厂的情况下不是 - 当它的代码执行是使用造纸厂的execute_notebook()函数控制时,它不会在输出笔记本中工作。在函数完成或中断其执行后,它必须在外部(控制器(笔记本中运行。因为输出笔记本在这个过程中已经增量保存到磁盘上,所以如果你想确保injected-parameters单元不会被永久保存,你需要无条件运行上面的剥离代码,即使造纸厂功能失败,所以把它放在你的finally部分try-except-finally

[ 基于: 使用 nbconvert 作为库运行预处理器 ]

相关内容

  • 没有找到相关文章

最新更新