Skip to main content

Advanced GetOpt Wrapper

Project description

How to use it

You write stuff that looks like this, containing all of the information you would ever need about a tool; options, test cases, metadata

"""
DESCRIPTION
===========

Print out options passed to it
"""
from galaxygetopt.ggo import GalaxyGetOpt as GGO
c = GGO(
    options=[
        ['int', 'An integer parameter', {'required': True, 'validate':
                                         'Int', 'default': 10}],
        ['float', 'A float', {'required': True, 'validate': 'Float',
                              'default': 1e-4}],
        ['string', 'A string value', {'required': True, 'multiple': True,
                                      'default': ['Hello', 'World'],
                                      'validate': 'String'}],
        [],
        ['Advanced'],
        ['option', 'A selection type parameter', {'required': False,
                                                  'validate': 'Option',
                                                  'options': {'a': 'Alpha',
                                                              'b': 'Bravo'}
                                                  }],
    ],
    outputs=[
        [
            'test_output',
            'Main output file of this utility',
            {
                'validate': 'File/Output',
                'required': True,
                'default': 'ggo_out.complex',
                'data_format': 'text/tabular',
                'default_format': 'TSV_U',
            }
        ]
    ],
    defaults={
        'appid': 'ggo.testscript.complex',
        'appname': 'GGO Complex Test Script',
        'appdesc': 'tests functinoality of ggo',
        'appvers': '1.0.0',
    },
    tests=[
        {
            'test_name': 'Default',
            'params': {'tag': 'CDS'},
            'outputs': {
                'test_output': ['ggo_out.complex.Sheet1.tsv', 'galaxygetopt/tests/test_file.tsv'],
            }
        }
    ],
    doc=__doc__
})
param_dict = c.params()

And you get data back in a nice dict, just like when using Getopt::Long::Descriptive. Life is good again!

{'int': 40, 'float': '1e-4', 'string': ['Hello', 'World'] }

–help me

Automatically generated

usage: example.py [-h] [--version] [-v] [--file [FILE]] [--int [INT]]
                  [--option [{a,b}]] [--test_output [TEST_OUTPUT]]
                  [--test_output_format [TEST_OUTPUT_FORMAT]]

Example Utility: prints out options passed to it

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -v, --verbose         Produce more verbose output

Options:
  --file [FILE]         Input file [Required]
  --int [INT]           An integer (Default: 30) [Required]
  --option [{a,b}]      A selection type parameter (Default: []) (Options:
                        Alpha [a], Bravo [b]

Output Files:
  --test_output [TEST_OUTPUT]
                        Output Data (Default: ggo_out.complex) [Required]
  --test_output_format [TEST_OUTPUT_FORMAT]
                        Associated Format for test_output (Default: TSV_U)
                        [Required]

XML Generation

I usually pipe my stuff through xmllint --pretty 1 - in order to reformat things nicely. The example script produces the following XML:

<?xml version="1.0"?>
<tool id="org.cpt.examples.GGOPoster" name="Example Utility" version="1.0.0">
  <description>prints out options passed to it</description>
  <version_command>python /home/hxr/work/gcc2014/poster/example.py --version</version_command>
  <stdio>
    <exit_code level="fatal" range="1:"/>
  </stdio>
  <command interpreter="python">/home/hxr/work/gcc2014/poster/example.py
--galaxy
--outfile_supporting $__new_file_path__
--file "${file}"

--int "${int}"

#for $item in $repeat_option:
--option "${item.option}"
#end for

--test_output "${test_output}"

--test_output_files_path "${test_output.files_path}"

--test_output_format "${test_output_format}"

--test_output_id "${test_output.id}"

</command>
  <inputs>
    <param help="Input file" label="file" name="file" optional="False" type="data"/>
    <param help="An integer" label="int" min="10" name="int" optional="False" type="integer" value="30"/>
    <repeat name="repeat_option" title="Option">
      <param help="A selection type parameter" label="option" name="option" optional="True" type="select">
        <option value="a">Alpha</option>
        <option value="b">Bravo</option>
      </param>
    </repeat>
    <param help="Output Data" label="Format of test_output" name="test_output_format" optional="False" type="select">
      <option value="CSV">CSV</option>
      <option value="CSV_U">CSV_U</option>
      <option value="Dumper">Dumper</option>
      <option value="JSON">JSON</option>
      <option value="ODS">ODS</option>
      <option value="TSV">TSV</option>
      <option selected="True" value="TSV_U">TSV_U</option>
      <option value="XLS">XLS</option>
      <option value="XLSX">XLSX</option>
      <option value="YAML">YAML</option>
    </param>
  </inputs>
  <outputs>
    <data format="TSV_U" name="test_output">
      <change_format>
        <when format="tabular" input="test_output_format" value="CSV"/>
        <when format="tabular" input="test_output_format" value="CSV_U"/>
        <when format="txt" input="test_output_format" value="Dumper"/>
        <when format="txt" input="test_output_format" value="JSON"/>
        <when format="data" input="test_output_format" value="ODS"/>
        <when format="tabular" input="test_output_format" value="TSV"/>
        <when format="tabular" input="test_output_format" value="TSV_U"/>
        <when format="data" input="test_output_format" value="XLS"/>
        <when format="data" input="test_output_format" value="XLSX"/>
        <when format="txt" input="test_output_format" value="YAML"/>
      </change_format>
    </data>
  </outputs>
  <help>DESCRIPTION
===========

Print out options passed to it
</help>
  <tests>
    <test>
      <output file="galaxygetopt/tests/test_file.tsv" name="test_output"/>
    </test>
  </tests>
</tool>

Generated Tests

Generating test scripts is very nice since that is more code that should not be duplicated. It generates a very simple test script which asserts that the created file and the static test file are equivalent.

#!/usr/bin/env python
import difflib
import unittest
import shlex, subprocess
import os

class TestScript(unittest.TestCase):

    def setUp(self):
        self.base = ['python', '/home/hxr/work/gcc2014/poster/example.py']
        self.tests = [{'outputs': {'test_output': ['ggo_out.complex.Sheet1.tsv', 'galaxygetopt/tests/test_file.tsv']}, 'command_line': '', 'test_name': 'Default'}]
    def test_run(self):
        for test_case in self.tests:
            failed_test = False
            try:
                current_command = self.base + \
                    shlex.split(test_case['command_line'])
                # Should probably be wrapped in an assert as well
                subprocess.check_call(current_command)

                for fileset in test_case['outputs']:
                    failed_test = self.file_comparison(
                            test_case['outputs'][fileset][0],
                            test_case['outputs'][fileset][1])
            except:
                raise
            self.assertFalse(failed_test)

    def file_comparison(self, test_file, comp_file):
        failed_test = False
        diff=difflib.unified_diff(open(test_file).readlines(),
                           open(comp_file).readlines())
        try:
            while True:
                print diff.next(),
                failed_test = True
        except:
            pass
        try:
            # Attempt to remove the generated file to cut down on
            # clutter/other bad things
            os.unlink(test_file)
        except:
            pass
        return failed_test

if __name__ == '__main__':
    unittest.main()

Known Bugs

Currently there is a known bug in the galaxy XML, under highly specific circumstances. If you define a parameter that is

  • required

  • hidden

  • validate String (probably not a hard req)

  • _galaxy_specific

and expect it to properly generate the value, it will not. See lines 206/207 of galaxygetopt/ggo.py for the current hack I use to get around this.

Other

This library features a number of subclasses of galaxygetopt.parameter.parameter, all of which have myriad numbers of options. In order to brutally test these, I have added a class galaxygetopt/tests/parameter_generator.py which can generate every single possible combination of functional calls, given rules you specify. You can then generate hundreds of objects with different sets of options, which you can filter a subset out and test at will. See that classes’s documentation for more information.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

galaxygetopt-0.9.1.tar.gz (15.0 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page