1
2
3
4
5
6
7 """General mechanisms to access applications in Biopython.
8
9 This module is not intended for direct use (any more). It provides
10 the basic objects for our command line wrappers such as:
11
12 - Bio.Align.Applications
13 - Bio.Blast.Applications
14 - Bio.Emboss.Applications
15 - Bio.Sequencing.Applications
16
17 """
18 import os, sys
19 import StringIO
20 import subprocess
21
22 from Bio import File
23
25 """Run an application with the given commandline (DEPRECATED).
26
27 This expects a pre-built commandline that derives from
28 AbstractCommandline, and returns a ApplicationResult object
29 to get results from a program, along with handles of the
30 standard output and standard error.
31
32 WARNING - This will read in the full program output into memory!
33 This may be in issue when the program writes a large amount of
34 data to standard output.
35
36 NOTE - This function is considered to be obsolete, and we intend to
37 deprecate it and then remove it in future releases of Biopython.
38 We now recommend you invoke subprocess directly, using str(commandline)
39 to turn an AbstractCommandline wrapper into a command line string. This
40 will give you full control of the tool's input and output as well.
41 """
42 import warnings
43 warnings.warn("Bio.Application.generic_run and the associated "
44 "Bio.Application.ApplicationResult are deprecated. "
45 "Please use the built in Python module subprocess "
46 "instead, as described in the Biopython Tutorial.",
47 DeprecationWarning)
48
49
50
51
52 child = subprocess.Popen(str(commandline),
53 stdin=subprocess.PIPE,
54 stdout=subprocess.PIPE,
55 stderr=subprocess.PIPE,
56 shell=(sys.platform!="win32"))
57
58 r_out, e_out = child.communicate()
59
60 error_code = child.returncode
61 return ApplicationResult(commandline, error_code), \
62 File.UndoHandle(StringIO.StringIO(r_out)), \
63 File.UndoHandle(StringIO.StringIO(e_out))
64
66 """Make results of a program available through a standard interface (DEPRECATED).
67
68 This tries to pick up output information available from the program
69 and make it available programmatically.
70
71 NOTE - This obsolete is considered to be obsolete, and we intend to
72 deprecate it and then remove it in future releases of Biopython.
73 """
74 - def __init__(self, application_cl, return_code):
75 """Intialize with the commandline from the program.
76 """
77 import warnings
78 warnings.warn("Bio.Application.ApplicationResult and the "
79 "associated function Bio.Application.generic_run "
80 "are deprecated. Please use the built in Python "
81 "module subprocess instead, as described in the "
82 "Biopython Tutorial", DeprecationWarning)
83 self._cl = application_cl
84
85
86 self.return_code = return_code
87
88
89
90 self._results = {}
91
92 for parameter in self._cl.parameters:
93 if "file" in parameter.param_types and \
94 "output" in parameter.param_types:
95 if parameter.is_set:
96 self._results[parameter.names[-1]] = parameter.value
97
99 """Retrieve result information for the given output.
100
101 Supports any of the defined parameters aliases (assuming the
102 parameter is defined as an output).
103 """
104 try:
105 return self._results[output_name]
106 except KeyError, err:
107
108 for parameter in self._cl.parameters:
109 if output_name in parameter.names:
110 return self._results[parameter.names[-1]]
111
112 raise err
113
115 """Retrieve a list of all available results.
116 """
117 result_names = self._results.keys()
118 result_names.sort()
119 return result_names
120
122 """Generic interface for constructing command line strings.
123
124 This class shouldn't be called directly; it should be subclassed to
125 provide an implementation for a specific application.
126
127 For a usage example we'll show one of the EMBOSS wrappers. You can set
128 options when creating the wrapper object using keyword arguments - or later
129 using their corresponding properties:
130
131 >>> from Bio.Emboss.Applications import WaterCommandline
132 >>> cline = WaterCommandline(gapopen=10, gapextend=0.5)
133 >>> cline
134 WaterCommandline(cmd='water', gapopen=10, gapextend=0.5)
135
136 You can instead manipulate the parameters via their properties, e.g.
137
138 >>> cline.gapopen
139 10
140 >>> cline.gapopen = 20
141 >>> cline
142 WaterCommandline(cmd='water', gapopen=20, gapextend=0.5)
143
144 You can clear a parameter you have already added by 'deleting' the
145 corresponding property:
146
147 >>> del cline.gapopen
148 >>> cline.gapopen
149 >>> cline
150 WaterCommandline(cmd='water', gapextend=0.5)
151
152 Once you have set the parameters you need, turn the object into a string:
153
154 >>> str(cline)
155 Traceback (most recent call last):
156 ...
157 ValueError: You must either set outfile (output filename), or enable filter or stdout (output to stdout).
158
159 In this case the wrapper knows certain arguments are required to construct
160 a valid command line for the tool. For a complete example,
161
162 >>> from Bio.Emboss.Applications import WaterCommandline
163 >>> cline = WaterCommandline(gapopen=10, gapextend=0.5)
164 >>> cline.asequence = "asis:ACCCGGGCGCGGT"
165 >>> cline.bsequence = "asis:ACCCGAGCGCGGT"
166 >>> cline.outfile = "temp_water.txt"
167 >>> print cline
168 water -outfile=temp_water.txt -asequence=asis:ACCCGGGCGCGGT -bsequence=asis:ACCCGAGCGCGGT -gapopen=10 -gapextend=0.5
169 >>> cline
170 WaterCommandline(cmd='water', outfile='temp_water.txt', asequence='asis:ACCCGGGCGCGGT', bsequence='asis:ACCCGAGCGCGGT', gapopen=10, gapextend=0.5)
171
172 You would typically run the command line via a standard Python operating
173 system call (e.g. using the subprocess module).
174 """
176 """Create a new instance of a command line wrapper object."""
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 self.program_name = cmd
194 try:
195 parameters = self.parameters
196 except AttributeError:
197 raise AttributeError("Subclass should have defined self.parameters")
198
199 aliases = set()
200 for p in parameters:
201 for name in p.names:
202 if name in aliases:
203 raise ValueError("Parameter alias %s multiply defined" \
204 % name)
205 aliases.add(name)
206 name = p.names[-1]
207
208 def getter(name):
209 return lambda x : x._get_parameter(name)
210 def setter(name):
211 return lambda x, value : x.set_parameter(name, value)
212 def deleter(name):
213 return lambda x : x._clear_parameter(name)
214 doc = p.description
215 if isinstance(p, _Switch):
216 doc += "\n\nThis property controls the addition of the %s " \
217 "switch, treat this property as a boolean." % p.names[0]
218 else:
219 doc += "\n\nThis controls the addition of the %s parameter " \
220 "and its associated value. Set this property to the " \
221 "argument value required." % p.names[0]
222 prop = property(getter(name), setter(name), deleter(name), doc)
223 setattr(self.__class__, name, prop)
224 for key, value in kwargs.iteritems():
225 self.set_parameter(key, value)
226
228 """Make sure the required parameters have been set (PRIVATE).
229
230 No return value - it either works or raises a ValueError.
231
232 This is a separate method (called from __str__) so that subclasses may
233 override it.
234 """
235 for p in self.parameters:
236
237 if p.is_required and not(p.is_set):
238 raise ValueError("Parameter %s is not set." \
239 % p.names[-1])
240
241
243 """Make the commandline string with the currently set options.
244
245 e.g.
246 >>> from Bio.Emboss.Applications import WaterCommandline
247 >>> cline = WaterCommandline(gapopen=10, gapextend=0.5)
248 >>> cline.asequence = "asis:ACCCGGGCGCGGT"
249 >>> cline.bsequence = "asis:ACCCGAGCGCGGT"
250 >>> cline.outfile = "temp_water.txt"
251 >>> print cline
252 water -outfile=temp_water.txt -asequence=asis:ACCCGGGCGCGGT -bsequence=asis:ACCCGAGCGCGGT -gapopen=10 -gapextend=0.5
253 >>> str(cline)
254 'water -outfile=temp_water.txt -asequence=asis:ACCCGGGCGCGGT -bsequence=asis:ACCCGAGCGCGGT -gapopen=10 -gapextend=0.5'
255 """
256 self._validate()
257 commandline = "%s " % self.program_name
258 for parameter in self.parameters:
259 if parameter.is_set:
260
261 commandline += str(parameter)
262 return commandline.strip()
263
265 """Return a representation of the command line object for debugging.
266
267 e.g.
268 >>> from Bio.Emboss.Applications import WaterCommandline
269 >>> cline = WaterCommandline(gapopen=10, gapextend=0.5)
270 >>> cline.asequence = "asis:ACCCGGGCGCGGT"
271 >>> cline.bsequence = "asis:ACCCGAGCGCGGT"
272 >>> cline.outfile = "temp_water.txt"
273 >>> print cline
274 water -outfile=temp_water.txt -asequence=asis:ACCCGGGCGCGGT -bsequence=asis:ACCCGAGCGCGGT -gapopen=10 -gapextend=0.5
275 >>> cline
276 WaterCommandline(cmd='water', outfile='temp_water.txt', asequence='asis:ACCCGGGCGCGGT', bsequence='asis:ACCCGAGCGCGGT', gapopen=10, gapextend=0.5)
277 """
278 answer = "%s(cmd=%s" % (self.__class__.__name__, repr(self.program_name))
279 for parameter in self.parameters:
280 if parameter.is_set:
281 if isinstance(parameter, _Switch):
282 answer += ", %s=True" % parameter.names[-1]
283 else:
284 answer += ", %s=%s" \
285 % (parameter.names[-1], repr(parameter.value))
286 answer += ")"
287 return answer
288
298
309
332
334 """Check whether the given value is valid.
335
336 No return value - it either works or raises a ValueError.
337
338 This uses the passed function 'check_function', which can either
339 return a [0, 1] (bad, good) value or raise an error. Either way
340 this function will raise an error if the value is not valid, or
341 finish silently otherwise.
342 """
343 if check_function is not None:
344 is_good = check_function(value)
345 assert is_good in [0,1,True,False]
346 if not is_good:
347 raise ValueError("Invalid parameter value %r for parameter %s" \
348 % (value, name))
349
351 """Set attribute name to value (PRIVATE).
352
353 This code implements a workaround for a user interface issue.
354 Without this __setattr__ attribute-based assignment of parameters
355 will silently accept invalid parameters, leading to known instances
356 of the user assuming that parameters for the application are set,
357 when they are not.
358
359 >>> from Bio.Emboss.Applications import WaterCommandline
360 >>> cline = WaterCommandline(gapopen=10, gapextend=0.5, stdout=True)
361 >>> cline.asequence = "a.fasta"
362 >>> cline.bsequence = "b.fasta"
363 >>> cline.csequence = "c.fasta"
364 Traceback (most recent call last):
365 ...
366 ValueError: Option name csequence was not found.
367 >>> print cline
368 water -stdout -asequence=a.fasta -bsequence=b.fasta -gapopen=10 -gapextend=0.5
369
370 This workaround uses a whitelist of object attributes, and sets the
371 object attribute list as normal, for these. Other attributes are
372 assumed to be parameters, and passed to the self.set_parameter method
373 for validation and assignment.
374 """
375 if name in ['parameters', 'program_name']:
376 self.__dict__[name] = value
377 else:
378 self.set_parameter(name, value)
379
380
382 """A class to hold information about a parameter for a commandline.
383
384 Do not use this directly, instead use one of the subclasses.
385 """
387 raise NotImplementedError
388
390 raise NotImplementedError
391
393 """Represent an option that can be set for a program.
394
395 This holds UNIXish options like --append=yes and -a yes,
396 where a value (here "yes") is generally expected.
397
398 For UNIXish options like -kimura in clustalw which don't
399 take a value, use the _Switch object instead.
400
401 Attributes:
402
403 o names -- a list of string names by which the parameter can be
404 referenced (ie. ["-a", "--append", "append"]). The first name in
405 the list is considered to be the one that goes on the commandline,
406 for those parameters that print the option. The last name in the list
407 is assumed to be a "human readable" name describing the option in one
408 word.
409
410 o param_types -- a list of string describing the type of parameter,
411 which can help let programs know how to use it. Example descriptions
412 include 'input', 'output', 'file'. Note that if 'file' is included,
413 these argument values will automatically be escaped if the filename
414 contains spaces.
415
416 o checker_function -- a reference to a function that will determine
417 if a given value is valid for this parameter. This function can either
418 raise an error when given a bad value, or return a [0, 1] decision on
419 whether the value is correct.
420
421 o equate -- should an equals sign be inserted if a value is used?
422
423 o description -- a description of the option.
424
425 o is_required -- a flag to indicate if the parameter must be set for
426 the program to be run.
427
428 o is_set -- if the parameter has been set
429
430 o value -- the value of a parameter
431 """
432 - def __init__(self, names = [], types = [], checker_function = None,
433 is_required = False, description = "", equate=True):
434 self.names = names
435 self.param_types = types
436 self.checker_function = checker_function
437 self.description = description
438 self.equate = equate
439 self.is_required = is_required
440
441 self.is_set = False
442 self.value = None
443
445 """Return the value of this option for the commandline.
446
447 Includes a trailing space.
448 """
449
450
451
452
453 if self.value is None:
454 return "%s " % self.names[0]
455 if "file" in self.param_types:
456 v = _escape_filename(self.value)
457 else:
458 v = str(self.value)
459 if self.equate:
460 return "%s=%s " % (self.names[0], v)
461 else:
462 return "%s %s " % (self.names[0], v)
463
465 """Represent an optional argument switch for a program.
466
467 This holds UNIXish options like -kimura in clustalw which don't
468 take a value, they are either included in the command string
469 or omitted.
470
471 o names -- a list of string names by which the parameter can be
472 referenced (ie. ["-a", "--append", "append"]). The first name in
473 the list is considered to be the one that goes on the commandline,
474 for those parameters that print the option. The last name in the list
475 is assumed to be a "human readable" name describing the option in one
476 word.
477
478 o param_types -- a list of string describing the type of parameter,
479 which can help let programs know how to use it. Example descriptions
480 include 'input', 'output', 'file'. Note that if 'file' is included,
481 these argument values will automatically be escaped if the filename
482 contains spaces.
483
484 o description -- a description of the option.
485
486 o is_set -- if the parameter has been set
487
488 NOTE - There is no value attribute, see is_set instead,
489 """
490 - def __init__(self, names = [], types = [], description = ""):
496
498 """Return the value of this option for the commandline.
499
500 Includes a trailing space.
501 """
502 assert not hasattr(self, "value")
503 if self.is_set:
504 return "%s " % self.names[0]
505 else:
506 return ""
507
509 """Represent an argument on a commandline.
510 """
511 - def __init__(self, names = [], types = [], checker_function = None,
512 is_required = False, description = ""):
513 self.names = names
514 self.param_types = types
515 self.checker_function = checker_function
516 self.description = description
517 self.is_required = is_required
518 self.is_set = False
519 self.value = None
520
522 if self.value is None:
523 return " "
524 else:
525 return "%s " % self.value
526
528 """Escape filenames with spaces by adding quotes (PRIVATE).
529
530 Note this will not add quotes if they are already included:
531
532 >>> print _escape_filename('example with spaces')
533 "example with spaces"
534 >>> print _escape_filename('"example with spaces"')
535 "example with spaces"
536 """
537
538
539
540
541
542
543
544
545
546
547
548
549
550 if " " not in filename:
551 return filename
552
553 if filename.startswith('"') and filename.endswith('"'):
554
555 return filename
556 else:
557 return '"%s"' % filename
558
560 """Run the Bio.Application module's doctests."""
561 import doctest
562 doctest.testmod(verbose=1)
563
564 if __name__ == "__main__":
565
566 _test()
567