Optik: Basic Usage ================== While Optik is quite flexible and powerful, you don't have to jump through hoops or read reams of documentation to get it working in basic cases. This document aims to demonstrate some simple usage patterns that will get you started using Optik in your scripts. To parse a command line with Optik, you must create an OptionParser instance and populate it. Obviously, you'll have to import the OptionParser classes in any script that uses Optik:: from optik import OptionParser Early on in the main program, create a parser:: parser = OptionParser() Then you can start populating the parser with options. Each option is really a set of synonmous option strings; most commonly, you'll have one short option string and one long option string -- e.g. "-f" and "--file":: parser.add_option("-f", "--file", ...) The interesting stuff, of course, is what comes after the option strings. In this document, we'll only cover four of the things you can put there: 'action', 'type', 'dest' (destination), and 'help'. The "store" action ------------------ The action tells Optik what to do when it sees one of the option strings for this option on the command-line. For example, the action "store" means: take the next argument (or the remainder of the current argument), ensure that it is of the correct type, and store it to your chosen destination. For example, let's fill in the "..." of that last option:: parser.add_option("-f", "--file", action="store", type="string", dest="filename") Now let's make up a fake command-line and ask Optik to parse it:: args = ["-f", "foo.txt"] (options, args) = parser.parse_args(args) (Note that if you don't pass an argument list to parse_args(), it automatically uses sys.argv[1:].) When Optik sees the "-f", it sucks in the next argument -- "foo.txt" -- and stores it in the 'filename' attribute of a special object. That object is the first return value from parse_args(), so :: print options.filename will print "foo.txt". The other option types supported by Optik are "int" and "float". Here's an option that expects an integer argument:: parser.add_option("-n", type="int", dest="num") Note that I didn't supply a long option, which is perfectly acceptable. I also didn't specify the action -- it defaults to "store". Let's parse another fake command-line. This time, we'll jam the option argument right up against the option -- "-n42" (one argument) is equivalent to "-n 42" (two arguments). :: (options, args) = parser.parse_args(["-n42"]) print options.num will print "42". Trying out the "float" type is left as an exercise for the reader. If you don't specify a type, Optik assumes "string". Combined with the fact that the default action is "store", that means our first example can be a lot shorter:: parser.add_option("-f", "--file", dest="filename") If you don't supply a destination, Optik figures out a sensible default from the option strings: if the first long option string is "--foo-bar", then the default destination is 'foo_bar'. If there are no long option strings, Optik looks at the first short option: the default destination for "-f" is 'f'. Adding types is fairly easy; see extending.txt for information on extending Optik. Other "store_*" actions ----------------------- Flag options -- set a variable to true or false when a particular option is seen -- are quite common. Optik supports them with two separate actions, "store_true" and "store_false". For example, you might have a "verbose" flag that is turned on with "-v" and off with "-q":: parser.add_option("-v", action="store_true", dest="verbose") parser.add_option("-q", action="store_false", dest="verbose") Here we have two different options with the same destination, which is perfectly OK. (It just means you have to be a bit careful when setting default values -- see below.) When Optik sees "-v" on the command line, it sets the 'verbose' attribute of the special "option values" object to 1; when it sees "-q", it sets 'verbose' to 0. Setting default values ---------------------- All of the above examples involve setting some variable (the "destination") when certain command-line options are seen. What happens if those options are never seen? Since we didn't supply any defaults, they are all set to None. Sometimes, this is just fine (which is why it's the default), but sometimes, you want more control. To address that need, Optik lets you supply a default value for each destination, which is assigned before the command-line is parsed. First, consider the verbose/quiet example. If we want Optik to set 'verbose' to 1 unless -q is seen, then we can do this:: parser.add_option("-v", action="store_true", dest="verbose", default=1) parser.add_option("-q", action="store_false", dest="verbose") Oddly enough, this is exactly equivalent:: parser.add_option("-v", action="store_true", dest="verbose") parser.add_option("-q", action="store_false", dest="verbose", default=1) Those are equivalent because you're supplying a default value for the option's *destination*, and these two options happen to have the same destination (the 'verbose' variable). Consider this:: parser.add_option("-v", action="store_true", dest="verbose", default=0) parser.add_option("-q", action="store_false", dest="verbose", default=1) Again, the default value for 'verbose' will be 1: the last default value supplied for any particular destination attribute is the one that counts. Generating help --------------- The last feature that you will use in every script is Optik's ability to generate help messages. All you have to do is supply a 'help' value when you add an option. Let's create a new parser and populate it with user-friendly (documented) options:: usage = "usage: %prog [options] arg1 arg2" parser = OptionParser(usage=usage) parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=1, help="make lots of noise [default]") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", help="be vewwy quiet (I'm hunting wabbits)") parser.add_option("-f", "--file", dest="filename", metavar="FILE", help="write output to FILE"), parser.add_option("-m", "--mode", default="intermediate", help="interaction mode: one of 'novice', " "'intermediate' [default], 'expert'") If Optik encounters either "-h" or "--help" on the command-line, or if you just call "parser.print_help()", it prints the following to stdout:: usage: [options] arg1 arg2 options: -h, --help show this help message and exit -v, --verbose make lots of noise [default] -q, --quiet be vewwy quiet (I'm hunting wabbits) -fFILE, --file=FILE write output to FILE -mMODE, --mode=MODE interaction mode: one of 'novice', 'intermediate' [default], 'expert' There's a lot going on here to help Optik generate the best possible help message: * the script defines its own usage message:: usage = "usage: %prog [options] arg1 arg2" Optik expands "%prog" in the usage string to the name of the current script, ie. os.path.basename(sys.argv[0]). The expanded string is then printed before the detailed option help. If you don't supply a usage string, Optik uses a bland but sensible default: "usage: %prog [options]", which is fine if your script doesn't take any positional arguments. * every option defines a help string, and doesn't worry about line- wrapping -- Optik takes care of wrapping lines and making the help output look good. * options that take a value indicate this fact in their automatically-generated help message, e.g. for the "mode" option:: -mMODE, --mode=MODE Here, "MODE" is called the meta-variable: it stands for the argument that the user is expected to supply to -m/--mode. By default, Optik converts the destination variable name to uppercase and uses that for the meta-variable. Sometimes, that's not what you want -- for example, the "filename" option explicitly sets metavar="FILE", resulting in this automatically-generated option description:: -fFILE, --file=FILE This is important for more than just saving space, though: the manually written help text uses the meta-variable "FILE", to clue the user in that there's a connection between the formal syntax "-fFILE" and the informal semantic description "write output to FILE". This is a simple but effective way to make your help text a lot clearer and more useful for end users. Print a version number ---------------------- Similar to the brief usage string, Optik can also print a version string for your program. You have to supply the string, as the 'version' argument to OptionParser:: parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0") Note that "%prog" is expanded just like it is in 'usage'. Apart from that, 'version' can contain anything you like. When you supply it, Optik automatically adds a "--version" option to your parser. If it encounters this option on the command line, it expands your 'version' string (by replacing "%prog"), prints it to stdout, and exits. For example, if your script is called /usr/bin/foo, a user might do:: $ /usr/bin/foo --version foo 1.0 Error-handling -------------- The one thing you need to know for basic usage is how Optik behaves when it encounters an error on the command-line -- e.g. "-n4x" where "-n" is an integer-valued option. Optik prints your usage message to stderr, followed by a useful and human-readable error message. Then it terminates (calls sys.exit()) with a non-zero exit status. If you don't like this, subclass OptionParser and override the error() method. See extending.txt. Putting it all together ----------------------- Here's what my Optik-based scripts usually look like:: from optik import OptionParser [...] def main (): usage = "usage: %prog [options] arg" parser = OptionParser(usage) parser.add_option("-f", "--file", type="string", dest="filename", help="read data from FILENAME") parser.add_option("-v", "--verbose", action="store_true", dest="verbose") parser.add_option("-q", "--quiet", action="store_false", dest="verbose") [... more options ...] (options, args) = parser.parse_args() if len(args) != 1: parser.error("incorrect number of arguments") if options.verbose: print "reading %s..." % options.filename [... go to work ...] if __name__ == "__main__": main()