Configuration Files¶
When configuration file support is enabled (by specifying config_option
in docoptcfg), Python’s native
configparser module is used to read configuration files. That means only INI/INF-type config files are supported.
An example configuration file is:
[my_script]
log-file = file_config.log
runtime = 10
threads = 11
Below are a few things to keep in mind.
The Basics¶
Let’s get some basics out of the way. When calling docoptcfg()
with the config_option
argument, the value of
that argument should be one of the options defined in your docstring. For example if we’ve got this docstring:
My little script.
Usage:
my_script [options]
Options:
-c FILE --config=FILE Path to INI config file.
-l FILE --log-file=FILE Write to this log file.
-r NUM --runtime=NUM How long before exiting.
-t NUM --threads=NUM Number of threads.
Then config_option
should be set to one of those, such as config_option='--config'
. You’ll need the hyphens.
Another thing to point out is that docoptcfg ignores re-defining configuration files within configuration files. So if your end user has this:
[my_script]
config = new_config.ini
runtime = 10
Then docoptcfg will just ignore the config setting. It will read the rest of the config file like normal.
Lastly, you can combine configuration files and environment variables. So your users can define a configuration file
with PREFIX_CONFIG=/path/to/config.ini
instead of through the command line.
Exception Handling¶
Unlike environment variables which don’t throw any exceptions, configuration file handling may raise two exceptions:
docoptcfg.DocoptcfgError
docoptcfg.DocoptcfgFileError
DocoptcfgError¶
This one’s easy. It’s only raised under one scenario: when you (the developer) specifies the wrong option for
config_option
when calling docoptcfg(). With the above example docstring, if you do
docoptcfg(__doc__, config_option='--i-dont-exist')
then DocoptcfgError
will be raised.
DocoptcfgFileError¶
This one may be raised by a mistake on your end-users’ part. Be sure to handle this. This is raised on any error that may come up while attempting to read and parse a config file. Situations include:
- File not found
- Permissions
- Corrupt/binary data instead of text data
- Malformed section formatting
- Missing section
- Non-boolean value for boolean options (valid values are listed in the configparser documentation)
A simple way to handle this is:
try:
CONFIG = docoptcfg(__doc__, config_option='--config')
except DocoptcfgFileError as exc:
log.error('Failed reading: %s', str(exc))
CONFIG = docoptcfg(__doc__)
Section Name¶
docoptcfg will only focus on one section in the config file. The name of that section must match the name of your program specified in your docstring. The example above has the section named “my_script”. Therefore in your docstring the first word after “Usage:” should match.
Short Names¶
Like environment variables, only long option names are used. In the example above we’ve got -l FILE --log-file=FILE
but docoptcfg will only look for log-file
.
Flags/Booleans¶
Flags in config files must be yes, no, on, off, true, false, 1, or 0. More info in the configparser documentation.
Repeating Options¶
Docopt supports repeating options by specifying an ellipses in the docstring. An example:
Test handling of ... options.
Usage:
my_script [--config=FILE] [--flag]... [--key=VAL]...
Options:
--config=FILE Path INI config file.
--flag Boolean value.
--key=VAL Key value value.
In this case, docopt gives you integers for flags (instead of booleans) and lists for key/value options (instead of strings).
docoptcfg supports this in configuration files as well:
- Configuration file options for flags are expected to be integers.
- Configuration file options for key/values can be delimited by newlines.
Here’s a quick example:
[my_script]
key =
a
b
c
flag = 2
The above is the equivalent of my_script --key=a --key=b --key=c --flag --flag
.