Storing settings data in Config File in Python


python config data store

A config file is a flat file but is used for reading and writing of settings that affect the behaviour of your application.  These files can be incredibly useful so that you can put individual settings inside the human editable file and then have the settings read from your application.  This helps you configure your application in the way you need without having to change the application code.  

Typically the config file is edited by a simple text editor by the user, then the application runs and reads the config file.  If there are any changes to the config file, normally (depending how the code is written), the application will then have to be restarted to take on the new settings.

Some of the considerations for using a config file as a “data store” includes:

  • Setup: There’s no setup that is required for files.  You should use one of the config management python libraries that are available to make it easier to manipulate config files.
  • Volume: Size Small-ish file size (< 5-10mb)
  • Record access: Does not require to search data within the file to extract just a portion of the records.  You would load or save all the data in the file in one go
  • Data Writes: Applications don’t generally write to a config file, but it can be done.  Instead the config file is edited outside in a text editor 
  • Data formats: Normally the data would be a structured record based (such as comma separated value – CSV or tab delimited), or a more complex structure such as what you see in windows based  .INI files or JSON format even
  • Editability: You generally want to allow direct editing of the file by users
  • Redundancy: There’s no inbuilt redundancy.  If there is any failure (data corrupt, the server with the file fails), then you’re out of luck.  You need to setup your own mechanisms (e.g. replicate file to another server automatically)

Code examples to read and write from config file using ConfigParse

Setting up a config file is actually not that much harder than simply creating a constants inside your application.  Your main decision will be what type of configuration file format you’d like to use as there are quite a few to choose from.  Here are some options and samples:

File type Example config file

1. Simple text file which is tab-delimited

Python Library = noneExample: below

records_per_page    10
logo_icon   /images/company_log.jpg

2. A properties file with key value pair

Python Library = None

#webpage display 
records_per_page = 10
logo_icon = /images/company_log.jpg

3. INI file format

Python library: configparser

[database]
#database related configuration files
port = 22
forward = no
name = db_test

4. JSON file format

Python library: json

{  “records_per_page”:10,  “logo_icon”: “/images/company_log.jpg”}

Example 1: Simple text file which is tab-delimited

You can see a full article on how to read a text file in our “Storing Data in Files in Python” article.  The short version of open a tab delimited file is as follows:

Suppose you have a configuration file as follows where each row has two fields which is separated by a tab:

config_data.txt

records_per_page    10
logo_icon   /images/company_log.jpg

You can load the data into a python dictionary like the following:

config = {}
file_handler = open('config_data.txt', 'r')
for rec in file_handler:
   config.update( [ tuple( rec.strip().split('\t') ) ] )
file_handler.close()
print(config)

The output will be as follows:

{'records_per_page': '10', 'logo_icon': '/images/company_log.jpg'}

Some explanation may be required on the code though to make it easier to understand.  Firstly, the for loop is used to read a record line by line.  So each time the for loop iterates, it will read a line into the field rec until the whole file is read.

The following code is a little tricky, but the intent is to take the two columns in the tab delimited file and create a dictionary key value pair.  

config.update( [ tuple( rec.strip().split('\t') ) ] )

It works by the following:

  1. It first removes the newline character from the end of the line (through rec.strip() )
  2. This will then return a string which is then split with split() by the a tab characters (denoted by ‘\t’)
  3. The result of this is a two filed array which is then created into a tuple format
  4. The tuple is then put in a list and added to list with the [] brackets
  5. The dictionary .update() method is used to finally add they key value pair

Example 2: A properties file with key value pair

If you have a fairly simple configuration needs with just a key-value pair, then a properties type file would work for you where you have <config name> = <config value>.  This can be easily loaded as a text file and then the key-value be loaded into a dictionary.

Imagine this was the config file: config_data.txt

#webpage display
records_per_page =10
logo_icon =/images/company_log.jpg

The following code could easily load this configuration:

config = {}
with open('config_data.txt', 'r') as file_hander:
   for rec in file_hander:
       if rec.startswith('#'): continue
       key, value = rec.strip().split('=')
       if key: config[key] = value
print( config  )  

Here the code ignores any comment lines (e.g. the line starts with a ‘#’), and then string-splits the line by the ‘=’ sign.  This will then load the dictionary ‘config’

Example 3: INI file format using ConfigParse

You can see a full article on how the ConfigParse library works in our earlier article.  The short version is as follows.

Suppose you have a configuration file as follows:

test.ini 

[default]
name = development
host = 192.168.1.1
port = 31
username = admin
password = admin

[database]
name = production
host = 144.101.1.1

You can then read the file with the following simple code:

import configparser

config = configparser.ConfigParser()

#Open the file again to try to read it
config.read('test.ini')
print( config['database'][‘name’] ) #This will output ‘production’
print( config['database'][‘port’] ) #This will output ‘31’.  As there is no port under
                                    # database the default value will be extracted

Example 4: Reading Config values from a JSON file

With JSON being so popular, this is also another alternative you could use to keep all your config data in.  It is very easy to also load.

Assume your config file is as follows: config_data.txt

{
  "records_per_page":10,
  "logo_icon": "/images/company_log.jpg"
}

Then the following code can be used to bring these into a dictionary:

import json
file_handler = open('config_data.txt', 'r')
config = json.loads( file_handler.read() )
file_handler.close()
print(config)

Where the output would be:

{'records_per_page': 10, 'logo_icon': '/images/company_log.jpg'}

Summary

A config file is a great option if you are looking to store settings for your applications.  These are usually loaded at the start of the application and then can be loaded into a dictionary which can then serve as a set of constants which your application can use.  This will both avoid the need to hardcode settings and also allow you to change the behaviour of your application without having to touch the code.

Charles White

I'm a big believer in the value of learning to code and learning to code is something that everyone should learn these days. Here are a collection of things i've learned over the years..

Leave a Reply

Your email address will not be published. Required fields are marked *

Recent Content