PKU²Hʌۃgalaxyxml/__init__.pyfrom builtins import str from builtins import object from lxml import etree class GalaxyXML(object): def __init__(self): self.root = etree.Element('root') def export(self): return etree.tostring(self.root, pretty_print=True) class Util(object): @classmethod def coerce(cls, data, kill_lists=False): """Recursive data sanitisation """ if isinstance(data, dict): return {k: cls.coerce(v, kill_lists=kill_lists) for k, v in list(data.items()) if v is not None} elif isinstance(data, list): if kill_lists: return cls.coerce(data[0]) else: return [cls.coerce(v, kill_lists=kill_lists) for v in data] else: return cls.coerce_value(data) @classmethod def coerce_value(cls, obj): """Make everything a string! """ if isinstance(obj, bool): if obj: return "true" else: return "false" elif isinstance(obj, str): return obj else: return str(obj) @classmethod def clean_kwargs(cls, params, final=False): if 'kwargs' in params: kwargs = params['kwargs'] for k in kwargs: params[k] = kwargs[k] del params['kwargs'] if 'self' in params: del params['self'] # There will be more params, it would be NICE to use a whitelist # instead of a blacklist, but until we have more data let's just # blacklist stuff we see commonly. if final: for blacklist in ('positional',): if blacklist in params: del params[blacklist] return params PKU²H@Q®SSgalaxyxml/tool/__init__.pyfrom __future__ import print_function from lxml import etree from galaxyxml import Util, GalaxyXML from galaxyxml.tool.parameters import XMLParam VALID_TOOL_TYPES = ('data_source', 'data_source_async') VALID_URL_METHODS = ('get', 'post') class Tool(GalaxyXML): def __init__(self, name, id, version, description, executable, hidden=False, tool_type=None, URL_method=None, workflow_compatible=True, interpreter=None, version_command='interpreter filename.exe --version'): self.executable = executable self.interpreter = interpreter kwargs = { 'name': name, 'id': id, 'version': version, 'hidden': hidden, 'workflow_compatible': workflow_compatible, } self.version_command = version_command # Remove some of the default values to make tools look a bit nicer if not hidden: del kwargs['hidden'] if workflow_compatible: del kwargs['workflow_compatible'] kwargs = Util.coerce(kwargs) self.root = etree.Element('tool', **kwargs) if tool_type is not None: if tool_type not in VALID_TOOL_TYPES: raise Exception("Tool type must be one of %s" % ','.join(VALID_TOOL_TYPES)) else: kwargs['tool_type'] = tool_type if URL_method is not None: if URL_method in VALID_URL_METHODS: kwargs['URL_method'] = URL_method else: raise Exception("URL_method must be one of %s" % ','.join(VALID_URL_METHODS)) description_node = etree.SubElement(self.root, 'description') description_node.text = description def append_version_command(self): version_command = etree.SubElement(self.root, 'version_command') try: version_command.text = self.version_command except: pass def append(self, sub_node): if issubclass(type(sub_node), XMLParam): self.root.append(sub_node.node) else: self.root.append(sub_node) def clean_command_string(self, command_line): clean = [] for x in command_line: if x is not [] and x is not ['']: clean.append(x) return '\n'.join(clean) def export(self): command_line = [] try: command_line.append(self.inputs.cli()) except Exception as e: print(e) try: command_line.append(self.outputs.cli()) except: pass # Add stdio section stdio = etree.SubElement(self.root, 'stdio') etree.SubElement(stdio, 'exit_code', range='1:', level='fatal') # Append version command self.append_version_command() # Steal interpreter from kwargs command_kwargs = {} if self.interpreter is not None: command_kwargs['interpreter'] = self.interpreter # Add command section command_node = etree.SubElement(self.root, 'command', **command_kwargs) actual_cli = "%s %s" % (self.executable, self.clean_command_string(command_line)) command_node.text = etree.CDATA(actual_cli.strip()) try: self.append(self.inputs) except: pass try: self.append(self.outputs) except: pass help_element = etree.SubElement(self.root, 'help') help_element.text = etree.CDATA(self.help) return super(Tool, self).export() PKU²HäæòNË3Ë3%galaxyxml/tool/parameters/__init__.pyfrom builtins import str from builtins import object from lxml import etree from galaxyxml import Util class XMLParam(object): name = 'node' def __init__(self, *args, **kwargs): # http://stackoverflow.com/a/12118700 self.children = [] kwargs = {k: v for k, v in list(kwargs.items()) if v is not None} kwargs = Util.coerce(kwargs, kill_lists=True) kwargs = Util.clean_kwargs(kwargs, final=True) self.node = etree.Element(self.name, **kwargs) def append(self, sub_node): if self.acceptable_child(sub_node): # If one of ours, they aren't etree nodes, they're custom objects if issubclass(type(sub_node), XMLParam): self.node.append(sub_node.node) self.children.append(sub_node) else: raise Exception("Child was unacceptable to parent (%s is not appropriate for %s)" % (type(self), type(sub_node))) else: raise Exception("Child was unacceptable to parent (%s is not appropriate for %s)" % (type(self), type(sub_node))) def validate(self): # Very few need validation, but some nodes we may want to have # validation routines on. Should only be called when DONE. for child in self.children: # If any child fails to validate return false. if not child.validate(): return False return True def cli(self): lines = [] for child in self.children: lines.append(child.command_line()) #lines += child.command_line() return '\n'.join(lines) def command_line(self): return None class RequestParamTranslation(XMLParam): name = 'request_param_translation' def __init__(self, **kwargs): self.node = etree.Element(self.name) def acceptable_child(self, child): return isinstance(child, RequestParamTranslation) class RequestParam(XMLParam): name = 'request_param' def __init__(self, galaxy_name, remote_name, missing, **kwargs): #TODO: bulk copy locals into self.attr? self.galaxy_name = galaxy_name # http://stackoverflow.com/a/1408860 params = Util.clean_kwargs(locals().copy()) super(RequestParam, self).__init__(**params) def acceptable_child(self, child): return isinstance(child, AppendParam) and self.galaxy_name == "URL" class AppendParam(XMLParam): name = 'append_param' def __init__(self, separator="&", first_separator="?", join="=", **kwargs): params = Util.clean_kwargs(locals().copy()) super(AppendParam, self).__init__(**params) def acceptable_child(self, child): return isinstance(child, AppendParamValue) class AppendParamValue(XMLParam): name = 'value' def __init__(self, name="_export", missing="1", **kwargs): params = Util.clean_kwargs(locals().copy()) super(AppendParamValue, self).__init__(**params) def acceptable_child(self, child): return False class Inputs(XMLParam): name = 'inputs' # This bodes to be an issue -__- def acceptable_child(self, child): return issubclass(type(child), InputParameter) class InputParameter(XMLParam): def __init__(self, name, **kwargs): # TODO: look at self.mako_identifier = name # We use kwargs instead of the usual locals(), so manually copy the # name to kwargs if name is not None: kwargs['name'] = name # Handle positional parameters if 'positional' in kwargs and kwargs['positional']: self.positional = True else: self.positional = False if 'num_dashes' in kwargs: self.num_dashes = kwargs['num_dashes'] del kwargs['num_dashes'] else: self.num_dashes = 0 self.space_between_arg = " " # Not sure about this :( # https://wiki.galaxyproject.org/Tools/BestPractices#Parameter_help if 'label' in kwargs: # TODO: replace with positional attribute if len(self.flag()) > 0: if kwargs['label'] is None: kwargs['label'] = 'Author did not provide help for this parameter... ' if not self.positional: if kwargs['help'] is None: kwargs['help'] = '(%s)' % self.flag() else: kwargs['help'] += ' (%s)' % self.flag() super(InputParameter, self).__init__(**kwargs) def command_line(self): before = self.command_line_before() cli = self.command_line_actual() after = self.command_line_after() complete = [x for x in (before, cli, after) if x is not None] return '\n'.join(complete) def command_line_before(self): try: return self.command_line_before_override except: return None def command_line_after(self): try: return self.command_line_after_override except: return None def command_line_actual(self): try: return self.command_line_override except: if self.positional: return self.mako_name() else: return "%s%s%s" % (self.flag(), self.space_between_arg, self.mako_name()) def mako_name(self): # TODO: enhance logic to check up parents for things like repeat>condotion>param return '$' + self.mako_identifier def flag(self): flag = '-' * self.num_dashes return flag + self.mako_identifier class Repeat(InputParameter): name = 'repeat' def __init__(self, name, title, min=None, max=None, default=None, **kwargs): params = Util.clean_kwargs(locals().copy()) # Allow overriding self.command_line_before_override = '#for $i in $%s:' % name self.command_line_after_override = '#end for' #self.command_line_override super(Repeat, self).__init__(**params) def acceptable_child(self, child): return issubclass(type(child), InputParameter) def command_line_actual(self): if hasattr(self, 'command_line_override'): return self.command_line_override else: return "%s" % self.mako_name() class Conditional(InputParameter): name = 'conditional' def __init__(self, name, **kwargs): params = Util.clean_kwargs(locals().copy()) super(Conditional, self).__init__(**params) def acceptable_child(self, child): return issubclass(type(child), InputParameter) \ and not isinstance(child, Conditional) def validate(self): # Find a way to check if one of the kids is a WHEN pass class Param(InputParameter): name = 'param' # This...isn't really valid as-is, and shouldn't be used. def __init__(self, name, optional=None, label=None, help=None, **kwargs): params = Util.clean_kwargs(locals().copy()) params['type'] = self.type super(Param, self).__init__(**params) if type(self) == Param: raise Exception("Param class is not an actual parameter type, use a subclass of Param") def acceptable_child(self, child): return issubclass(type(child, InputParameter) or isinstance(child), ValidatorParam) class TextParam(Param): type = 'text' def __init__(self, name, optional=None, label=None, help=None, size=None, area=False, **kwargs): params = Util.clean_kwargs(locals().copy()) super(TextParam, self).__init__(**params) class _NumericParam(Param): def __init__(self, name, value, optional=None, label=None, help=None, min=None, max=None, **kwargs): params = Util.clean_kwargs(locals().copy()) super(_NumericParam, self).__init__(**params) class IntegerParam(_NumericParam): type = 'integer' class FloatParam(_NumericParam): type = 'float' class BooleanParam(Param): type = 'boolean' def __init__(self, name, optional=None, label=None, help=None, checked=False, truevalue=None, falsevalue=None, **kwargs): params = Util.clean_kwargs(locals().copy()) super(BooleanParam, self).__init__(**params) if truevalue is None: # If truevalue and falsevalue are None, then we use "auto", the IUC # recommended default. # # truevalue is set to the parameter's value, and falsevalue is not. # # Unfortunately, mako_identifier is set as a result of the super # call, which we shouldn't call TWICE, so we'll just hack around this :( #params['truevalue'] = '%s%s' % (self.) self.node.attrib['truevalue'] = self.flag() if falsevalue is None: self.node.attrib['falsevalue'] = "" def command_line_actual(self): if hasattr(self, 'command_line_override'): return self.command_line_override else: return "%s" % self.mako_name() class DataParam(Param): type = 'data' def __init__(self, name, optional=None, label=None, help=None, format=None, multiple=None, **kwargs): params = Util.clean_kwargs(locals().copy()) super(DataParam, self).__init__(**params) class SelectParam(Param): type = None def __init__(self, name, optional=None, label=None, help=None, data_ref=None, display=None, multiple=None, options=None, default=None, **kwargs): params = Util.clean_kwargs(locals().copy()) del params['options'] del params['default'] super(SelectParam, self).__init__(**params) if options is not None and default is not None: if default not in options: raise Exception("Specified a default that isn't in options") for k,v in options.items(): selected = (k == default) self.append(SelectOption(k, v, selected=selected)) def acceptable_child(self, child): return issubclass(type(child), SelectOption) class SelectOption(InputParameter): name = 'option' def __init__(self, value, text, selected=False, **kwargs): params = Util.clean_kwargs(locals().copy()) passed_kwargs = {} if selected: passed_kwargs['selected'] = "true" passed_kwargs['value'] = params['value'] super(SelectOption, self).__init__(None, **passed_kwargs) self.node.text = str(text) class ValidatorParam(InputParameter): name = 'validator' def __init__(self, type, message=None, filename=None, metadata_name=None, metadata_column=None, line_startswith=None, min=None, max=None, **kwargs): params = Util.clean_kwargs(locals().copy()) super(ValidatorParam, self).__init__(**params) class Outputs(XMLParam): name = 'outputs' def acceptable_child(self, child): return issubclass(type(child), OutputParameter) class OutputParameter(XMLParam): """Copypasta of InputParameter, needs work """ name = 'data' def __init__(self, name, format, format_source=None, metadata_source=None, label=None, from_work_dir=None, hidden=False, **kwargs): # TODO: validate format_source&metadata_source against something in the # XMLParam children tree. self.mako_identifier = name if 'num_dashes' in kwargs: self.num_dashes = kwargs['num_dashes'] del kwargs['num_dashes'] else: self.num_dashes = 0 self.space_between_arg = " " params = Util.clean_kwargs(locals().copy()) super(OutputParameter, self).__init__(**params) def command_line(self): if hasattr(self, 'command_line_override'): return self.command_line_override else: return "%s%s%s" % (self.flag(), self.space_between_arg, self.mako_name()) def mako_name(self): return '$' + self.mako_identifier def flag(self): flag = '-' * self.num_dashes return flag + self.mako_identifier def acceptable_child(self, child): return isinstance(child, OutputFilter) or isinstance(child, ChangeFormat) class OutputFilter(XMLParam): name = 'filter' def __init__(self, text, **kwargs): params = Util.clean_kwargs(locals().copy()) del params['text'] super(OutputFilter, self).__init__(**params) self.node.text = text def acceptable_child(self, child): return False class ChangeFormat(XMLParam): name = 'change_format' def __init__(self, **kwargs): params = Util.clean_kwargs(locals().copy()) super(ChangeFormat, self).__init__(**params) def acceptable_child(self, child): return isinstance(child, ChangeFormatWhen) class ChangeFormatWhen(XMLParam): name = 'when' def __init__(self, input, format, value, **kwargs): params = Util.clean_kwargs(locals().copy()) super(ChangeFormatWhen, self).__init__(**params) def acceptable_child(self, child): return False PKa²H^-Ò )galaxyxml-0.2.1.dist-info/DESCRIPTION.rstUNKNOWN PKa²HE“jFF'galaxyxml-0.2.1.dist-info/metadata.json{"classifiers": ["Development Status :: 3 - Alpha", "Operating System :: OS Independent", "Intended Audience :: Developers", "Environment :: Console", "License :: OSI Approved :: Apache Software License"], "extensions": {"python.details": {"contacts": [{"email": "esr@tamu.edu", "name": "Eric Rasche", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}}}, "extras": [], "generator": "bdist_wheel (0.26.0)", "metadata_version": "2.0", "name": "galaxyxml", "run_requires": [{"requires": ["lxml"]}], "summary": "Galaxy XML generation library", "version": "0.2.1"}PKa²Hš†å 'galaxyxml-0.2.1.dist-info/top_level.txtgalaxyxml PKa²HŒ''\\galaxyxml-0.2.1.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py2-none-any PKa²HC<:ÉÉ"galaxyxml-0.2.1.dist-info/METADATAMetadata-Version: 2.0 Name: galaxyxml Version: 0.2.1 Summary: Galaxy XML generation library Home-page: UNKNOWN Author: Eric Rasche Author-email: esr@tamu.edu License: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Operating System :: OS Independent Classifier: Intended Audience :: Developers Classifier: Environment :: Console Classifier: License :: OSI Approved :: Apache Software License Requires-Dist: lxml UNKNOWN PKa²HoÑý$ùù galaxyxml-0.2.1.dist-info/RECORDgalaxyxml/__init__.py,sha256=Fl2bgomWcPkG3cNwIAwTFN7BgX-iQekVJ6XudSIjAA8,1794 galaxyxml/tool/__init__.py,sha256=_YaaYjReNajeg5p4rFP_PahpUe_hdLGKiIfUl-W8zFY,3667 galaxyxml/tool/parameters/__init__.py,sha256=nKtL-63lTEH-1jgne-SVTSt9bOJf4jmLU1H-WolBsTQ,13259 galaxyxml-0.2.1.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10 galaxyxml-0.2.1.dist-info/METADATA,sha256=oVVo6bx8KMGbmigcI7S1JRjW6PkK1wd1n5ArYvEruNA,457 galaxyxml-0.2.1.dist-info/RECORD,, galaxyxml-0.2.1.dist-info/WHEEL,sha256=JTb7YztR8fkPg6aSjc571Q4eiVHCwmUDlX8PhuuqIIE,92 galaxyxml-0.2.1.dist-info/metadata.json,sha256=KRjPepf0E7f9rmOSf10SKJjttjomZ8P99TGJgCyfZLY,582 galaxyxml-0.2.1.dist-info/top_level.txt,sha256=ypP2XKsxXPcxhcgwHz9Z5UuR-krolYUF6NqHbOHDdAA,10 PKU²Hʌۃgalaxyxml/__init__.pyPKU²H@Q®SS5galaxyxml/tool/__init__.pyPKU²HäæòNË3Ë3%Àgalaxyxml/tool/parameters/__init__.pyPKa²H^-Ò )ÎIgalaxyxml-0.2.1.dist-info/DESCRIPTION.rstPKa²HE“jFF'Jgalaxyxml-0.2.1.dist-info/metadata.jsonPKa²Hš†å 'ªLgalaxyxml-0.2.1.dist-info/top_level.txtPKa²HŒ''\\ùLgalaxyxml-0.2.1.dist-info/WHEELPKa²HC<:ÉÉ"’Mgalaxyxml-0.2.1.dist-info/METADATAPKa²HoÑý$ùù ›Ogalaxyxml-0.2.1.dist-info/RECORDPK ÊÒR