Change the future

Saturday 3:15 p.m.–3:45 p.m.

Let Them Configure!

Łukasz Langa

Audience level:
Intermediate
Category:
Best Practices/Patterns

Description

A look at possible approaches to introducing configurability to your Python application, and a quick analysis of the most common problems.

Abstract

Narrative

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.

Outline

1. High level configurability features.

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

2. Configuration format whirlwind tour.

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

3. Balance between one-size-fits-all and tweakable-beyond-comprehension.

  • 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

    • configuration describes behaviour

4. Practical configurability.

  • 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.

5. Why you'll love 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