[英]Re-using generic tasks in Luigi
我在理解如何在Luigi中进行可重复使用的任务,然后在具体情况下使用它们时遇到了麻烦。
例如。 我有两个通用的任务,它们对文件进行处理然后输出结果:
class GffFilter(luigi.Task):
"Filters a GFF file to only one feature"
feature = luigi.Parameter()
out_file = luigi.Parameter()
in_file = luigi.Parameter()
...
class BgZip(luigi.Task):
"bgZips a file"
out_file = luigi.Parameter()
in_file = luigi.Parameter()
...
现在,我想要一个工作流程,该工作流程首先过滤,然后使用以下任务bgzip特定文件:
class FilterSomeFile(luigi.WrapperTask):
def requires(self):
return GffFilter(in_file='some.gff3', out_file='some.genes.gff3', filter='gene')
def output(self):
return self.inputs()
class BgZipSomeFile(luigi.Task):
def run(self):
filtered = FilterSomeFile()
BzZip(filtered)
但这很尴尬。 在第一个任务中,我没有run
方法,而我只是在使用依赖项来使用通用任务。 这个对吗? 我应该在这里使用继承吗?
然后,在第二个任务中,我不能使用依赖项,因为我需要FilterSomeFile
的输出才能使用BgZip
。 但是使用动态依赖关系似乎是错误的,因为luigi无法构建适当的依赖关系图。
我应该怎样做一个路易吉工作流出来的我一般任务?
但这很尴尬。 在第一个任务中,我没有运行方法,而我只是在使用依赖项来使用通用任务。 这个对吗?
是的,根据此页面 , WrapperTask
是一个虚拟任务,其目的是定义任务的工作流程,因此它本身不会执行任何操作。 相反,通过定义几个需求,当requires
方法中列出的每个需求都已完成时,此任务将完成。 本的主要区别WrapperTask
到正规的Task
,就是你不需要定义输出方法,发出信号,这个任务suceeded,可以看出这里 。
然后在第二个任务中,我不能使用依赖项,因为我需要FilterSomeFile的输出才能使用BgZip。 但是使用动态依赖关系似乎是错误的,因为luigi无法构建适当的依赖关系图。
从理论上说,你可以把FilterSomeFile
有输出相同GffFilter
,使BgZipSomeFile
需要FilterSomeFile
,然后用FilterSomeFile.output()
在BgZipSomeFile.run
访问的压缩文件。 但是,此解决方案有些奇怪,因为:
包装器任务仅“运行”另外一个任务,因此包装后的任务可以直接使用,而无需创建WrapperTask
。 有一种更好的使用WrapperTask
将涉及合并BgZipSomeFile
和FilterSomeFile
在一个子类WrapperTask
正在运行方法中实例化Task
。 这会导致动态依赖性,但这在此问题中不需要。
最后, GffFilter
的输入在FilterSomeFile
任务中进行了硬编码,这使工作流程的使用性降低。 可以通过使WrapperClass
仍然接收参数并将这些参数传递到其要求来避免这种情况。
更好的解决方案是:
import luigi as lg
class A(lg.Task):
inFile = lg.Parameter()
outFile = lg.Parameter()
def run(self,):
with open(self.inFile, "r") as oldFile:
text = oldFile.read()
text += "*" * 10 + "\n" + "This text was added by task A.\n" + "*" * 10 + "\n"
print(text)
with open(self.outFile, "w") as newFile:
newFile.write(text)
def output(self,):
return lg.LocalTarget(self.outFile)
class B(lg.Task):
inFile = lg.Parameter()
outFile = lg.Parameter()
def run(self,):
with open(self.inFile, "r") as oldFile:
text = oldFile.read()
text += "*" * 10 + "\n" + "This text was added by task B.\n" + "*" * 10 + "\n"
with open(self.outFile, "w") as newFile:
newFile.write(text)
def output(self,):
return lg.LocalTarget(self.outFile)
class CustomWorkflow(lg.WrapperTask):
mainOutFile = lg.Parameter()
mainInFile = lg.Parameter()
tempFile = "/tmp/myTempFile.txt"
def requires(self,):
return [ A(inFile = self.mainInFile, outFile = self.tempFile),
B(inFile = self.tempFile, outFile = self.mainOutFile)
]
可以使用以下命令在命令行中运行此代码:
PYTHONPATH='.' luigi --module pythonModuleContainingTheTasks --local-scheduler CustomWorkflow --mainInFile ./text.txt --mainOutFile ./procText.txt
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.