|
From: Pettit, K. (SAIC) <Kei...@bp...> - 2007-12-04 18:20:21
|
I had a need for a application I was doing to have multiple levels of
configuration. On top of that I also needed to take into account
commandline options from the optparse module. Also needed to make
certain options immutable. So this is my hack which works pretty well
for me. Anyways I thought my solition to that problem might help this
group.
The order I look at the config files, and my particular need.
1) SiteConfig - Global defaults, this is my Spec file. In the Spec I
specify any global options defaults I need
2) UserConfig - The first config I look at
3) ProjectConfig - Config's for a specific project
Additional Features I needed:
* Immutable: I made a immutable option that users can put in any of the
config files, so the next config that is looked at will not overwrite
it's option. In the config if there is a immutable value it will look
at the results and make those immutable. For example if your config had
something like:
Org =3D "Power Plant"
First =3D "Homer"
Last =3D "Simpson"
Immutable =3D "Org" #This can be a list of options to make immutable
* OptParse - I like optparse for commandline options and needed to merge
options form optparse and configobj, I also needed to let the user play
a trump card so the commandline could overwrite any previous options,
even if it was set as immutable. Weird but we needed it.
If this is usefull to anybody let me know and I can create a example
script with config's, or maybe I could spend the time and figure out how
to put this into configobj. That might be beyond me though.
Keith
###################################
# Config functions
###################################
"config" is the dictionary I create to hold the configobj configs and
optparse options. =20
# UserConfig
def config_usermerge(userconfigfile, config):
userconfig =3D ConfigObj(userconfigfile, interpolation=3D"Template")
val =3D Validator()
config.validate(val, copy=3DTrue)
for key, value in config.iteritems():
# If marked as Immutable do not update value
if key not in config['immutable']:
config[key] =3D value #Update config with new value
val =3D Validator()
config.validate(val, copy=3DTrue)
return config
#Overwrite "config" with project config
def config_projmerge(projconfigfile, config):
projconfig =3D ConfigObj(projconfigfile, interpolation=3D"Template")
val =3D Validator()
config.validate(val, copy=3DTrue)
for key, value in config.iteritems():
# If marked as Immutable do not update item
if key not in config['immutable']:
config[key] =3D value #Update config with new value
val =3D Validator()
config.validate(val, copy=3DTrue)
return config
# Merge CLI options with config
def config_climerge(options, config):
cliconfig =3D vars(options) # CLI options
if options.overwrite: # If the overwrite flag is set CLI variables
have preferance
for key, value in cliconfig.iteritems():
if value: # Only add/overwrite config if option has a value
config[key] =3D value # Update config with new value
else: # Update config options unless immutable
for key, value in cliconfig.iteritems():
if key not in config['immutable'] and value: #if not immutable and
there is a value present
config[key] =3D value #Update config with new value
val =3D Validator()
config.validate(val, copy=3DTrue)
return config
###################################
# Importing configs
###################################
if os.path.exists(userconfigfile): # Import User config
config =3D config_usermerge(userconfigfile, config)
#Overwrite "config" with project config
if os.path.exists(projconfigfile): # Import project Config
config =3D config_projmerge(projconfigfile, config)
config =3D config_climerge(options, config) # Import CLI option
|