Package cliutils
[hide private]
[frames] | no frames]

Package cliutils

source code

A collection of utilities easing the creation of command line scripts.

cliutils is pure Python with no dependencies.

At the moment, the module provides three disparate features: Process objects, a command-line argument parsing decorator, a logging decoratory factory, and a decorator factory that runs functions after changing to a given directory.

Process objects

Although it isn't very difficult to execute shell commands from a Python script, there are several lines of overhead in the standard pattern. Process objects reduce the entire pattern to a single line. In addition, they are more flexible; they may be piped into each other, just as regular processes may be on the bash command line.

>>> Process("echo 'spam and eggs'")
spam and eggs
>>> s = Process("echo 'spam and eggs'").stdout
>>> s
'spam and eggs'
>>> p = Process("echo 'spam and eggs'") | Process("wc -w")
>>> p.stdout
'3'

For convenience, a singleton object (sh) is provided that is able to create process objects from given attributes.

>>> sh.echo("spam and eggs") | sh.wc("-w") | sh.cat()
3

Arguments passed to Process objects are split using the shlex module, so most simple strings will work just fine. More complex arguments should be passed in as lists:

>>> sh.echo(["spam", "and", "eggs"])
spam and eggs

The cliargs decorator

A common pattern for shell scripts is:

   def main():
       parser = make_an_option_parser()
       parser.parse(sys.argv[1:])
       do_some_stuff_with_options()

   if __name__=="__main__":
       main()

Creation of shell scripts using setuptools' entry_points results in a similar pattern; a function is called with no arguments, and must do its own command-line argument parsing. This makes sense in some cases, where complex argument parsing is required. In simple cases, however, where parsing of a few arguments or keywords is required, the cliargs decorator will be of use. It does a simple parse of sys.argv, using a parsing algorithm based on some code in getopt, and calls the decorated function with the results:

   @cliargs
   def myScript(anarg, anotherarg, someval="default")
       "Usage: myscript anarg anotherarg [--someval VALUE]"
       print anarg anotherarg someval

When that function is called as a result of a command line script, such as:

   $ myscript val1 val2 --someflag somevalue 

cliargs will parse sys.argv and pass the results into myScript. If improper arguments are passed such that a TypeError is raised, the docstring of the function will be printed; this makes that an ideal place to include a usage string.

cliargs is of course limited to very simple cases. More complex argument parsing will require the use of the getopt or optparse modules.

log_decorator

log_decorator is an almost trivially simple decorator factory. When called with a file-like object, it returns a decorator that redirects sys.stdout to that file for the duration of the execution of the decorated function.

>>> from StringIO import StringIO
>>> logfile = StringIO()
>>> logger = log_decorator(logfile)
>>> @logger
... def func():
...     print "ABCDEFGHIJK"
... 
>>> func()
>>> logfile.seek(0)
>>> logfile.read().strip()
'ABCDEFGHIJK'

indir

indir is a decorator factory that runs the decorated function in a given directory, changing back to the original directory on completion.


Version: 0.1.1

Submodules [hide private]

Classes [hide private]
  Process
A wrapper for subprocess.Popen that allows bash-like pipe syntax and simplified output retrieval.
Functions [hide private]
 
cliargs(f)
Decorator that parses sys.argv and passes the results into the function.
source code
 
log_decorator(fobj)
Create a logged decorator for re-use.
source code
Variables [hide private]
  sh = _shell()
Function Details [hide private]

cliargs(f)

source code 

Decorator that parses sys.argv and passes the results into the function.

Meant for functions that are a target of setuptools' automatic script creation (by default, nothing is passed in, and the function must handle sys.argv parsing itself). If something very simple is all that is required, this is the answer. Fancier arguments should use getopt or optparse.

If the wrong args/kwargs are passed in such that a TypeError is raised, the docstring is printed, so that's an ideal place to put usage information.

Decorators:
  • @decorator

log_decorator(fobj)

source code 

Create a logged decorator for re-use.

>>> from StringIO import StringIO
>>> logfile = StringIO()
>>> logger = log_decorator(logfile)
>>> @logger
... def func():
...     print "ABCDEFGHIJK"
... 
>>> func()
>>> logfile.seek(0)
>>> logfile.read().strip()
'ABCDEFGHIJK'