【问题标题】:JSON serialization error when creating a Luigi task graph创建 Luigi 任务图时出现 JSON 序列化错误
【发布时间】:2017-11-06 20:14:42
【问题描述】:

我正在尝试使用 Luigi 批量处理几个 Jupyter 笔记本,但遇到了问题。

我有两节课。第一个,transform.py

import nbformat
import nbconvert

import luigi
from nbconvert.preprocessors.execute import CellExecutionError


class Transform(luigi.Task):
    """Foo."""
    notebook = luigi.Parameter()
    requirements = luigi.ListParameter()

    def requires(self):
        return self.requirements

    def run(self):
        nb = nbformat.read(self.notebook, nbformat.current_nbformat)
        # https://nbconvert.readthedocs.io/en/latest/execute_api.html
        ep = nbconvert.preprocessors.ExecutePreprocessor(timeout=600, kernel_name='python3')
        try:
            ep.preprocess(nb, {'metadata': {'path': "/".join(self.notebook.split("/")[:-1])}})
            with self.output().open('w') as f:
                nbformat.write(nb, f)
        except CellExecutionError:
            pass  # TODO

    def output(self):
        return luigi.LocalTarget(self.notebook)

这定义了一个将笔记本作为输入的 Luigi 任务(以及运行此任务的可能的先前要求),并且应该运行该笔记本并报告成功或失败作为输出。

要运行 Transform 任务,我有一个很小的 ​​Runner 类:

import luigi


class Runner(luigi.Task):
    requirements = luigi.ListParameter()

    def requires(self):
        return self.requirements

为了完成我的小工作,我会这样做:

from transform Transform
trans = Transform("../tests/fixtures/empty_valid_errorless_notebook.ipynb", []) 
from runner import Runner
run_things = Runner([trans])

但这引发了TypeError: Object of type 'Transform' is not JSON serializable

我的luigi 任务格式是否正确?如果是这样,run 中的哪个组件使整个类不可序列化是否很明显?如果没有,我应该如何调试?

【问题讨论】:

    标签: python json serialization jupyter luigi


    【解决方案1】:

    requires() 应该返回一个或多个任务,而不是参数。

    例如,

    class Runner(luigi.Task):
      notebooks = luigi.ListParameter()
    
      def requires(self):
        required_tasks = []  
        for notebook in self.notebooks:
          required_tasks.append(Transform(notebook))
        return required_tasks
    
    class Transform(luigi.Task):
       notebook = luigi.Parameter()
    
       def requires(self):
          return []
    
    # then to run at cmd line
    luigi --module YourModule Runner --noteboooks '["notebook1.pynb","notebook2.pynb"]' 
    

    【讨论】:

    • 所以不可能不提前硬编码依赖关系?
    • 不确定您的意思...您可以对其进行硬编码,我只是指出 requires() 方法的预期返回类型是什么。如果您需要另一个示例,请告诉我。
    • 我想在运行时以编程方式创建一个新任务,将任何额外的要求从上面传递下去。所以假设我在运行时决定我的任务图是 Transform("a.ipynb") --> Transform("b.ipynb") --> Runner。 Runner 需要能够创建trans_a = Transform("a.ipynb", requirements=[])Transform("b.ipynb", requirements=[trans_a])。如果我不能将 requirements 参数作为变量写入,我不确定我该怎么做(至少没有文件 I/O 技巧)。
    • 不确定“运行时”是什么意思。您将传入动态生成任务所需的笔记本列表和其他参数,而不是任务本身作为参数。
    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多