Updated On : Sep-01,2021 Tags configuration-files-parser
configparser - Simple Guide to Create and Parse Configuration Files

configparser - Simple Guide to Create and Parse Configuration Files (.conf, .ini, etc)

Configuration files ending with extensions .ini, .conf or .cfg are used for storing configuration information for particular software. The .ini files are commonly used on windows and .conf files are commonly used on Linux/Unix systems. Configuration information pertains to how to initialize some parameters of the software or some properties which are retrieved from these kinds of files. It can be used to initialize the default behavior of the software as well.

The configuration files have normally below-mentioned format.

[default_section]
key=value
key=value
...

[section_1]
key=value
key=value
...

[section_2]
key=value
key=value
...

:
:


[section_n]
key=value
key=value
...

The file has a list of sections where each section can pertain to a particular part of the software. Each section has a list of key-value pairs storing details about setting particular property. The key can be property name and value can be property value that we want to set. The first section is generally the default section storing default values. If the value is present for a given key in a particular section then the value is read from it else default section is checked for the value of that key.

Python provides a library named configparser which provides a very easy-to-use API to interact with configuration files. As a part of this tutorial, we'll try to explain with simple examples how we can use configparser to create, read, interpret and write configuration files. Python module named logging also uses configuration files for the configuration. Our examples in this tutorial are inspired by configuration files used for configuring logging module in our tutorial on logging.config

Example 1: Create Configuration File

As a part of our first example, we'll explain how we can create a configuration file using ConfigParser instance of configparser module.


  • ConfigParser(defaults=None,dict_type=dict,delimiters=('=',':'),comment_prefixes=('#',';'),default_section=configparser.DEFAULTSECT,interpolation=BasicInterpolation()) - This constructor creates and instance of ConfigParser which holds total configuration details. Below we have explained the arguments of it.
    • defaults - This parameter accepts dictionary and initializes configuration section with it.
    • delimiters - This parameter has a list of characters that will be used to separate key-value pairs.
    • comment_prefixes - This parameter has a list of characters that will be used to indicate lines starting with them as comments.
    • default_section - This parameter accepts string specifying section that will be used as default section. By default, it’s set to configparser.DEFAULTSECT which holds string DEFAULT in it.
    • interpolation - This parameter accepts None or instance of BasicInterplation or ExtendedInterpolation. If we provide BasicInterpolation then it lets us specify format strings in the value of a key and then it'll try to get value for that format string from other values in that section or default section. If we provide ExtendedInterpolation then it also lets us specify formatted strings which let us retrieve values from the same section and other sections as well. We have later created simple examples to explain both.


NOTE

Please make a note that ConfigParser instance works almost like dictionary hence we can retrieve/assign values from/to keys the same way we do with python dictionary.

Important Methods of ConfigParser Object

  • write(file_object) - This method takes as input file-like instance and writes configuration contents to that file.

Our code for the first example starts by creating an instance of ConfigParser with default parameters. It then goes on to create 5 different sections.

* loggers
* handlers
* formatters
* logger_root
* handler_console
* formatter_stdout

It then first initializes each section with an empty dictionary. After that, it assigns different values to the key of the sections. At last, we open a file logging.conf in writing mode and write the content of configuration to it using write() method of ConfigParser object. Please make a note that how we handled the ConfigParser instance as a python dictionary.

Once contents are written, we also verify the contents of the file.

In [1]:
import configparser

parser = configparser.ConfigParser()

parser["loggers"] ={}
parser["loggers"]["keys"] = "root"

parser["handlers"] = {}
parser["handlers"]["keys"] = "console"

parser["formatters"] = {}
parser["formatters"]["keys"] = "stdout"

parser["logger_root"] = {}
parser["logger_root"]["handlers"] = "console"
parser["logger_root"]["level"] = "DEBUG"

parser["handler_console"] = {}
parser["handler_console"]["class"] = "logging.StreamHandler"
parser["handler_console"]["level"] = "DEBUG"
parser["handler_console"]["formatter"] = "stdout"

parser["formatter_stdout"] = {}
parser["formatter_stdout"]["format"] = "$(levelname)s : $(module)s : $(funcName)s : $(message)s"

with open("logging.conf", "w") as fp:
    parser.write(fp)
In [2]:
!cat logging.conf
[loggers]
keys = root

[handlers]
keys = console

[formatters]
keys = stdout

[logger_root]
handlers = console
level = DEBUG

[handler_console]
class = logging.StreamHandler
level = DEBUG
formatter = stdout

[formatter_stdout]
format = $(levelname)s : $(module)s : $(funcName)s : $(message)s

Example 2: Read Configuration File

As a part of our second example, we demonstrate how we can read the existing configuration file and print the contents. We'll use read() method of ConfigParser instance for our purpose.


Important Methods of ConfigParser Object

  • read(filenames,encoding=None) - This method accepts one or more file names and loads the contents of each file. It also lets us provide encoding of the file to read.

Our code for this example starts by creating an instance of ConfigParser. It then reads the configuration file that we created in our previous example. We are then treading ConfigParser instance as a dictionary and printing information about a different section. As we already know the contents of the file, we are calling it this way. We'll explain in upcoming examples how to handle files for which we don't know the structure.

In [3]:
import configparser

parser = configparser.ConfigParser()

parser.read("logging.conf");

print("loggers                    : {}".format(parser['loggers']))
print("loggers[keys]              : {}\n".format(parser['loggers']["keys"]))

print("handlers                   : {}".format(parser['handlers']))
print("handlers[keys]             : {}\n".format(parser['handlers']["keys"]))

print("formatters                 : {}".format(parser['formatters']))
print("formatters[keys]           : {}\n".format(parser['formatters']["keys"]))

print("logger_root                : {}".format(parser['logger_root']))
print("logger_root[handlers]      : {}".format(parser['logger_root']["handlers"]))
print("logger_root[level]         : {}\n".format(parser['logger_root']["level"]))


print("handler_console            : {}".format(parser['handler_console']))
print("handler_console[class]     : {}".format(parser['handler_console']["class"]))
print("handler_console[level]     : {}".format(parser['handler_console']["level"]))
print("handler_console[formatter] : {}\n".format(parser['handler_console']["formatter"]))

print("formatter_std_out          : {}".format(parser['formatter_stdout']))
print("formatter_std_out[format]  : {}".format(parser['formatter_stdout']["format"]))
loggers                    : <Section: loggers>
loggers[keys]              : root

handlers                   : <Section: handlers>
handlers[keys]             : console

formatters                 : <Section: formatters>
formatters[keys]           : stdout

logger_root                : <Section: logger_root>
logger_root[handlers]      : console
logger_root[level]         : DEBUG

handler_console            : <Section: handler_console>
handler_console[class]     : logging.StreamHandler
handler_console[level]     : DEBUG
handler_console[formatter] : stdout

formatter_std_out          : <Section: formatter_stdout>
formatter_std_out[format]  : $(levelname)s : $(module)s : $(funcName)s : $(message)s

Example 3: Default Section

As a part of our third example, we'll explain how we can create default section of the configuration.


NOTE

Please make a note that whenever particular section does not have any key then it'll try to retrieve that key's value from default section.

Our code for this example is almost the same as our code from the first example with few minor additions. We have added code for adding DEFAULT section and two key-value pairs in it. We are then trying to retrieve those keys in sections where they are not present to check whether it's getting values from the default section or not. We can notice that level key is not defined in loggers and formatters section, hence it retrieves the value of it from the default section. Same way propagate key is not defined in handlers and formatter_std_out section but value is retrieved from default section.

In [4]:
import configparser

parser = configparser.ConfigParser()

parser["DEFAULT"] = {}
parser["DEFAULT"]["level"] = "WARNING"
parser["DEFAULT"]["propagate"] = "True"

parser["loggers"] ={}
parser["loggers"]["keys"] = "root"

parser["handlers"] = {}
parser["handlers"]["keys"] = "console"

parser["formatters"] = {}
parser["formatters"]["keys"] = "stdout"

parser["logger_root"] = {}
parser["logger_root"]["handlers"] = "console"
parser["logger_root"]["level"] = "DEBUG"

parser["handler_console"] = {}
parser["handler_console"]["class"] = "logging.StreamHandler"
parser["handler_console"]["level"] = "DEBUG"
parser["handler_console"]["formatter"] = "std_out"

parser["formatter_stdout"] = {}
parser["formatter_stdout"]["format"] = "$(levelname)s : $(module)s : $(funcName)s : $(message)s"

with open("logging1.conf", "w") as fp:
    parser.write(fp)

print("loggers[level]             : {}".format(parser["loggers"]["level"]))
print("formatters[level]          : {}".format(parser["formatters"]["level"]))
print("handlers[level]            : {}".format(parser["formatters"]["propagate"]))
print("formatter_std_out[level]   : {}".format(parser["formatters"]["propagate"]))
loggers[level]             : WARNING
formatters[level]          : WARNING
handlers[level]            : True
formatter_std_out[level]   : True
In [5]:
!cat logging1.conf
[DEFAULT]
level = WARNING
propagate = True

[loggers]
keys = root

[handlers]
keys = console

[formatters]
keys = stdout

[logger_root]
handlers = console
level = DEBUG

[handler_console]
class = logging.StreamHandler
level = DEBUG
formatter = std_out

[formatter_stdout]
format = $(levelname)s : $(module)s : $(funcName)s : $(message)s

Below we have created another example to demonstrate how we can create a default section. The code for this example is almost the same as our previous example with a minor change. We have provided default dictionary to defaults parameter of the ConfigParser instance. All the remaining code is the same as the previous example.

In [6]:
import configparser

parser = configparser.ConfigParser(defaults={"level":"WARNING", "propagate": "True"})

parser["loggers"] ={}
parser["loggers"]["keys"] = "root"

parser["handlers"] = {}
parser["handlers"]["keys"] = "console"

parser["formatters"] = {}
parser["formatters"]["keys"] = "stdout"

parser["logger_root"] = {}
parser["logger_root"]["handlers"] = "console"
parser["logger_root"]["level"] = "DEBUG"

parser["handler_console"] = {}
parser["handler_console"]["class"] = "logging.StreamHandler"
parser["handler_console"]["level"] = "DEBUG"
parser["handler_console"]["formatter"] = "std_out"

parser["formatter_stdout"] = {}
parser["formatter_stdout"]["format"] = "$(levelname)s : $(module)s : $(funcName)s : $(message)s"

with open("logging2.conf", "w") as fp:
    parser.write(fp)

print("loggers[level]             : {}".format(parser["loggers"]["level"]))
print("formatters[level]          : {}".format(parser["formatters"]["level"]))
print("handlers[level]            : {}".format(parser["formatters"]["propagate"]))
print("formatter_std_out[level]   : {}".format(parser["formatters"]["propagate"]))
loggers[level]             : WARNING
formatters[level]          : WARNING
handlers[level]            : True
formatter_std_out[level]   : True
In [7]:
!cat logging2.conf
[DEFAULT]
level = WARNING
propagate = True

[loggers]
keys = root

[handlers]
keys = console

[formatters]
keys = stdout

[logger_root]
handlers = console
level = DEBUG

[handler_console]
class = logging.StreamHandler
level = DEBUG
formatter = std_out

[formatter_stdout]
format = $(levelname)s : $(module)s : $(funcName)s : $(message)s

Example 4: Parse Configuration File

As a part of our fourth example, we'll explain different methods of ConfigParser instance that can be used to parse the contents of a configuration file. Below is a list of methods that we'll explain in this example.


Important Methods of ConfigParser Object

  • read_file(f) - This method takes as input file-like object and reads the configuration contents from it.
  • defaults() - This method returns dictionary of defaults.
  • sections() - This method returns list of sections in configuration excluding default section.
  • has_section(section) - This method takes as input string and returns True if section is present in configuration else False.
  • options(section) - This method takes as input section name and returns keys in that section. It'll include keys from the default section not present in that section as well.
  • has_option(section,option) - It takes as input section and key name. It then checks for availability of that key in that section and returns True if present else False.
  • get(section,option) - It takes as input section and key as input. It then returns a value of that key from that section.
  • getboolean(section,option) - It works exactly like get() method but return boolean value. It should be used for key which returns boolean value. If we use get() method instead then it'll return value as string.
  • items() - This method works like a python dictionary and returns a list where each entry is a tuple. The first value in the tuple is section name and the second value is a dictionary containing key-value pairs of that section. It'll return key-value pairs from the default section which are not present in a particular section.
  • items(section) - This method takes as an input section name and returns a list of tuples. The first entry is key and the second entry is the value for that key from that section.

Our code for this example starts by creating an instance of ConfigParser as usual. It then reads the configuration contents from the file which we created in the previous example. We are then calling different methods of ConfigParser instance to explain their usage. We are also printing information about each section using items() method.

In [8]:
import configparser

parser = configparser.ConfigParser()

parser.read_file(open("logging1.conf"))

print("Defaults Section                  : {}".format(parser.defaults()))
print("Sections                          : {}".format(parser.sections()))
print("Does parser has loggers section?  : {}".format(parser.has_section("loggers")))
print("Section Options                   : {}".format(parser.options("handlers")))
print("Section loggers has option keys?  : {}".format(parser.has_option("loggers", "keys")))
print("Section loggers has option class? : {}".format(parser.has_option("loggers", "class")))
print("Section loggers has option class? : {}".format(parser.has_option("loggers", "propagate"))) ## Value will come from Default section
print("loggers[keys]                     : {}".format(parser.get("loggers", "keys")))
print("loggers[level]                    : {}".format(parser.get("loggers", "level")))
print("DEFAULT[propagate]                : {}\n".format(parser.getboolean("DEFAULT", "propagate")))

print("======== All Sections ===============")
for section_name, section in parser.items():
    print("{:20s} - {} - {}".format(section_name, section, dict(section)))

print("\n ============== Handlers Section ================")
for sec_key, sec_val in parser.items("handlers"):
    print("{:20s} - {}".format(sec_key, sec_val))
Defaults Section                  : OrderedDict([('level', 'WARNING'), ('propagate', 'True')])
Sections                          : ['loggers', 'handlers', 'formatters', 'logger_root', 'handler_console', 'formatter_stdout']
Does parser has loggers section?  : True
Section Options                   : ['keys', 'level', 'propagate']
Section loggers has option keys?  : True
Section loggers has option class? : False
Section loggers has option class? : True
loggers[keys]                     : root
loggers[level]                    : WARNING
DEFAULT[propagate]                : True

======== All Sections ===============
DEFAULT              - <Section: DEFAULT> - {'level': 'WARNING', 'propagate': 'True'}
loggers              - <Section: loggers> - {'keys': 'root', 'level': 'WARNING', 'propagate': 'True'}
handlers             - <Section: handlers> - {'keys': 'console', 'level': 'WARNING', 'propagate': 'True'}
formatters           - <Section: formatters> - {'keys': 'stdout', 'level': 'WARNING', 'propagate': 'True'}
logger_root          - <Section: logger_root> - {'handlers': 'console', 'level': 'DEBUG', 'propagate': 'True'}
handler_console      - <Section: handler_console> - {'class': 'logging.StreamHandler', 'level': 'DEBUG', 'formatter': 'std_out', 'propagate': 'True'}
formatter_stdout     - <Section: formatter_stdout> - {'format': '$(levelname)s : $(module)s : $(funcName)s : $(message)s', 'level': 'WARNING', 'propagate': 'True'}

 ============== Handlers Section ================
level                - WARNING
propagate            - True
keys                 - console

Example 5: Add/Remove Sections/Options from Configuration File

As a part of our fifth example, we'll explain how we can add/remove sections/options from the configuration using methods of ConfigParser instance. We'll be using the below-mentioned methods for our purpose.


Important Methods of ConfigParser Object

  • add_section(section) - This method accepts section name as input and adds that section in configuration.
  • remove_section(section) - This method accepts section name as input and removes that section from configuration.
  • set(section,key,value) - This method accepts section name, key name and value as input and adds that key-value pair to that section.
  • remove_option(section,key) - This method accepts section name and key from that section as input and removes that key-value pairs from section.

Our code for this example starts by creating an instance of ConfigParser and reads the existing configuration file that we created in our previous example using it. We then add a new section named loggers_main to configuration and print a list of sections to verify addition. We then add four options to that section and verify them by printing. We then remove filters option from loggers_main section and verify removal. We then remove loggers_main section and list down sections to verify the removal.

In [9]:
import configparser

parser = configparser.ConfigParser()

parser.read_file(open("logging1.conf"))

print("Current Sections        : {}".format(parser.sections()))

parser.add_section("loggers_main") ### Add Section

print("\nSections After Addition : {}".format(parser.sections()))

parser.set("loggers_main", "handlers", "console") ## Add Values to New Section 
parser.set("loggers_main", "level", "INFO")       ## Add Values to New Section
parser.set("loggers_main", "propagate", "False")  ## Add Values to New Section
parser.set("loggers_main", "filters", "warnings_filter")  ## Add Values to New Section

print("\nloggers_main Section    : {}".format(dict(parser["loggers_main"])))

result = parser.remove_option("loggers_main", "filters")  ## Remove option filters from loggers_main

print("\nIs filters option removed from loggers_main? : {}".format(result))

print("\nloggers_main Section    : {}".format(dict(parser["loggers_main"])))

result = parser.remove_section("loggers_main") ### Remove Section loggers_main

print("\nIs loggers_main section removed from parser? : {}".format(result))

print("\nSections                : {}".format(parser.sections()))

print("\nBoolean States in Parser : {}".format(parser.BOOLEAN_STATES))
Current Sections        : ['loggers', 'handlers', 'formatters', 'logger_root', 'handler_console', 'formatter_stdout']

Sections After Addition : ['loggers', 'handlers', 'formatters', 'logger_root', 'handler_console', 'formatter_stdout', 'loggers_main']

loggers_main Section    : {'handlers': 'console', 'level': 'INFO', 'propagate': 'False', 'filters': 'warnings_filter'}

Is filters option removed from loggers_main? : True

loggers_main Section    : {'handlers': 'console', 'level': 'INFO', 'propagate': 'False'}

Is loggers_main section removed from parser? : True

Sections                : ['loggers', 'handlers', 'formatters', 'logger_root', 'handler_console', 'formatter_stdout']

Boolean States in Parser : {'1': True, 'yes': True, 'true': True, 'on': True, '0': False, 'no': False, 'false': False, 'off': False}

Example 6: Create Configuration File from String

As a part of our sixth example, we are demonstrating how we can create a configuration from a string. We'll be using read_string() method of ConfigParser for our purpose which accepts a string as input and creates configuration from it.

Our code for this example starts by creating an instance of ConfigParser as usual. We then load configuration details using read_string() method passing configuration as a single string to it. We then write the configuration to a file. At last, we verify the contents of the configuration file as well.

In [10]:
import configparser

parser = configparser.ConfigParser()

parser.read_string('''
[DEFAULT]
level = WARNING
propagate = True

[loggers]
keys = root

[handlers]
keys = console

[formatters]
keys = stdout

[logger_root]
handlers = console
level = DEBUG

[handler_console]
class = logging.StreamHandler
level = DEBUG
formatter = stdout

[formatter_stdout]
format = $(levelname)s : $(module)s : $(funcName)s : $(message)s
''')

with open("logging3.conf", "w") as fp:
    parser.write(fp)
In [11]:
!cat logging3.conf
[DEFAULT]
level = WARNING
propagate = True

[loggers]
keys = root

[handlers]
keys = console

[formatters]
keys = stdout

[logger_root]
handlers = console
level = DEBUG

[handler_console]
class = logging.StreamHandler
level = DEBUG
formatter = std_out

[formatter_stdout]
format = $(levelname)s : $(module)s : $(funcName)s : $(message)s

Example 7: Create Configuration File from Dictionary

As a part of our seventh example, we are demonstrating how we can create a configuration from a dictionary. We'll be using read_dict() method of ConfigParser for this purpose. It takes as input a dictionary containing configuration details.

Our code for this example starts as usual by creating an instance of ConfigParser. It then creates a dictionary with configuration details. We then load configuration details present in dictionary to ConfigParser instance using read_dict() method. It then writes the contents of the configuration to a file and verifies the contents of the file by printing them at last.

In [12]:
import configparser

parser = configparser.ConfigParser()

config_dict = {
    "DEFAULT": {
        "level":"WARNING",
        "propagate":"True"
    },
    "loggers": {
        "keys": "root"
    },
    "handlers": {
        "keys": "console"
    },
    "formatters": {
        "keys": "stdout"
    },
    "loggers_root": {
        "handlers": "console",
        "level": "DEBUG"
    },
    "handler_console": {
        "class": "logging.StreamHandler",
        "level": "DEBUG",
        "formatter": "stdout"
    },
    "formatter_stdout": {
        "format": "$(levelname)s : $(module)s : $(funcName)s : $(message)s"
    }

}

parser.read_dict(config_dict)

with open("logging4.conf", "w") as fp:
    parser.write(fp)
In [13]:
!cat logging4.conf
[DEFAULT]
level = WARNING
propagate = True

[loggers]
keys = root

[handlers]
keys = console

[formatters]
keys = stdout

[logger_root]
handlers = console
level = DEBUG

[handler_console]
class = logging.StreamHandler
level = DEBUG
formatter = stdout

[formatter_stdout]
format = $(levelname)s : $(module)s : $(funcName)s : $(message)s

Example 8: Basic Interpolation

As a part of our eighth example, we'll explain how interpolation parameter of ConfigParser instance works. We had mentioned earlier that interpolation parameter is set to BasicInterpolation by default which lets us specify a formatted string as values of the keys.

Our code for this example starts by creating an instance of ConfigParser. It then creates a dictionary with configuration details. This time we have added few extra keys in formatter_stdout section. We have provided formatted strings in the values of that keys. We have included other key-value pairs in that section that holds values that are required by formatted strings.

We can notice that all 4 values required by format1 key are present in that section. For format2 option, name key is not present in that section but is present in DEFAULT section hence it'll be taken from there. Our third option format3 is included to explain how we can escape % character. The value of that option won't be treated as a formatted string.

Our code then loads configuration details from a dictionary. We are then printing items of each section as well for verification purposes. We can notice that how formatted strings are replaced with values from the same section or default section.


NOTE

Please make a note that if we set interpolation parameter to None then the special handling of formatted string won't happen. It'll treat them as simple strings.

In [26]:
import configparser

parser = configparser.ConfigParser()

config_dict = {
    "DEFAULT": {
        "level":"WARNING",
        "propagate":"True",
        "name": "default"
    },
    "loggers": {
        "keys": "root"
    },
    "handlers": {
        "keys": "console"
    },
    "formatters": {
        "keys": "stdout"
    },
    "loggers_root": {
        "handlers": "console",
        "level": "DEBUG"
    },
    "handler_console": {
        "class": "logging.StreamHandler",
        "level": "DEBUG",
        "formatter": "stdout"
    },
    "formatter_stdout": {
        "levelname": "WARNING",
        "module": "Addition",
        "funcName": "addition",
        "message": "Addition Completed Successfully",
        "format1": "%(levelname)s : %(module)s : %(funcName)s : %(message)s",
        "format2": "%(name)s : %(message)s",
        "format3": "%%(message)s"
    }

}


parser.read_dict(config_dict)

for section_name, section in parser.items():
    print("{:18s} - {}".format(section_name, dict(section)))
DEFAULT            - {'level': 'WARNING', 'propagate': 'True', 'name': 'default'}
loggers            - {'keys': 'root', 'level': 'WARNING', 'propagate': 'True', 'name': 'default'}
handlers           - {'keys': 'console', 'level': 'WARNING', 'propagate': 'True', 'name': 'default'}
formatters         - {'keys': 'stdout', 'level': 'WARNING', 'propagate': 'True', 'name': 'default'}
loggers_root       - {'handlers': 'console', 'level': 'DEBUG', 'propagate': 'True', 'name': 'default'}
handler_console    - {'class': 'logging.StreamHandler', 'level': 'DEBUG', 'formatter': 'stdout', 'propagate': 'True', 'name': 'default'}
formatter_stdout   - {'levelname': 'WARNING', 'module': 'Addition', 'funcname': 'addition', 'message': 'Addition Completed Successfully', 'format1': 'WARNING : Addition : addition : Addition Completed Successfully', 'format2': 'default : Addition Completed Successfully', 'format3': '%(message)s', 'level': 'WARNING', 'propagate': 'True', 'name': 'default'}

Example 9: Extended Interpolation

As a part of our ninth and last example, we'll explain what is use of ExtendedInterpolation class is. This class lets us specify formatted strings like BasicInterpolation but it also lets us retrieve value from keys of other sections unlike BasicInterpolation which lets us retrieve values only from the current or default section.

The ExtendedInterpolation let us specify formatted string in format ${[section:]option}. Here section is optional and if we don't specify the section then it'll try to retrieve that value from the key of the current section or default section.

Our code for this example starts by creating an instance of ConfigParser as usual but this time it sets interpolation parameter with an instance of ExtendedInterpolation.

We have then created a dictionary with configuration details. We have added extra options in formatter_stdout section for explanation purpose. The value of format1 option tries to retrieve one value from handler_console section and the remaining value from the current section. The value of format2 option tries to retrieve all values from the current section.

Our code then parses contents of dictionary into ConfigParser instance using read_dict() method. We are then printing section details to verify that formatted strings were properly interpreted or not.

In [22]:
import configparser

parser = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())

config_dict = {
    "DEFAULT": {
        "level":"WARNING",
        "propagate":"True"
    },
    "loggers": {
        "keys": "root"
    },
    "handlers": {
        "keys": "console"
    },
    "formatters": {
        "keys": "stdout"
    },
    "loggers_root": {
        "handlers": "console",
        "level": "DEBUG"
    },
    "handler_console": {
        "class": "logging.StreamHandler",
        "level": "DEBUG",
        "formatter": "stdout"
    },
    "formatter_stdout": {
        "levelname": "WARNING",
        "module": "Addition",
        "funcName": "addition",
        "message": "Addition Completed Successfully",
        "format1": "${handler_console:level} : ${module} : ${funcName} : ${message}",
        "format2": "${levelname} : ${module} : ${funcName} : ${message}",

    }

}

parser.read_dict(config_dict)

for section_name, section in parser.items():
    print("{:18s} - {}".format(section_name, dict(section)))
DEFAULT            - {'level': 'WARNING', 'propagate': 'True'}
loggers            - {'keys': 'root', 'level': 'WARNING', 'propagate': 'True'}
handlers           - {'keys': 'console', 'level': 'WARNING', 'propagate': 'True'}
formatters         - {'keys': 'stdout', 'level': 'WARNING', 'propagate': 'True'}
loggers_root       - {'handlers': 'console', 'level': 'DEBUG', 'propagate': 'True'}
handler_console    - {'class': 'logging.StreamHandler', 'level': 'DEBUG', 'formatter': 'stdout', 'propagate': 'True'}
formatter_stdout   - {'levelname': 'WARNING', 'module': 'Addition', 'funcname': 'addition', 'message': 'Addition Completed Successfully', 'format1': 'DEBUG : Addition : addition : Addition Completed Successfully', 'format2': 'WARNING : Addition : addition : Addition Completed Successfully', 'level': 'WARNING', 'propagate': 'True'}

This ends our small tutorial explaining the usage of configparser module of python. Please feel free to let us know your views in the comments section.



Sunny Solanki  Sunny Solanki