Python configuration files

Introduction

A common need when writing an application is loading and saving configuration values in a human-readable text format. For example, if you need to pass in database configuration information at run-time, you might want to have a file that stores the username, password, and database name in a plain-text file that you can modify. This is where INI configuration files come in.

Python standard library has a configparser module that can read and write INI style files. We will look at how to read and write INI files as well as some alternatives for storing configuration.

Note this is for Python 3. Python 2 does have a ConfigParser.ConfigParser class but it is not exactly the same.

Writing INI files

To create an INI file and write it to disk, you first need to create an instance of the ConfigParser class. Then you treat it as a dictionary and populate the data you want. Then you use the write() method provided by the ConfigParser object to store the data in a file. Here is an example:

from configparser import ConfigParser

config = ConfigParser()
config['main_section'] = {
    'key1': 'value1',
    'key2': 123,
    'key3': 123.45,
}

with open('config.ini', 'w') as output_file:
    config.write(output_file)

# Example output in `congig.ini`:
"""
[main_section]
key1 = value1
key2 = 123
key3 = 123.45
"""

Reading INI files

Let's try to read the file that we created in the last section. We will load the contents in to a config parser and access some of the values.

Note that even though we were able to output integers and floating point values, everything gets stored in the INI file as a string. You will have to be explicit when loading the value if you want it to be a specific data type.

It is also possible to provide default values in case the key you are looking for does not exist in the INI file.

from configparser import ConfigParser

config = ConfigParser()
config.read('config.ini')


# Get a list of all sections
print('Sections: %s' % config.sections())

# You can treat it as an iterable and check for keys
# or iterate through them
if 'main_section' in config:
    print('Main section does exist in config.')

for section in config:
    print('Section: %s' % section)
    for key, value in config[section].items():
        print('Key: %s, Value: %s' % (key, value))

# If you know exactly what key you are looking for,
# try to grab it directly, optionally providing a default
print(config['main_section'].get('key1'))  # Gets as string
print(config['main_section'].getint('key2',))
print(config['main_section'].getfloat('key3'))
print(config['main_section'].getboolean('key99', False))

Alternatives

Using INI files is only one option for reading and writing configuration values. There are many other options but here are a few worth considering:

  • JSON files - Python's standard json module is good for reading and writing JSON data which can be written and read from a file. The syntax for JSON is a little more complex to edit by hand, but still possible. This can be good if your configuration is too complex to store in INI format.
  • Python files - You can create a .py file and store your variables in there directly. Then obtaining your configuration is as simple as importing your Python file and accessing the variables. The big benefit here is that you can include some logic if necessary, and store complex data structures.

Conclusion

After reading this, you should understand how to read and write INI format configuration files in Python as well as some alternative options.

References