Tuesday, October 6, 2009

Python over-riding options with ConfigParser and OptionParser

It looks like it may be woth looking into argparse (non-standard library)

"""
The basic idea is that config information can be pulled out of

* Global config file
* User local config file
* environment variables
* command line

Higher priority comes later in the list. 
"""

But here's an implementation of cascading config file/command line options with ConfigParser and OptionParser - without subclassing.

Basically you just...

  • Set global defaults in at the top of the module in the constants section
  • Use those to set defaults in the config object
  • Read in the config file possibly over-riding defaults
  • Read out the values in the config object to a dictionary
  • Use THOSE values to set the command line defaults

Then you can get any option you need out of the command line options argument

It's not very flexible, but it uses standard libraries and should be fairly  obvious.


#! /usr/bin/env python
__doc__ = """
example of cascading options with ConfigParser and OptionParser
"""

# imports
import sys
from ConfigParser import ConfigParser
from optparse import OptionParser
# constants
default_option = 'default_value'
default_toggle = True

# classes
# internal functions

def main():
    # create a config parser
    # config parser objects store all options as strings
    config = ConfigParser({'option':str(default_option),
                           'toggle':str(default_toggle),
                          })
    config.read('example.cfg')
    
    # create command line option parser
    parser = OptionParser("%prog [options]" + __doc__.rstrip())
    
    # configure command line options
    parser.add_option("-o", "--option", action="store", dest="option", help="set option")
    parser.add_option("-t", "--toggleOff", action="store_false", dest="toggle", help="set toggle off")
    parser.add_option("-T", "--toggleOn", action="store_true", dest="toggle", help="set toggle on")
    
    # read config objects defaults section into a dictionary
    config_options = config.defaults()
    # config_options is dictionary of strings, over-ride toggle to bool
    config_options['toggle'] = config.getboolean('DEFAULT', 'toggle')
    # feed dictionary of defaults into parser object
    parser.set_defaults(**config_options)

    # parse command line options
    (options, args) = parser.parse_args()

    print "option: %s" % options.option
    if options.toggle:
        print "toggle is ON"
    else:
        print "toggle is OFF"

    return 0;

if __name__ == '__main__':
    status = main()
    sys.exit(status)

2 comments:

機車 said...

Circumstances are the rulers of the weak, instrument of the wise..........................

Gene Wood said...

Excellent example. Here's a modification I made to make it more general. Instead of hard coding the variable "toggle" in as a boolean variable that needs to be processed, just process all boolean values programatically

Here's the diff

and here's the resulting updated code