【问题标题】:Luigi flexible pipeline and passing parameters all the way throughLuigi 灵活的管道和一路传递参数
【发布时间】:2017-10-06 19:12:30
【问题描述】:

我最近实施了一个 luigi 管道来处理我们的一个生物信息学管道的处理。但是,关于如何设置这些任务的一些基本知识我没有掌握。

假设我有一个包含三个任务的链,我希望能够与多个工作人员一起运行。例如,三个工作人员的依赖关系图可能如下所示:

/taskC -> taskB -> taskA
- 任务C -> 任务B -> 任务A
\ taskC -> taskB -> taskA

我可能会写

class entry(luigi.Task):

    in_dir = luigi.Parameter()

    def requires(self):
        for f in self.in_dir:
            yield taskC(pass_through=f)

    def run(self):
        some logic using self.input().path
        from each worker in the above yield

class taskA(luigi.Task):

    in_file_A = luigi.Parameter()

    def output(self):
        return luigi.LocalTarget('outA.txt')

    def run(self):
        some logic generating outA.txt

class taskB(luigi.Task):

    pass_through = luigi.Parameter()

    def output(self):
        return luigi.LocalTarget('outB.txt')

    def requires(self):
        return taskA(in_file_A=self.pass_through)

    def run(self):
        some logic using self.input().path [outA.txt] 
        and generating self.output().path [outB.txt]

class taskC(luigi.Task):

    pass_through = luigi.Parameter()

    def output(self):
        return luigi.LocalTarget('outC.txt')

    def requires(self):
        return taskB(pass_through=self.pass_through)

    def run(self):
        some logic using self.input().path [outB.txt] 
        and generating self.output().path [outC.txt]

如果我的代码位于 pipeline.py,我可能会使用以下命令启动它:

luigi --module pipeline entry --workers 3 --in-dir some_dir_w_input_files/

我将参数pass_through 一直发送到taskA 的事实感觉不是正确的方法。此外,如果将来某个时候我已经拥有taskA(单独)生成的数据,taskB 不够灵活,无法处理这种情况。也许我可以写:

class taskB(luigi.Task):

    in_file_B = luigi.Parameter() # if we already have the output of taskA
    pass_through = luigi.Parameter() # if we require taskA

    def output(self):
        return luigi.LocalTarget('outB.txt')

    def requires(self):
        if self.pass_through:
            return taskA(in_file_A=self.pass_through)

    def run(self):
        if self.input().path:
           logic_input = self.input().path
        else:
           logic_input = self.in_file_B

        some logic using 'logic_input'
        and generating self.output().path [outB.txt]

我想知道这是否是 Luigi 的“正确”设计模式,或者我是否完全偏离了基础。

【问题讨论】:

    标签: python pipeline luigi


    【解决方案1】:

    我认为这在很大程度上是您在这里所拥有的抽象任务的产物,在现实世界中,您可能需要知道您在哪里读取/写入。例如:

    class DecompressTask(luigi.Task):
        dirname = luigi.Parameter()
        filename = luigi.Parameter()
    
        def output(self):
            return luigi.LocalTarget(os.path.join(self.dirname , self.filename + ".txt"))
    
        def run(self):
            decompress(os.path.join(self.dirname, self.filename + ".gz"),
                       os.path.join(self.dirname, self.filename + ".txt"))
    
    
    class TranslateTask(luigi.Task):
        dirname = luigi.Parameter()
        filename = luigi.Parameter()
    
        def requires(self):
            return DecompressTask(dirname=self.dirname, filename=self.filename)
    
        def output(self):
            return luigi.LocalTarget(os.path.join(self.dirname + self.filename + ".translated"))
    
        def run(self):
            translate(os.path.join(self.dirname, self.filename + ".txt"),
                      os.path.join(self.dirname, self.filename + ".translated"))
    
    
    class ProcessDirectory(luigi.WrapperTask):
        dirname = luigi.Parameter()
    
        def requires(self):
            tasks = []
            for file_name in os.listdir(self.dirname):
                if file_name.endswith("gz"):
                    prefix = file_name.split(".")[0]
                    tasks.append(TranslateTask(filename=prefix, dirname=self.dirname))
            return tasks
    

    【讨论】:

    • 我不确定这是否完全回答了我的问题。 taskA 的参数仅在生成依赖关系树后定义 - 每个工作人员为 taskA 设置输入文件(而不是目录)。在我的示例中,我需要一种从 entry 任务中设置 --taskA-in-file-A 的方法(类似于我在 passthrough 参数中传递该文件名的方式)
    • 是的,你的例子真的搞砸了,因为你所有的 TaskB 和 TaskC 的输出都是单个静态文件名,一旦运行,该任务将被视为永远完成。
    猜你喜欢
    • 1970-01-01
    • 2017-11-26
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    • 2021-09-11
    • 2020-12-10
    相关资源
    最近更新 更多