How to log the contents of a ConfigParser?

Question:

How can I print the contents of a Python 2.7 ConfigParser to logging?

The only solution I can find is to write to a temporary file and read that file back in. Another idea I had was to get a fake “file handle” from the logging utility and pass that to the ConfigParser write method, but I don’t know how to get such a handle form logging.

Asked By: Adam

||

Answers:

You should be able to create a writable object that writes to the log. Something like this (if you want to keep the string around you could modify the ConfigLogger to save it as well):

import ConfigParser
import logging

class ConfigLogger(object):
    def __init__(self, log):
        self.__log = log
    def __call__(self, config):
        self.__log.info("Config:")
        config.write(self)
    def write(self, data):
        # stripping the data makes the output nicer and avoids empty lines
        line = data.strip()
        self.__log.info(line)

config = ConfigParser.ConfigParser()
config.add_section("test")
config.set("test", "a", 1)
# create the logger and pass it to write
logging.basicConfig(filename="test.log", level=logging.INFO)
config_logger = ConfigLogger(logging)
config_logger(config)

This yields the following output:

INFO:root:Config:
INFO:root:[test]
INFO:root:a = 1
INFO:root:
Answered By: agrinh

As this is the top Google search result and I was hoping to find a solution to print the values of the ConfigParser instance to stdout, here’s a one-liner to help all future readers:

print({section: dict(config[section]) for section in config.sections()})
Answered By: Sean Pianka

Just use a StringIO object and the configparser’s write method.

It looks like the only method for "printing" the contents of a config object is ConfigParser.write which takes a file-like object. io.StringIO is a file-like object. So, write the config to the StringIO object and then read the StringIO object into a string.

import logging
import io
import configparser



if __name__ == "__main__":
    ini='''
[GENERAL]
station_id = station_id

[SERIAL PORTS]
serial_ports = 
    com1
    com2
    com3
'''
    cp = configparser.ConfigParser()
    cp.read_string(ini)
    with io.StringIO() as ss:
        cp.write(ss)
        ss.seek(0) # rewind
        logging.warning(ss.read())

output:

WARNING:root:[GENERAL]
station_id = station_id

[SERIAL PORTS]
serial_ports = 
    com1
    com2
    com3
Answered By: shrewmouse

In Python 3, you can print all sections, including the DEFAULT section, by using this variation of Sean Pianka’s one-liner:

print({section: dict(config[section]) for section in config})

Iterating over config instead of config.sections() also returns the DEFAULT section.

Answered By: cma
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.