config file with a dictionary using python

22,622

Solution 1

If you're not obligated to use INI files, you might consider using another file format more suitable to handle dict-like objects. Looking at the example file you gave, you could use JSON files, Python has a built-in module to handle it.

Example:

JSON File "settings.json":

{"report": {"/report1": "/https://apicall...", "/report2": "/https://apicall..."}}

Python code:

import json

with open("settings.json") as jsonfile:
    # `json.loads` parses a string in json format
    reports_dict = json.load(jsonfile)
    for report in reports_dict['report']:
        # Will print the dictionary keys
        # '/report1', '/report2'
        print report

Solution 2

I had a similar issue trying to read ini file:

[Section]
Value: {"Min": -0.2 , "Max": 0.2}

Ended up using a combination of config parser and json:

import ConfigParser
import json
IniRead = ConfigParser.ConfigParser()
IniRead.read('{0}\{1}'.format(config_path, 'config.ini'))
value = json.loads(IniRead.get('Section', 'Value'))

Obviously other text file parsers can be used as the json load only requires a string in the json format. One issue I did run into was the keys in the dictionary/ json string need to be in double quotes.

Solution 3

Your config file settings.ini should be in following format:

[report]
/report1 = /https://apicall...
/report2 = /https://apicall...

from configobj import ConfigObj

config = ConfigObj('settings.ini')
for report, url in config['report'].items():
    print report, url

If you want to use unrepr=True, you need to

Solution 4

This config file used as input is fine:

report = {'/report1': '/https://apicall...', '/report2': '/https://apicall...'}

This config file used as input

flag = true
report = {'/report1': '/https://apicall...', '/report2': '/https://apicall...'}

generates this exception, which looks like what you are getting:

O:\_bats>configobj-test.py
Traceback (most recent call last):
  File "O:\_bats\configobj-test.py", line 43, in <module>
    config = ConfigObj('configobj-test.ini', unrepr=True)
  File "c:\Python27\lib\site-packages\configobj.py", line 1242, in __init__
    self._load(infile, configspec)
  File "c:\Python27\lib\site-packages\configobj.py", line 1332, in _load
    raise error
configobj.UnreprError: Unknown name or type in value at line 1.

With the unrepr mode set on, you are required to use valid Python keywords. In my example I used true instead of True. I'm guessing you have some other settings in your Settings.ini which are causing the exception.

The unrepr option allows you to store and retrieve the basic Python data-types using config files. It has to use a slightly different syntax to normal ConfigObj files. Unsurprisingly it uses Python syntax. This means that lists are different (they are surrounded by square brackets), and strings must be quoted.

The types that unrepr can work with are :

strings, lists, tuples
None, True, False
dictionaries, integers, floats
longs and complex numbers

Share:
22,622
Jesse Dugger
Author by

Jesse Dugger

Updated on June 21, 2020

Comments

  • Jesse Dugger
    Jesse Dugger almost 4 years

    So I am trying to use a dictionary inside a config file to store a report name to an API call. So something like this:

    report = {'/report1': '/https://apicall...', '/report2': '/https://apicall...'}
    

    I need to store multiple reports:apicalls to one config value. I am using ConfigObj. I have read there documentation, documentation and it says I should be able to do it. My code looks something like this:

    from configobj import ConfigObj
    config = ConfigObj('settings.ini', unrepr=True)
    for x in config['report']:
        # do something... 
        print x
    

    However when it hits the config= it throws a raise error. I am kinda lost here. I even copied and pasted their example and same thing, "raise error". I am using python27 and have the configobj library installed.