In this tutorial, we are going to see how to read python config .ini file.

How to read config.ini files:

The python’s configparser module used to read the .ini files, typically these file contains configuration information.

The following few examples illustrate some of the more interesting features of the ConfigParsermodule. First, consider a sample .ini file:

app_config.ini
[dev]
LOG_FILE_PATH = %(BASEDIR)s/app.log
secret_key = DEV_SECRET_KEY
secret_value = DEV_SECRET_VALUE
BASEDIR = /opt/logs
port = 8080
is_debug = on
app_base_url = dev.myapp.com

[stage]
LOG_FILE_PATH = %(basedir)s/app.log
secret_key = STAGE_SECRET_KEY
secret_value = STAGE_SECRET_VALUE
BASEDIR = /opt/logs
port = 8088
is_debug = off
app_base_url = stage.myapp.com

Let’s read the above app_config.ini file using the python configparser module.

from configparser import ConfigParser

cfg = ConfigParser()
cfg.read('app_config.ini')

print ("Sections : ", cfg.sections())

for section in cfg.sections():
    print("SECTION -> ",section)
    print("-------------------")
    print('LOG_FILE_PATH - ' , cfg.get(section,'LOG_FILE_PATH'))
    print('SECRET_KEY - ', cfg.get(section,'SECRET_KEY'))
    print('SECRET_VALUE - ' , cfg.get(section,'SECRET_VALUE'))
    print('PORT - ' , cfg.get(section,'PORT'))
    print('APP_BASE_URL - ' , cfg.get(section,'APP_BASE_URL'))
    print('IS_DEBUG - ', cfg.getboolean(section, 'IS_DEBUG'))

Output:

Sections :  ['dev', 'stage']
SECTION ->  dev
-------------------
LOG_FILE_PATH -  /opt/logs/app.log
SECRET_KEY -  DEV_SECRET_KEY
SECRET_VALUE -  DEV_SECRET_VALUE
PORT -  8080
APP_BASE_URL -  dev.myapp.com
IS_DEBUG - True
SECTION ->  stage
-------------------
LOG_FILE_PATH -  /opt/logs/app.log
SECRET_KEY -  STAGE_SECRET_KEY
SECRET_VALUE -  STAGE_SECRET_VALUE
PORT -  8088
APP_BASE_URL -  stage.myapp.com
IS_DEBUG - False

Points to note while using ConfigParser:

  • Configuration parameters are case insensitive. Thus, if your program is reading a parameter 'log_file_path', it does not matter if the configuration file uses 'log_file_path', 'LOG_FILE_PATH', or 'Log_File_Path
  • Configuration parameters can include variable substitutions such as '%(BASEDIR)s' as seen in the file. These substitutions are also case insensitive.
  • The definition order of configuration parameters does not matter in these substitutions. For example, in config.ini, the LOGFILE parameter makes a reference to the BASEDIR parameter, which is defined later in the file.
  • The values in configuration files are often interpreted correctly even if they donโ€™t exactly match Python syntax or datatypes. For example, the 'on' value of the IS_DEBUG parameter is interpreted as True by the cfg.getboolean()method.

Merging configuration files:

The configuration files have the ability to merge together, suppose we have separate .ini file for each environment, we can merge among them and read the content.

prod_app_config.ini
[prod]
LOG_FILE_PATH = %(BASEDIR)s/app.log
secret_key = PROD_SECRET_KEY
secret_value = PROD_SECRET_VALUE
BASEDIR = /opt/app/logs
port = 8000
is_debug = off
app_base_url = myapp.com

read the prod_app_config.ini file soon after reading the config.ini file like below, so that both the config files made available to read the content.

from configparser import ConfigParser

cfg = ConfigParser()
cfg.read('app_config.ini')
cfg.read('prod_app_config.ini')

print ("Sections : ", cfg.sections())

for section in cfg.sections():
    print("SECTION -> ",section)
    print("-------------------")
    print('LOG_FILE_PATH - ' , cfg.get(section,'LOG_FILE_PATH'))
    print('SECRET_KEY - ', cfg.get(section,'SECRET_KEY'))
    print('SECRET_VALUE - ' , cfg.get(section,'SECRET_VALUE'))
    print('PORT - ' , cfg.get(section,'PORT'))
    print('APP_BASE_URL - ' , cfg.get(section,'APP_BASE_URL'))
    print('IS_DEBUG - ' , cfg.getboolean(section,'is_debug'))

you can observe the Sections in the output now we could see [‘dev’, ‘stage’, ‘prod’].

Sections :  ['dev', 'stage', 'prod']
SECTION ->  dev
-------------------
LOG_FILE_PATH -  /opt/logs/app.log
SECRET_KEY -  DEV_SECRET_KEY
SECRET_VALUE -  DEV_SECRET_VALUE
PORT -  8080
APP_BASE_URL -  dev.myapp.com
IS_DEBUG -  True
SECTION ->  stage
-------------------
LOG_FILE_PATH -  /opt/logs/app.log
SECRET_KEY -  STAGE_SECRET_KEY
SECRET_VALUE -  STAGE_SECRET_VALUE
PORT -  8088
APP_BASE_URL -  stage.myapp.com
IS_DEBUG -  False
SECTION ->  prod
-------------------
LOG_FILE_PATH -  /opt/app/logs/app.log
SECRET_KEY -  PROD_SECRET_KEY
SECRET_VALUE -  PROD_SECRET_VALUE
PORT -  8000
APP_BASE_URL -  myapp.com
IS_DEBUG -  False
We do have RawConfigParser class for the same, and it also provides all the functionalities provided by the ConfigParser class except variable interpolation. If you’re least bother about variable interpolation you may use RawConfigParser.

References:

Happy Learning ๐Ÿ™‚