JSON 创建 Luigi 任务图时出现序列化错误

JSON serialization error when creating a Luigi task graph

我正在尝试使用 Luigi 对一些 Jupyter notebook 进行批处理,但我 运行 遇到了问题。

我有两个 class。第一个,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任务我有一个小小的Runnerclass:

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 中的哪个组件使整个 class 不可序列化是否显而易见?如果没有,我应该如何调试它?

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

例如,

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"]'