0

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

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

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

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

什么没有奏效

隐藏输入单元格还不够好,因为它仍然会保存到磁盘中(这包括report_onlypapermill's 中的选项execute_notebook())。同样“转换”nbconvert为 HTML(它确实允许根据标签选择要删除的单元格,如在解决方案中一样)仍将保留原始笔记本,其中包含编码密码。

4

2 回答 2

0

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

我的第一个建议是不要以纯文本形式传递敏感信息。一个(稍微)更好和简单的选择是将密码存储在环境变量中,并使用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')
于 2020-05-29T03:58:38.830 回答
0

答案似乎涉及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()不适用于 papermill - 当使用 papermill 的功能控制其代码执行时,它不会在输出笔记本中工作。在函数完成或中断执行后,它必须在外部(控制器)笔记本中运行。因为输出notebook在这个过程中是增量保存到磁盘的,如果要保证injected-parameterscell不会被永久保存,需要无条件运行上面的剥离代码,即使papermill函数失败,所以放入你的finally部分try-except-finally

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

于 2020-05-26T17:33:24.670 回答