[med-svn] [python-galaxyxml] 01/11: Imported Upstream version 0.1
Andreas Tille
tille at debian.org
Sat Jan 14 14:55:22 UTC 2017
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository python-galaxyxml.
commit 9bbb0a5ea094eed53a61c1c8c07bdfaf4b682614
Author: Anton Khodak <anton.khodak at ukr.net>
Date: Sat Jan 14 15:43:42 2017 +0200
Imported Upstream version 0.1
---
.gitignore | 67 ++++++
README.md | 20 ++
examples/example.py | 51 +++++
examples/tool.xml | 20 ++
galaxyxml/__init__.py | 47 ++++
galaxyxml/tool/__init__.py | 103 +++++++++
galaxyxml/tool/parameters/__init__.py | 400 ++++++++++++++++++++++++++++++++++
parser.py | 119 ++++++++++
requirements.txt | 1 +
setup.py | 19 ++
10 files changed, 847 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..47af8f3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,67 @@
+# Created by https://www.gitignore.io
+
+### vim ###
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+*.un~
+Session.vim
+.netrwhist
+*~
+
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..32dcbe7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+# Galaxy XML Generation Libraries
+
+These libraries will support building of Tool XML and Tool Dependencies XML.
+We'd be happy to support any other XML that Galaxy supports, just make an issue
+or PR if you're feeling motivated.
+
+## Status
+
+- ToolXML is mostly supported, there
+
+## Known Bugs
+
+- no validation of unique names
+- repeats aren't named properly
+- conditional/whens aren't named properly
+- conditionals not handled in CLI
+
+## License
+
+- Apache License, v2
diff --git a/examples/example.py b/examples/example.py
new file mode 100644
index 0000000..c97d48a
--- /dev/null
+++ b/examples/example.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+import galaxyxml.tool as gxt
+import galaxyxml.tool.parameters as gxtp
+
+tool = gxt.Tool("aragorn", 'se.lu.mbioekol.mbio-serv2.aragorn',
+ "1.2.36", "Aragorn is a tRNA finder", "aragorn.exe")
+
+inputs = gxtp.Inputs()
+outputs = gxtp.Outputs()
+
+# A parameter
+param = gxtp.BooleanParam('flag', label='Flag label', help='Flag help', num_dashes=1)
+# Yes I know this is rubbish. Please make a PR!!
+param.space_between_arg = ' '
+inputs.append(param)
+
+
+# A float
+param = gxtp.FloatParam('float', label='Float label',
+ help='Float help', value=0, num_dashes=1)
+param.space_between_arg = ' '
+inputs.append(param)
+
+
+param_min = gxtp.IntegerParam('int_min',
+ label='int_min label',
+ help='int_min help', value=0, num_dashes=1)
+param_max = gxtp.IntegerParam('int_max',
+ label='int_max label',
+ help='int_max help', value=0, num_dashes=1)
+param_min.command_line_override = '-i$int_min,$int_max'
+param_max.command_line_override = ''
+param_min.space_between_arg = ' '
+param_max.space_between_arg = ' '
+inputs.append(param_min)
+inputs.append(param_max)
+
+
+# Outputs
+param = gxtp.OutputParameter('output', format="tabular", num_dashes=1)
+param.space_between_arg = ' '
+outputs.append(param)
+
+tool.inputs = inputs
+tool.outputs = outputs
+tool.help = 'HI'
+
+data = tool.export()
+
+with open('tool.xml', 'w') as handle:
+ handle.write(data)
diff --git a/examples/tool.xml b/examples/tool.xml
new file mode 100644
index 0000000..a7c64a8
--- /dev/null
+++ b/examples/tool.xml
@@ -0,0 +1,20 @@
+<tool force_history_refresh="false" hidden="false" id="se.lu.mbioekol.mbio-serv2.aragorn" name="aragorn" version="1.2.36" workflow_compatible="true">
+ <description>Aragorn is a tRNA finder</description>
+ <stdio>
+ <exit_code level="fatal" range="1:"/>
+ </stdio>
+ <command><![CDATA[aragorn.exe $flag
+-float $float
+-i$int_min,$int_max
+-output $output]]></command>
+ <inputs>
+ <param checked="false" help="(-flag) Flag help" label="Flag label" name="flag" type="boolean" truevalue="-flag"/>
+ <param help="(-float) Float help" label="Float label" name="float" type="float" value="0"/>
+ <param help="(-int_min) int_min help" label="int_min label" name="int_min" type="integer" value="0"/>
+ <param help="(-int_max) int_max help" label="int_max label" name="int_max" type="integer" value="0"/>
+ </inputs>
+ <outputs>
+ <data format="tabular" hidden="false" name="output"/>
+ </outputs>
+ <help><![CDATA[HI]]></help>
+</tool>
diff --git a/galaxyxml/__init__.py b/galaxyxml/__init__.py
new file mode 100644
index 0000000..0d2e959
--- /dev/null
+++ b/galaxyxml/__init__.py
@@ -0,0 +1,47 @@
+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):
+ """Recursive data sanitisation
+ """
+ if isinstance(data, dict):
+ return {k: cls.coerce(v) for k, v in data.items() if v is not None}
+ elif isinstance(data, list):
+ return [cls.coerce(v) 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):
+ if 'kwargs' in params:
+ kwargs = params['kwargs']
+ for k in kwargs:
+ params[k] = kwargs[k]
+ del params['kwargs']
+ del params['self']
+ return params
diff --git a/galaxyxml/tool/__init__.py b/galaxyxml/tool/__init__.py
new file mode 100644
index 0000000..6e077df
--- /dev/null
+++ b/galaxyxml/tool/__init__.py
@@ -0,0 +1,103 @@
+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,
+ force_history_refresh=False, interpreter=None):
+
+ self.executable = executable
+ self.interpreter = interpreter
+ kwargs = {
+ 'name': name,
+ 'id': id,
+ 'version': version,
+ 'hidden': hidden,
+ 'workflow_compatible': workflow_compatible,
+ 'force_history_refresh': force_history_refresh,
+ }
+ 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 version_command(self, command_string):
+ version_command = etree.SubElement(self.root, 'version_command')
+ version_command.text = version_command
+
+ 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, 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')
+
+ # 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()
diff --git a/galaxyxml/tool/parameters/__init__.py b/galaxyxml/tool/parameters/__init__.py
new file mode 100644
index 0000000..1703adb
--- /dev/null
+++ b/galaxyxml/tool/parameters/__init__.py
@@ -0,0 +1,400 @@
+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 kwargs.items() if v is not None}
+ kwargs = Util.coerce(kwargs)
+ 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
+ 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:
+ kwargs['label'] += ' (%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):
+ return None
+
+ def command_line_after(self):
+ return None
+
+ def command_line_actual(self):
+ if hasattr(self, 'command_line_override'):
+ return self.command_line_override
+ else:
+ 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.cli_before = '#for $i in $%s' % name
+ self.cli_after = '#end for'
+ super(Repeat, self).__init__(**params)
+
+ def acceptable_child(self, child):
+ return issubclass(type(child), InputParameter)
+
+ def command_line_before(self):
+ return self.cli_before
+
+ def command_line_after(self):
+ return self.cli_after
+
+ 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 and falsevalue 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()
+
+
+ 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 = 'data'
+
+ 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(DataParam, 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:
+ selected = (k == default)
+ self.append(SelectOption(k, v, selected=selected))
+
+
+class SelectOption(InputParameter):
+ name = 'option'
+
+ def __init__(self, value, text, selected=False, **kwargs):
+ params = Util.clean_kwargs(locals().copy())
+ del params['text']
+ super(SelectOption, self).__init__(**params)
+ self.node.text = 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
diff --git a/parser.py b/parser.py
new file mode 100644
index 0000000..e822ef6
--- /dev/null
+++ b/parser.py
@@ -0,0 +1,119 @@
+import re
+
+def start_pattern(string):
+ return string.startswith(' -')
+
+
+CLI = {
+ 'OUTPUT': (re.compile(r'^\s*(?P<dash>--?)(?P<name>[A-Za-z0-9]+)(?P<space_between_arg>[ ]*)<(?P<args>out[^>]*)>\s+(?P<content>.*)'), {'nargs': 1}),
+ 'FLAG': (re.compile(r'^\s*(?P<dash>--?)(?P<name>[A-Za-z0-9]+)[ ]{2,}(?P<content>.*)'), {'nargs': 0}),
+ 'PARAM': (re.compile(r'^\s*(?P<dash>--?)(?P<name>[A-Za-z0-9]+)(?P<space_between_arg>[ ]*)<(?P<args>[^>]*)>\s+(?P<content>.*)'), {'nargs': 1}),
+ 'PARAM_RANGE': (re.compile(r'^\s*(?P<dash>--?)(?P<name>[A-Za-z0-9]+)(?P<space_between_arg>[ ]*)<(?P<args>[^>]*)>,<(?P<args2>[^>]*)>\s+(?P<content>.*)'), {'nargs': 2}),
+}
+
+CLI_GROUPS = ('name', 'args', 'content', 'args2', 'dash', 'space_between_arg')
+CLI_DEFAULTS = {
+ 'space_between_arg': ' '
+}
+
+def detect_args(cli):
+ for matcher in CLI:
+ matches = CLI[matcher][0].search(cli)
+ if matches:
+ hit = CLI[matcher][1]
+ hit['type'] = matcher
+
+ # Apply defaults. Poorly organised.
+ for default in CLI_DEFAULTS:
+ hit[default] = CLI_DEFAULTS[default]
+
+ # Actual groups in regex
+ for group in CLI_GROUPS:
+ try:
+ hit[group] = matches.group(group)
+ except IndexError:
+ # Ignore missing groups
+ pass
+ return hit
+ return None
+
+def reflow_block(block):
+ single = ' '.join([x.strip() for x in block])
+ return detect_args(single)
+
+def blocks(iterable):
+ accumulator = []
+ for line in iterable:
+ if start_pattern(line):
+ if accumulator:
+ yield reflow_block(accumulator)
+ accumulator = [line]
+ else:
+ accumulator.append(line)
+ if accumulator:
+ yield reflow_block(accumulator)
+
+import galaxyxml.tool as gxt
+import galaxyxml.tool.parameters as gxtp
+
+tool = gxt.Tool(name="aragorn", version="1.2.36", description="tRNA finder",
+ executable="aragorn")
+inputs = gxtp.Inputs()
+outputs = gxtp.Outputs()
+for line in blocks(open('tmp','r').readlines()):
+ if line and line['type'] == 'FLAG':
+ param = gxtp.BooleanParam(line['name'], label=line['name'], help=line['content'],
+ #truevalue=cli_param, falsevalue="")
+ )
+ param.num_dashes = len(line['dash'])
+ param.space_between_arg = line['space_between_arg']
+ inputs.append(param)
+ elif line and line['type'] == 'PARAM':
+ print "%(dash)s%(name)s <%(args)s> %(content)s" % line
+ answer = raw_input("Is this a FLOAT, INT, or TEXT input? ")
+ if 'FLOAT' in answer:
+ param = gxtp.FloatParam(line['name'], label=line['name'],
+ help=line['content'], value=0)
+ elif 'INT' in answer:
+ param = gxtp.IntegerParam(line['name'], label=line['name'],
+ help=line['content'], value=0)
+ elif 'TEXT' in answer:
+ param = gxtp.TextParam(line['name'], label=line['name'],
+ help=line['content'])
+ try:
+ param.num_dashes = len(line['dash'])
+ param.space_between_arg = line['space_between_arg']
+ inputs.append(param)
+ except:
+ print "Uhoh, bad answer"
+ print
+ elif line and line['type'] == 'PARAM_RANGE':
+ param_min = gxtp.IntegerParam(line['name']+'_min',
+ label=line['name']+'_min',
+ help=line['content'], value=0)
+ param_max = gxtp.IntegerParam(line['name']+'_max',
+ label=line['name']+'_max',
+ help=line['content'], value=0)
+ param_min.command_line_override = '-i$i_min,$i_max'
+ param_max.command_line_override = ''
+ param_min.num_dashes = len(line['dash'])
+ param_max.num_dashes = len(line['dash'])
+ param_min.space_between_arg = line['space_between_arg']
+ param_max.space_between_arg = line['space_between_arg']
+ inputs.append(param_min)
+ inputs.append(param_max)
+ elif line and line['type'] == 'OUTPUT':
+ param = gxtp.OutputParameter(line['name'], format="tabular")
+ param.num_dashes = len(line['dash'])
+ param.space_between_arg = line['space_between_arg']
+ outputs.append(param)
+
+tool.inputs = inputs
+tool.outputs = outputs
+tool.help = 'HI'
+
+
+data = tool.export()
+
+with open('tool.xml', 'w') as handle:
+ handle.write(data)
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..ab90481
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+lxml
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..90a9146
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,19 @@
+from setuptools import setup
+
+requirements = [x.strip() for x in open('requirements.txt', 'r').readlines()]
+
+setup(name="galaxyxml",
+ version='0.1',
+ description='Galaxy XML generation library',
+ author='Eric Rasche',
+ author_email='rasche.eric at yandex.ru',
+ license='GPL3',
+ install_requires=requirements,
+ packages=["galaxyxml", "galaxyxml.tool", "galaxyxml.tool.parameters"],
+ classifiers=[
+ 'Development Status :: 3 - Alpha',
+ 'Operating System :: OS Independent',
+ 'Intended Audience :: Developers',
+ 'Environment :: Console',
+ ],
+ )
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-galaxyxml.git
More information about the debian-med-commit
mailing list