Beispiel #1
0
    def from_loaded_task(self, obj: WDL.Task):
        rt = obj.runtime
        translated_script = self.translate_expr(obj.command)
        inputs = obj.inputs

        cpus = self.translate_expr(rt.get("cpu"))
        if cpus is not None and not isinstance(cpus, (int, float)):
            cpus = int(cpus)

        c = j.CommandToolBuilder(
            tool=obj.name,
            base_command=["sh", "script.sh"],
            container=self.container_from_runtime(rt, inputs=inputs),
            version="DEV",
            inputs=[
                self.parse_command_tool_input(i) for i in obj.inputs
                if not i.name.startswith("runtime_")
            ],
            outputs=[self.parse_command_tool_output(o) for o in obj.outputs],
            files_to_create={"script.sh": translated_script},
            memory=self.parse_memory_requirement(rt.get("memory")),
            cpus=cpus,
            disk=self.parse_disk_requirement(rt.get("disks")),
        )

        return c
    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")
Beispiel #3
0
    def ingest_command_line_tool(self, clt):

        docker_requirement = None  # : Optional[self.cwlgen.DockerRequirement]
        files_to_create = {}
        memory, cpus, time = None, None, None
        for req in clt.requirements or []:
            if isinstance(req, self.cwlgen.DockerRequirement):
                docker_requirement = req

            elif isinstance(req, self.cwlgen.InitialWorkDirRequirement):
                for dirent in req.listing:
                    if isinstance(dirent, str):
                        continue
                    files_to_create[self.parse_basic_expression(
                        dirent.entryname)] = dirent.entry

            elif isinstance(req, self.cwlgen.ResourceRequirement):
                # maybe convert mebibytes to megabytes?
                memory = self.parse_basic_expression(req.ramMin or req.ramMax)
                cpus = self.parse_basic_expression(req.coresMin)
            elif (hasattr(self.cwlgen, "ToolTimeLimit")
                  and isinstance(req, self.cwlgen.ToolTimeLimit)
                  and req.timelimit > 0):
                time = req.timelimit

        container = None
        if docker_requirement:
            container = docker_requirement.dockerPull

        tool_id = self.get_tool_tag_from_identifier(clt.id)
        jclt = j.CommandToolBuilder(
            tool=tool_id,
            base_command=clt.baseCommand,
            inputs=[self.ingest_command_tool_input(inp) for inp in clt.inputs],
            outputs=[
                self.ingest_command_tool_output(out) for out in clt.outputs
            ],
            arguments=[
                self.ingest_command_tool_argument(arg)
                for arg in (clt.arguments or [])
            ],
            version="v0.1.0",
            container=container or "ubuntu:latest",
            doc=clt.doc,
            friendly_name=clt.label,
            files_to_create=files_to_create or None,
            memory=memory,
            cpus=cpus,
            time=time,
        )
        return jclt
Beispiel #4
0
    def command_to_tool(self, cmd: Command) -> janis.CommandToolBuilder:

        inputs: List[CliArgument] = [*cmd.named] + (
            [] if self.ignore_positionals else [*cmd.positional])
        names = self.choose_variable_names(inputs)

        tool = janis.CommandToolBuilder(
            tool=cmd.as_filename,
            base_command=list(cmd.command),
            inputs=self.get_inputs(names),
            outputs=self.get_outputs(names),
            version="v0.1.0",
            container=cmd.docker_image,
        )

        return tool
Beispiel #5
0
# 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")
Beispiel #6
0
class MyDataTypeWithSecondaries(j.File):
    def __init__(self, optional=False):
        super().__init__(optional=optional)

    @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:
Beispiel #7
0
Create a step whose value is dependent on multiplying an input number,
and the length of an list input. We construct the combination of operators
using fairly natural Python syntax.
"""

import janis_core as j
from janis_core import ToolInput, ToolOutput, Int, Stdout, File
from janis_unix.tools import Echo


AddTwo = j.CommandToolBuilder(
    tool="expr",
    base_command=None,
    arguments=[j.ToolArgument("expr 2 + ", position=0, shell_quote=False)],
    version="dev", container="ubuntu:latest",
    inputs=[
        ToolInput("inp", Int(), position=1)
    ],
    outputs=[
        ToolOutput("out", Stdout()),
    ]
)


w = j.WorkflowBuilder("str_to_int")

w.input("str_input", str)

w.step("echo", Echo(inp=w.str_input))
w.step("exp", AddTwo(inp=w.echo.out.contents().as_int()))

w.output("out", source=w.exp.out)
# (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
# 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

HelloContainerOverrideTool = j.CommandToolBuilder(
    tool="HelloContainerOverrideTool",  # <- Matching this toolID
    container="ubuntu:latest",
    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()))
    ],
)

# We can swap the container out during translation (and also during running with the CLI)
# by providing the container_override={"ToolID": "containerToOverride"}
#   NB: the toolId must match what's in `tool="HelloContainerOverrideTool"`,
#   not the variable you've assigned the tool to.
#   You can also use {"*": "newcontainer"} to match all tools.

HelloContainerOverrideTool.translate(
    "wdl", container_override={"HelloContainerOverrideTool": "ubuntu:bionic"})
Beispiel #10
0
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)
Beispiel #11
0
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))
    ],
)

if __name__ == "__main__":
CommandLineThatBindsArrays = j.CommandToolBuilder(
    tool="CommandLineThatBindsArrays",
    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())],
)
Beispiel #13
0
import janis_core as j
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")
Beispiel #16
0
#
# 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")