Python's standard library has modules for configuration file parsing (configparser), environment variable reading (os.environ), and command-line argument parsing (argparse). I want to write a program that does all those, and also:
Has a cascade of option values:
- default option values, overridden by
- config file options, overridden by
- environment variables, overridden by
- command-line options.
Allows one or more configuration file locations specified on the command line with e.g.
--config-file foo.conf
, and reads that (either instead of, or additional to, the usual configuration file). This must still obey the above cascade.Allows option definitions in a single place to determine the parsing behaviour for configuration files and the command line.
Unifies the parsed options into a single collection of option values for the rest of the program to access without caring where they came from.
Everything I need is apparently in the Python standard library, but they don't work together smoothly.
How can I achieve this with minimum deviation from the Python standard library?
The Python standard library does not provide this, as far as I know. I solved this for myself by writing code to use
optparse
andConfigParser
to parse the command line and config files, and provide an abstraction layer on top of them. However, you would need this as a separate dependency, which from your earlier comment seems to be unpalatable.If you want to look at the code I wrote, it's at http://liw.fi/cliapp/. It's integrated into my "command line application framework" library, since that's a large part of what the framework needs to do.
I was tried something like this recently, using "optparse".
I set it up as a sub-class of OptonParser, with a '--Store' and a '--Check' command.
The code below should pretty much have you covered. You just need to define your own 'load' and 'store' methods which accept/return dictionaries and you're prey much set.
While I haven't tried it by my own, there is ConfigArgParse library which states that it does most of things that you want:
UPDATE: I finally got around to putting this on pypi. Install latest version via:
Full help and instructions are here.
Original post
Here's a little something that I hacked together. Feel free suggest improvements/bug-reports in the comments:
TODO
This implementation is still incomplete. Here's a partial TODO list:
argparse
handles error messagesConform to documented behavior
dest
fromargs
inadd_argument
, instead of relying on theAction
objectparse_args
function which usesparse_known_args
. (e.g. copyparse_args
from thecpython
implementation to guarantee it callsparse_known_args
.)Less Easy Stuff…
I haven't tried any of this yet. It's unlikely—but still possible!—that it could just work…
section
in the config file.)section
in the config file.)Here's a module I hacked together that reads command-line arguments, environment settings, ini files, and keyring values as well. It's also available in a gist.
There's library that does exactly this called configglue.
It also supports environment variables.
There's also another library called ConfigArgParse which is
You might be interested in PyCon talk about configuration by Łukasz Langa - Let Them Configure!