+++ /dev/null
-"""General mechanisms to access applications in biopython.
-"""
-import os, sys
-import StringIO
-
-from Bio import File
-
-def generic_run(commandline):
- """Run an application with the given commandline.
-
- This expects a pre-built commandline that derives from
- AbstractCommandline, and returns a ApplicationResult object
- to get results from a program, along with handles of the
- standard output and standard error.
-
- WARNING - This will read in the full program output into memory!
- This may be in issue when the program write a large amount of
- data to standard output.
- """
- # print str(commandline)
-
- #Try and use subprocess (available in python 2.4+)
- try :
- import subprocess, sys
- #We don't need to supply any piped input, but we setup the
- #standard input pipe anyway as a work around for a python
- #bug if this is called from a Windows GUI program. For
- #details, see http://bugs.python.org/issue1124861
- child = subprocess.Popen(str(commandline),
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- shell=(sys.platform!="win32"))
- child.stdin.close()
- r = child.stdout
- e = child.stderr
-
- r_out = r.read()
- e_out = e.read()
- r.close()
- e.close()
-
- # capture error code
- error_code = child.wait()
-
- except ImportError :
- #For python 2.3 can't use subprocess, using popen2 instead
- #(deprecated in python 2.6)
- import popen2
- if sys.platform[:3]=='win':
- # Windows does not have popen2.Popen3
- r, w, e = popen2.popen3(str(commandline))
-
- r_out = r.read()
- e_out = e.read()
- w.close()
- r.close()
- e.close()
-
- # No way to get the error code; setting it to a dummy variable
- error_code = 0
-
- else:
- child = popen2.Popen3(str(commandline), 1)
- # get information and close the files, so if we call this function
- # repeatedly we won't end up with too many open files
-
- # here are the file descriptors
- r = child.fromchild
- w = child.tochild
- e = child.childerr
-
- r_out = r.read()
- e_out = e.read()
- w.close()
- r.close()
- e.close()
-
- # capture error code
- error_code = os.WEXITSTATUS(child.wait())
-
- return ApplicationResult(commandline, error_code), \
- File.UndoHandle(StringIO.StringIO(r_out)), \
- File.UndoHandle(StringIO.StringIO(e_out))
-
-class ApplicationResult:
- """Make results of a program available through a standard interface.
-
- This tries to pick up output information available from the program
- and make it available programmatically.
- """
- def __init__(self, application_cl, return_code):
- """Intialize with the commandline from the program.
- """
- self._cl = application_cl
-
- # provide the return code of the application
- self.return_code = return_code
-
- # get the application dependent results we can provide
- # right now the only results we handle are output files
- self._results = {}
-
- for parameter in self._cl.parameters:
- if "file" in parameter.param_types and \
- "output" in parameter.param_types:
- if parameter.is_set:
- self._results[parameter.names[-1]] = parameter.value
-
- def get_result(self, output_name):
- """Retrieve result information for the given output.
- """
- return self._results[output_name]
-
- def available_results(self):
- """Retrieve a list of all available results.
- """
- result_names = self._results.keys()
- result_names.sort()
- return result_names
-
-class AbstractCommandline:
- """Generic interface for running applications from biopython.
-
- This class shouldn't be called directly; it should be subclassed to
- provide an implementation for a specific application.
- """
- def __init__(self):
- self.program_name = ""
- self.parameters = []
-
- def __str__(self):
- """Make the commandline with the currently set options.
- """
- commandline = "%s " % self.program_name
- for parameter in self.parameters:
- if parameter.is_required and not(parameter.is_set):
- raise ValueError("Parameter %s is not set." % parameter.names)
- if parameter.is_set:
- commandline += str(parameter)
-
- return commandline
-
- def set_parameter(self, name, value = None):
- """Set a commandline option for a program.
- """
- set_option = 0
- for parameter in self.parameters:
- if name in parameter.names:
- if value is not None:
- self._check_value(value, name, parameter.checker_function)
- parameter.value = value
- parameter.is_set = 1
- set_option = 1
-
- if set_option == 0:
- raise ValueError("Option name %s was not found." % name)
-
- def _check_value(self, value, name, check_function):
- """Check whether the given value is valid.
-
- This uses the passed function 'check_function', which can either
- return a [0, 1] (bad, good) value or raise an error. Either way
- this function will raise an error if the value is not valid, or
- finish silently otherwise.
- """
- if check_function is not None:
- is_good = check_function(value)
- if is_good in [0, 1]: # if we are dealing with a good/bad check
- if not(is_good):
- raise ValueError(
- "Invalid parameter value %r for parameter %s" %
- (value, name))
-
-class _AbstractParameter:
- """A class to hold information about a parameter for a commandline.
-
- Do not use this directly, instead use one of the subclasses.
-
- Attributes:
-
- o names -- a list of string names by which the parameter can be
- referenced (ie. ["-a", "--append", "append"]). The first name in
- the list is considered to be the one that goes on the commandline,
- for those parameters that print the option. The last name in the list
- is assumed to be a "human readable" name describing the option in one
- word.
-
- o param_type -- a list of string describing the type of parameter,
- which can help let programs know how to use it. Example descriptions
- include 'input', 'output', 'file'
-
- o checker_function -- a reference to a function that will determine
- if a given value is valid for this parameter. This function can either
- raise an error when given a bad value, or return a [0, 1] decision on
- whether the value is correct.
-
- o description -- a description of the option.
-
- o is_required -- a flag to indicate if the parameter must be set for
- the program to be run.
-
- o is_set -- if the parameter has been set
-
- o value -- the value of a parameter
- """
- def __init__(self, names = [], types = [], checker_function = None,
- is_required = 0, description = ""):
- self.names = names
- self.param_types = types
- self.checker_function = checker_function
- self.description = description
- self.is_required = is_required
-
- self.is_set = 0
- self.value = None
-
-class _Option(_AbstractParameter):
- """Represent an option that can be set for a program.
-
- This holds UNIXish options like --append=yes and -a yes
- """
- def __str__(self):
- """Return the value of this option for the commandline.
- """
- # first deal with long options
- if self.names[0].find("--") >= 0:
- output = "%s" % self.names[0]
- if self.value is not None:
- output += "=%s " % self.value
- else:
- output += " "
- # now short options
- elif self.names[0].find("-") >= 0:
- output = "%s " % self.names[0]
- if self.value is not None:
- output += "%s " % self.value
- else:
- raise ValueError("Unrecognized option type: %s" % self.names[0])
-
- return output
-
-class _Argument(_AbstractParameter):
- """Represent an argument on a commandline.
- """
- def __str__(self):
- if self.value is not None:
- return "%s " % self.value
- else:
- return " "