2

I am trying some basic python scripts using ConfigParser and converting to a dictionary. I am reading a file named "file.cfg" which contains three sections - root, first, second. Currently the code reads the file and converts everything within the file to a dictionary.

My requirement is to convert only sections named "first" and "second" and so on, its key value pair to a dictionary. What would be best way of excluding the section "root" and its key value pair?

import urllib
import urllib2
import base64
import json
import sys
from ConfigParser import SafeConfigParser

parser = SafeConfigParser()
parser.read('file.cfg')

print parser.get('root', 'auth')

config_dict = {}

for sect in parser.sections():
    config_dict[sect] = {}
    for name, value in parser.items(sect):
        config_dict[sect][name] = value

print config_dict

Contents of file.cfg -

~]# cat file.cfg

[root]
username = admin
password = admin
auth = http://192.168.1.1/login

[first]
username = pete
password = sEcReT
url = http://192.168.1.1/list

[second]
username = ron
password = SeCrET
url = http://192.168.1.1/status

Output of the script -

 ~]# python test4.py 

http://192.168.1.1/login
{'second': {'username': 'ron', 'url': 'http://192.168.1.1/status', 'password': 'SeCrEt'}, 'root': {'username': 'admin', 'password': 'admin', 'auth': 'http://192.168.1.1/login'}, 'first': {'username': 'pete', 'url': 'http://192.168.1.1/list', 'password': 'sEcReT'}}

3 Answers 3

4

You can remove root section from parser.sections() as follows:

parser.remove_section('root')

Also you don't have to iterate over each pair in each section. You can just convert them to dict:

config_dict = {}
for sect in parser.sections():
    config_dict[sect] = dict(parser.items(sect))

Here is one liner:

config_dict = {sect: dict(parser.items(sect)) for sect in parser.sections()}
Sign up to request clarification or add additional context in comments.

Comments

1

Bypass the root section by comparison.

for sect in parser.sections():
    if sect == 'root':
        continue
    config_dict[sect] = {}
    for name, value in parser.items(sect):
        config_dict[sect][name] = value

Edit after acceptance:

ozgur's one liner is a much more concise solution. Upvote from me. If you don't feel like removing sections from the parser directly, the entry can be deleted afterwards.

config_dict = {sect: dict(parser.items(sect)) for sect in parser.sections()} # ozgur's one-liner
del config_dict['root']

1 Comment

del config_dict['root'] may raise KeyError in case of absence of the key. I would do: config_dict.pop('root', None).
0

Maybe a bit off topic, but ConfigParser is a real pain when in comes to store int, floats and booleans. I prefer using dicts which I dump into configparser.

I also use funtcions to convert between ConfigParser objects and dicts, but those deal with variable type changing, so ConfigParser is happy since it requests strings, and my program is happy since 'False' is not False.

def configparser_to_dict(config: configparser.ConfigParser) -> dict:
    config_dict = {}
    for section in config.sections():
        config_dict[section] = {}
        for key, value in config.items(section):
            # Now try to convert back to original types if possible
            for boolean in ['True', 'False', 'None']:
                if value == boolean:
                    value = bool(boolean)

            # Try to convert to float or int
            try:
                if isinstance(value, str):
                    if '.' in value:
                        value = float(value)
                    else:
                        value = int(value)
            except ValueError:
                pass

            config_dict[section][key] = value

    # Now drop root section if present
    config_dict.pop('root', None)
    return config_dict


def dict_to_configparser(config_dict: dict) -> configparser.ConfigParser:
    config = configparser.ConfigParser()

    for section in config_dict.keys():
        config.add_section(section)
        # Now let's convert all objects to strings so configparser is happy
        for key, value in config_dict[section].items():
            config[section][key] = str(value)

    return config

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.