A look at possible approaches to introducing configurability to your Python application, and a quick analysis of the most common problems.
Today's JSON will be tomorrow's XML. Convention over configuration or configuration over hard-coded defaults? Should the user be given the freedom to decide or should the programmer free users from confusion over too many options?
This talk presents answers to both sides of the argument. In the first part, I discuss different options for handling configuration in Python applications. Each will receive its share of benefits and problems, and some quick examples of how to use them in real code. In the second part, I describe things you can do right now to increase configurability of your existing applications.
The final part will briefly introduce the new configparser module from Python 3.2.
Some words on the desirable characteristics of configuration, e.g.:
composable (levels: program defaults -> OS defaults -> user defaults -> environment specifics -> runtime overrides)
readable (by people: to easily distinguish an enabled option from a disabled one; by programs: cheap to parse)
easy to modify, store and exchange (including: the ability for a program to write changes back to the configuration registry)
discoverable, e.g. self-documenting
An overview of typical format,from easy-ish (INI, Apache, JSON) through complex (XML, YAML) and Turing complete (Python or other programming languages) to awkward (DSLs like Puppet, SQLite, Windows registry). Each format will be judged according to the features introduced in Section 1. Plus: unless there's no other way, don't invent your own format:
configuration once written has to be supported forever
parser quirks
unintuitive design decisions
learning curve
favor convention over configuration (simple is better than complex, there should be one obvious way to do it)
changes in design decisions: opportunity for configurability
the more configurability, the harder the tool is to use and to test
do you want an end-user tool or a framework?
favor storing data in databases and not configuration files
Django settings.py
: too much power in the hands of users -> no default
way of solving environment-specific configuration (staging, production,
etc.). Solutions: django-configurations
, ordered incremental execution of files, package based composition, INI based composition.
Mercurial, Git, paster: INI files all the way down. How to mix file-based configuration with command-line overrides.
Mandatory reminder: avoid global state.
configparser
in Python 3.2.full mapping protocol support, including deep copying to and from other dictionaries
pluggable interpolation
more sensible defaults in the base INI format
there's a maintained backport: pip install configparser