def test_1(self): import janis_core as j class FileWithSec(j.File): def __init__(self, optional=False): super().__init__(optional=optional, extension=".txt") def secondary_files(self): return [".sec"] Tool = j.CommandToolBuilder( tool="ls", base_command=["ls"], inputs=[ j.ToolInput("inp", FileWithSec, secondaries_present_as={".sec": "^.sec"}) ], outputs=[ j.ToolOutput("std", j.Stdout), j.ToolOutput( "out", FileWithSec, secondaries_present_as={".sec": "^.sec"}, glob=j.InputSelector("inp"), ), ], container="ubuntu:latest", version="v0.1.0", ) Tool.translate("wdl")
def outputs(self) -> List[j.ToolOutput]: return [ j.ToolOutput( "extended", Csv(), glob=j.InputSelector("reportPrefix") + ".extended.csv", ), j.ToolOutput("summary", Csv(), glob=j.InputSelector("reportPrefix") + ".summary.csv"), j.ToolOutput( "metrics", j.File(), glob=j.InputSelector("reportPrefix") + ".metrics.json.gz", ), j.ToolOutput("vcf", VcfTabix(), glob=j.InputSelector("reportPrefix") + ".vcf.gz"), j.ToolOutput( "runinfo", JsonFile(), glob=j.InputSelector("reportPrefix") + ".runinfo.json", ), j.ToolOutput( "rocOut", j.File(), glob=j.InputSelector("reportPrefix") + ".roc.all.csv.gz", ), j.ToolOutput( "indelLocations", j.File(), glob=j.InputSelector("reportPrefix") + ".roc.Locations.INDEL.csv.gz", ), j.ToolOutput( "indelPassLocations", j.File(), glob=j.InputSelector("reportPrefix") + ".roc.Locations.INDEL.PASS.csv.gz", ), j.ToolOutput( "snpLocations", j.File(), glob=j.InputSelector("reportPrefix") + ".roc.Locations.SNP.csv.gz", ), j.ToolOutput( "snpPassLocations", j.File(), glob=j.InputSelector("reportPrefix") + ".roc.Locations.SNP.PASS.csv.gz", ), ]
def ingest_expression_tool_output(self, out): out_type = self.ingest_cwl_type(out.type, secondary_files=out.secondaryFiles) return j.ToolOutput( self.get_tag_from_identifier(out.id), output_type=out_type, skip_output_quality_check=True, )
def get_outputs(self, names: List[NamedArgument]) -> List[janis.ToolOutput]: ret = [] for arg in names: typ = arg.arg.get_type() if isinstance(typ, cli_types.CliFileSystemType) and typ.output: ret.append( janis.ToolOutput( tag="out_" + arg.name, output_type=self.arg_to_janis_type(arg.arg), doc=arg.arg.description, selector=janis.InputSelector("in_" + arg.name), )) return ret
def ingest_command_tool_output( self, out): # out: self.cwlgen.CommandOutputParameter outBinding = out.outputBinding selector = None if outBinding: if outBinding.glob: selector = j.WildcardSelector( self.parse_basic_expression(outBinding.glob)) elif outBinding.outputEval: selector = self.parse_basic_expression(outBinding.outputEval) elif out.outputEval: selector = self.parse_basic_expression(out.outputEval) return j.ToolOutput( tag=self.get_tag_from_identifier(out.id), output_type=self.ingest_cwl_type( out.type, secondary_files=out.secondaryFiles), selector=selector, )
# GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ How to create an empty directory, using the value of an input """ import janis_core as j CLT = j.CommandToolBuilder( tool="create_initial_stuff", base_command=["ls", "*"], version="dev", container="ubuntu:latest", inputs=[ j.ToolInput("name_of_output_folder", j.String(optional=True), default="some-string") ], outputs=[j.ToolOutput("out_dir", j.Directory, selector="some-string")], directories_to_create=[j.InputSelector("name_of_output_folder")], files_to_create=[( j.StringFormatter("{dir}/file.txt", dir=j.InputSelector("name_of_output_folder")), "contents of file", )], ) if __name__ == "__main__": CLT().translate("cwl")
@staticmethod def secondary_files(): return [".csv"] ToolWithSecondaryFiles = j.CommandToolBuilder( tool="secondary_files", version="v0.1.0", container="ubuntu:latest", base_command="echo", inputs=[j.ToolInput("inp", MyDataTypeWithSecondaries, position=0)], outputs=[ j.ToolOutput( "out", MyDataTypeWithSecondaries, selector="file.txt", ) ], ) WorkflowWithSecondaries = j.WorkflowBuilder("workflow_with_secondaries") inner_dt = MyDataTypeWithSecondaries scatter = None # helper method to show how scatters / not scatters work should_scatter = False if should_scatter: inner_dt = j.Array(MyDataTypeWithSecondaries) scatter = "inp"
# (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import janis_core as j HelloWorldTool = j.CommandToolBuilder( tool="HelloWorldTool", container=None, version="development", base_command="echo", inputs=[j.ToolInput("inp", j.String, position=0, default="Hello, World!")], outputs=[ j.ToolOutput("out", j.String, selector=j.standard.ReadContents(j.Stdout())) ], ) # as there is no container, you need to provide "allow_empty_containers=True" to the translate method: HelloWorldTool.translate("wdl", allow_empty_container=True) # OR (bash): # $ janis translate --allow-empty-container hello wdl
import janis_core as j from unittest import TestCase from janis_assistant.management.workflowmanager import WorkflowManager ct = j.CommandToolBuilder( tool="TEST_EXTENSION", base_command=["echo", "1", ">", "file.out"], inputs=[], outputs=[ j.ToolOutput("out", j.File(extension=".out"), selector="file.out") ], container="ubuntu:latest", version="TEST", ) class TestOutputEvaluation(TestCase): def test_basic_extension(self): w = j.WorkflowBuilder("wf") w.step("stp", ct) w.output("out", source=w.stp.out) outputs = WorkflowManager.evaluate_output_params(wf=w, inputs={}, submission_id="SID", run_id="RID") self.assertEqual(".out", outputs[0].extension)
NB: Although WDL supports optional files, some backends of Cromwell do not. """ import janis_core as j ToolWithOptionalWildcardOutput = j.CommandToolBuilder( tool="optional_wildcard_output_tool", version="v0.1.0", container="ubuntu:latest", base_command=None, # write '1' to a file called 'out.csv' arguments=[j.ToolArgument("echo 1 > out.csv", shell_quote=False)], inputs=[j.ToolInput("inp", j.File, localise_file=True)], outputs=[ j.ToolOutput("out_csv_files", j.Array(j.File), selector=j.WildcardSelector("*.csv")), # the next two are functionally equivalent j.ToolOutput("out_single_csv_file_1", j.Array(j.File), selector=j.WildcardSelector("*.csv", select_first=True)), j.ToolOutput("out_single_csv_file_2", j.Array(j.File), selector=j.WildcardSelector("*.csv")[0]), # OPTIONAL glob outputs # capture all files with *.txt pattern (but select the first if possible) j.ToolOutput("out_optional_glob", j.File(optional=True), selector=j.WildcardSelector("*.txt", select_first=True)) ],
container="ubuntu:latest", version="development", base_command="echo", inputs=[ # NO prefix, joined by space (' ') [DEFAULT] # need a position to ensure it binds onto the command line j.ToolInput("array1", j.Array(j.String), position=0), # # No prefix, joined by commans (',') j.ToolInput("array2", j.Array(j.String), separator=",", position=1), # # Single prefix, then joined by space (' ') j.ToolInput("array3", j.Array(j.String), prefix="--prefix"), # # Single prefix, then joined by commas (',') j.ToolInput("array4", j.Array(j.String), prefix="--prefix", separator=","), # # Prefix applies to each element j.ToolInput( "array5", j.Array(j.String), prefix="--prefix", prefix_applies_to_all_elements=True, ), ], outputs=[j.ToolOutput("out", j.Stdout())], )
def parse_command_tool_output(self, outp: WDL.Decl): sel = self.translate_expr(outp.expr) return j.ToolOutput(outp.name, self.parse_wdl_type(outp.type), selector=sel)
from janis_unix.tools import Cat # Declare a new subclass of j.File and write a new tool to accept it class SubFile(j.File): @staticmethod def name(): return "SubFile" ToolThatAcceptsSubFile = j.CommandToolBuilder( tool="acceptingSubFile", base_command="cat", inputs=[j.ToolInput("inp", SubFile)], outputs=[j.ToolOutput("out", j.Stdout(SubFile))], version="test", container="ubuntu:latest", ) # Declare workflow we're we'll use the type alias w = j.WorkflowBuilder("aliasing") w.input("inp", SubFile) w.step("stp1", Cat(file=w.inp)) # This line would cause the following critical message to be logged: # [CRITICAL]: Mismatch of types when joining 'stp1.out' to 'stp2.inp': stdout<File> -/→ SubFile # w.step("stp2", ToolThatAcceptsSubFile(inp=w.stp1.out)) # Instead, we'll use the .as_type method:
# GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ NB: Although WDL supports optional files, some backends of Cromwell do not. """ import janis_core as j ToolWithOptionalOutput = j.CommandToolBuilder( tool="optional_output_tool", version="v0.1.0", container="ubuntu:latest", base_command=[], arguments=[j.ToolArgument("echo 1 > ", shell_quote=False)], inputs=[ j.ToolInput("outputFilename", j.String(optional=True), default="out.csv", position=1) ], outputs=[ j.ToolOutput("out", j.File(optional=True), selector=j.InputSelector("outputFilename")) ], ) if __name__ == "__main__": ToolWithOptionalOutput().translate("wdl")
# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import janis_core as j CLT = j.CommandToolBuilder( tool="collecting_std_outputs", base_command=["echo", "Hello, World"], version="dev", container="ubuntu:latest", inputs=[], outputs=[ # stdout j.ToolOutput("out_stdout_1", j.Stdout()), j.ToolOutput("out_stdout_2", j.File(), selector=j.Stdout()), # stderr j.ToolOutput("out_stderr_1", j.Stderr()), j.ToolOutput("out_stderr_2", j.File(), selector=j.Stderr()), ]) if __name__ == "__main__": CLT.translate("cwl")
# # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ We'll use Janis to _try_ and collect a SINGLE file with the extension '.txt', but one won't exist. CWL will automatically coerce the empty File[0] to File? (null). However, in WDL, we have do this slightly differently: File? out = if length(glob("*.txt")) > 0 then glob("*.txt")[0] else None NB: Although WDL supports optional files, some backends of Cromwell do not. """ import janis_core as j ToolWithDynamicGlob = j.CommandToolBuilder( tool="tool_with_dynamic_glob", version="v0.1.0", container="ubuntu:latest", base_command=None, # write '1' to a file called 'out.csv' arguments=[j.ToolArgument("echo 1 > out.csv", shell_quote=False)], inputs=[j.ToolInput("extension", str)], outputs=[ j.ToolOutput("out_csv_files", j.Array(j.File), selector=j.WildcardSelector("*" + j.InputSelector("extension"))), ], ) if __name__ == "__main__": ToolWithDynamicGlob().translate("cwl")