1 """General mechanisms to access applications in biopython.
2 """
3 import os, sys
4 import StringIO
5
6 from Bio import File
7
9 """Run an application with the given commandline.
10
11 This expects a pre-built commandline that derives from
12 AbstractCommandline, and returns a ApplicationResult object
13 to get results from a program, along with handles of the
14 standard output and standard error.
15
16 WARNING - This will read in the full program output into memory!
17 This may be in issue when the program write a large amount of
18 data to standard output.
19 """
20
21
22
23 try :
24 import subprocess, sys
25
26
27
28
29 child = subprocess.Popen(str(commandline),
30 stdin=subprocess.PIPE,
31 stdout=subprocess.PIPE,
32 stderr=subprocess.PIPE,
33 shell=(sys.platform!="win32"))
34 child.stdin.close()
35 r = child.stdout
36 e = child.stderr
37
38 r_out = r.read()
39 e_out = e.read()
40 r.close()
41 e.close()
42
43
44 error_code = child.wait()
45
46 except ImportError :
47
48
49 import popen2
50 if sys.platform[:3]=='win':
51
52 r, w, e = popen2.popen3(str(commandline))
53
54 r_out = r.read()
55 e_out = e.read()
56 w.close()
57 r.close()
58 e.close()
59
60
61 error_code = 0
62
63 else:
64 child = popen2.Popen3(str(commandline), 1)
65
66
67
68
69 r = child.fromchild
70 w = child.tochild
71 e = child.childerr
72
73 r_out = r.read()
74 e_out = e.read()
75 w.close()
76 r.close()
77 e.close()
78
79
80 error_code = os.WEXITSTATUS(child.wait())
81
82 return ApplicationResult(commandline, error_code), \
83 File.UndoHandle(StringIO.StringIO(r_out)), \
84 File.UndoHandle(StringIO.StringIO(e_out))
85
87 """Make results of a program available through a standard interface.
88
89 This tries to pick up output information available from the program
90 and make it available programmatically.
91 """
92 - def __init__(self, application_cl, return_code):
93 """Intialize with the commandline from the program.
94 """
95 self._cl = application_cl
96
97
98 self.return_code = return_code
99
100
101
102 self._results = {}
103
104 for parameter in self._cl.parameters:
105 if "file" in parameter.param_types and \
106 "output" in parameter.param_types:
107 if parameter.is_set:
108 self._results[parameter.names[-1]] = parameter.value
109
111 """Retrieve result information for the given output.
112 """
113 return self._results[output_name]
114
116 """Retrieve a list of all available results.
117 """
118 result_names = self._results.keys()
119 result_names.sort()
120 return result_names
121
123 """Generic interface for running applications from biopython.
124
125 This class shouldn't be called directly; it should be subclassed to
126 provide an implementation for a specific application.
127 """
129 self.program_name = ""
130 self.parameters = []
131
133 """Make the commandline with the currently set options.
134 """
135 commandline = "%s " % self.program_name
136 for parameter in self.parameters:
137 if parameter.is_required and not(parameter.is_set):
138 raise ValueError("Parameter %s is not set." % parameter.names)
139 if parameter.is_set:
140 commandline += str(parameter)
141
142 return commandline
143
158
160 """Check whether the given value is valid.
161
162 This uses the passed function 'check_function', which can either
163 return a [0, 1] (bad, good) value or raise an error. Either way
164 this function will raise an error if the value is not valid, or
165 finish silently otherwise.
166 """
167 if check_function is not None:
168 is_good = check_function(value)
169 if is_good in [0, 1]:
170 if not(is_good):
171 raise ValueError(
172 "Invalid parameter value %r for parameter %s" %
173 (value, name))
174
176 """A class to hold information about a parameter for a commandline.
177
178 Do not use this directly, instead use one of the subclasses.
179
180 Attributes:
181
182 o names -- a list of string names by which the parameter can be
183 referenced (ie. ["-a", "--append", "append"]). The first name in
184 the list is considered to be the one that goes on the commandline,
185 for those parameters that print the option. The last name in the list
186 is assumed to be a "human readable" name describing the option in one
187 word.
188
189 o param_type -- a list of string describing the type of parameter,
190 which can help let programs know how to use it. Example descriptions
191 include 'input', 'output', 'file'
192
193 o checker_function -- a reference to a function that will determine
194 if a given value is valid for this parameter. This function can either
195 raise an error when given a bad value, or return a [0, 1] decision on
196 whether the value is correct.
197
198 o description -- a description of the option.
199
200 o is_required -- a flag to indicate if the parameter must be set for
201 the program to be run.
202
203 o is_set -- if the parameter has been set
204
205 o value -- the value of a parameter
206 """
207 - def __init__(self, names = [], types = [], checker_function = None,
208 is_required = 0, description = ""):
209 self.names = names
210 self.param_types = types
211 self.checker_function = checker_function
212 self.description = description
213 self.is_required = is_required
214
215 self.is_set = 0
216 self.value = None
217
219 """Represent an option that can be set for a program.
220
221 This holds UNIXish options like --append=yes and -a yes
222 """
224 """Return the value of this option for the commandline.
225 """
226
227 if self.names[0].find("--") >= 0:
228 output = "%s" % self.names[0]
229 if self.value is not None:
230 output += "=%s " % self.value
231 else:
232 output += " "
233
234 elif self.names[0].find("-") >= 0:
235 output = "%s " % self.names[0]
236 if self.value is not None:
237 output += "%s " % self.value
238 else:
239 raise ValueError("Unrecognized option type: %s" % self.names[0])
240
241 return output
242
244 """Represent an argument on a commandline.
245 """
247 if self.value is not None:
248 return "%s " % self.value
249 else:
250 return " "
251