Source code for tooldog.annotate.cwl

#!/usr/bin/env python3

"""
Generation of CWL tool from https://bio.tools based on the ToolDog model using
cwlgen library.
"""

#  Import  ------------------------------

# General libraries
import os
import logging

# External libraries
import cwlgen
from cwlgen.import_cwl import CWLToolParser

# Class and Objects

#  Constant(s)  ------------------------------

LOGGER = logging.getLogger(__name__)

#  Class(es)  ------------------------------


[docs]class CwlToolGen(object): """ Class to support generation of CWL from :class:`tooldog.biotool_model.Biotool` object. """
[docs] def __init__(self, biotool, existing_tool=None): """ Initialize a [CommandLineTool] object from cwlgen. :param biotool: Biotool object of an entry from https://bio.tools. :type biotool: :class:`tooldog.biotool_model.Biotool` """ if existing_tool: LOGGER.info("Loading existing CWL tool from " + existing_tool) ctp = CWLToolParser() self.tool = ctp.import_cwl(existing_tool) if 'None' in self.tool.doc: self.tool.doc = biotool.generate_cwl_doc() else: LOGGER.info("Creating new CwlToolGen object...") # Initialize counters for inputs and outputs self.input_ct = 0 self.output_ct = 0 # Initialize tool # Get the first sentence of the description only description = biotool.description.split('.')[0] + '.' documentation = biotool.generate_cwl_doc() self.tool = cwlgen.CommandLineTool(tool_id=biotool.tool_id, label=description, base_command="COMMAND", doc=documentation, cwl_version='v1.0') self._set_meta_from_biotool(biotool)
[docs] def add_input_file(self, input_obj): """ Add an input to the CWL tool. :param input_obj: Input object. :type input_obj: :class:`tooldog.biotool_model.Input` """ LOGGER.info("Adding input to CwlToolGen object...") # Build parameter self.input_ct += 1 # Give unique name to the input name = 'INPUT' + str(self.input_ct) # Get all different formats for this input list_formats = [] for format_obj in input_obj.formats: list_formats.append(format_obj.uri) formats = ', '.join(list_formats) # Create the parameter param_binding = cwlgen.CommandLineBinding(prefix='--' + name) param = cwlgen.CommandInputParameter(name, param_type='File', label=input_obj.data_type.term, param_format=formats, input_binding=param_binding) # Appends parameter to inputs self.tool.inputs.append(param)
[docs] def add_output_file(self, output): """ Add an output to the CWL tool. :param output: Output object. :type output: :class:`tooldog.biotool_model.Output` """ LOGGER.info("Adding output to CwlToolGen object...") # Build parameter self.output_ct += 1 # Give unique name to the output name = 'OUTPUT' + str(self.output_ct) # Get all different format for this output list_formats = [] for format_obj in output.formats: list_formats.append(format_obj.uri) formats = ', '.join(list_formats) # Create the parameter param_binding = cwlgen.CommandOutputBinding(glob=name + '.ext') param = cwlgen.CommandOutputParameter(name, param_type='File', label=output.data_type.term, param_format=formats, output_binding=param_binding) self.tool.outputs.append(param)
def _set_meta_from_biotool(self, biotool): """ Add first set of metadata found on bio.tools to the description. :param biotool: Biotool object of an entry from https://bio.tools. :type biotool: :class:`tooldog.biotool_model.Biotool` """ self.tool.metadata = cwlgen.Metadata() self.tool.metadata.name = biotool.name self.tool.metadata.about = biotool.description self.tool.metadata.url = biotool.homepage if biotool.informations.language: self.tool.metadata.programmingLanguage = biotool.informations.language
[docs] def add_publication(self, publication): """ Add publication to the tool (CWL: s:publication). :param publication: Publication object. :type publication: :class:`tooldog.biotool_model.Publication` """ LOGGER.debug("Adding publication to CwlToolGen object...") if not hasattr(self.tool.metadata, 'publication'): self.tool.metadata.publication = [] # Add citation depending the type (doi, pmid...) if publication.doi is not None: self.tool.metadata.publication.append({'id': 'http://dx.doi.org/' + publication.doi}) # <citation> only supports doi and bibtex as a type elif publication.pmid is not None: LOGGER.warn('pmid is not supported by publication, publication skipped') elif publication.pmcid is not None: LOGGER.warn('pmcid is not supported by publication, publication skipped')
[docs] def add_edam_topic(self, topic): """ Add the EDAM topic to the tool (CWL: s:topic). :param topic: Topic object. :type topic: :class:`tooldog.biotool_model.Topic` """ LOGGER.debug("Adding EDAM topic to CwlToolGen object...") if not hasattr(self.tool.metadata, 'keywords'): self.tool.metadata.keywords = [] self.tool.namespaces.edam = "https://edamontology.org/" self.tool.metadata.keywords.append('edam:' + topic.get_edam_id())
[docs] def add_edam_operation(self, operation): """ Add the EDAM operation to the tool (CWL: s:operation). :param operation: Operation object. :type operation: :class:`tooldog.biotool_model.Operation` """ LOGGER.debug("Adding EDAM operation to CwlToolGen object...") if not hasattr(self.tool.metadata, 'keywords'): self.tool.metadata.keywords = [] self.tool.namespaces.edam = "https://edamontology.org/" self.tool.metadata.keywords.append('edam:' + operation.get_edam_id())
[docs] def write_cwl(self, out_file=None, index=None): """ Write CWL to STDOUT or out_file(s). :param out_file: path to output file. :type out_file: STRING :param index: Index in case more than one function is described. :type index: INT """ # Give CWL on STDout if out_file is None: if index is not None: print('########## CWL number ' + str(index) + ' ##########') LOGGER.info("Writing CWL file to STDOUT...") self.tool.export() else: # Format name for output file(s) if index is not None: out_file = os.path.splitext(out_file)[0] + str(index) + '.cwl' else: out_file = os.path.splitext(out_file)[0] + '.cwl' LOGGER.info("Writing CWL file to " + out_file) self.tool.export(out_file)