Python configuration

A configuration file is where you store global variables such as database settings, directory and file paths, API keys, or any settings that need to change for different environments. For me an ideal config format is easy to understand, handles default values, and is included in the Python standard library. With those requirements my options are a Python module, an .ini file, or a JSON file.

Python module config file

Storing static information in an executable Python module sounds odd but it works and is even recommended in the official Python FAQ:

The canonical way to share information across modules within a single program is to create a special module (often called config or cfg). Just import the config module in all modules of your application; the module then becomes available as a global name.

config.py

NAME = 'Stuart'
AGE = 3

app.py

import config
print(f'Name: {config.NAME} Age: {config.AGE}')

It works well enough if config.py is in the same directory as the application importing it, otherwise you have to put it in sys.path. It doesn’t allow you to supply default configuration settings, at least not without a lot of work.

INI config file

The .ini format, used by the configparser module, is straight out of the Windows 95 era. The file is broken into sections of key:value pairs of strings—no other data types are allowed. If you’d rather not use sections you can trick configparser into ignoring them, but I’d prefer a file format that isn’t convoluted and archaic.

config.ini

[DEFAULT]
NAME: Stuart
AGE: 3

app.py

import configparser
config = configparser.ConfigParser()
config.read('config.ini')
print(f'Name: {config.get("DEFAULT", "NAME")} Age: {config.getint("DEFAULT", "AGE")}')

JSON config file

JavaScript Object Notation (JSON) originated as a way to serialize data: an object is converted to a byte stream and transmitted to another computer which constructs an exact duplicate of the original object.

JSON supports several Python data types: dict, list, tuple, str, int, float, and bool. The json module is included in the Python library and is easy to use: dump() writes an object to a file, dumps() writes an object to a string, load() reads an object from a file, and loads() reads an object from a string.

config.json

{
  "NAME": "Stuart",
  "AGE": 3
}

app.py

import json
config = {'NAME': 'Jake', 'AGE': 12} # Default values.
with open('config.json', 'r') as f:
    config.update(json.load(f))
print(f'Name: {config["NAME"]} Age: {config["AGE"]}')

In the example above, the config dictionary is loaded with default settings, and update() merges the defaults with the dictionary read from the JSON file. Simple.

JSON is easy to use, supports several data types, and allows you to provide default settings. I use it for my Drakken and Thera projects.