3

I'm trying to create a config that holds information such as username password etc.

I have created an ini file holding this:

[DEFAULT]
username: user
password: pass

I then have a config map class like:

import configparser

class ConfigSectionMap:
    def __init__(self):
        my_config_parser = configparser.ConfigParser()
        my_config_parser.read('inilocation')
        print(my_config_parser.default_section)

    def config_map(self, section):
        dict1 = {}
        options = self.my_config_parser.options(section)
        for option in options:
            try:
                dict1[option] = self.my_config_parser.get(section, option)
                if dict1[option] == -1:
                    print("skip: %s" % option)
            except:
                print("exception on %s!" % option)
                dict1[option] = None
        return dict1

In my main class where I want to use this I do:

from config_section_map import ConfigSectionMap

print(ConfigSectionMap.config_map(("DEFAULT")['password']))

when running this I receive an error:

TypeError: string indices must be integers

I've been following the docs but it's not working: https://wiki.python.org/moin/ConfigParserExamples

Or if there is an easier way please show me

edit:

changing to this

print(ConfigSectionMap.config_map("DEFAULT")['password']) 

shows

TypeError: config_map() missing 1 required positional argument: 'section'
Sam
  • 1,207
  • 4
  • 26
  • 50
  • Possible duplicate of [I need to securely store a username and password in Python, what are my options?](https://stackoverflow.com/questions/7014953/i-need-to-securely-store-a-username-and-password-in-python-what-are-my-options) – Don Kirkby Oct 28 '18 at 00:01

2 Answers2

3

You made an error calling config map. Config map takes a section, like "DEFAULT".

What you are trying is to send ('DEFAULT')['password']. But ('DEFAULT') evaluates to a string, and string indices can only take integers.

Trying to take an index to begin with is just an typing error you made.

There is a problem with how you are working with ConfigSectionMap. As it is now, you are working with attribute refrences, which is legal but not the expected way to work with config_map. config_map() expects two arguments (self, section) when doing a reference to config_map you are only passing one argument.

You either pass along self or you make an instance. By calling ConfigSectionMap() you will get an instance that have initiated the attributes inside self.

Change your code to the following instead, do you see the difference?

from config_section_map import ConfigSectionMap

conf_object = ConfigSectionMap()

print(conf_object.config_map("DEFAULT")['password'])

The ['password'] is now applied to the returned result from config_map instead of the argument to it.

To solve the problem options = self.my_config_parser.options(section) AttributeError: 'ConfigSectionMap' object has no attribute 'my_config_parser'

You have to define the attributes inside self, otherwise it will stay in that local scope of __init__

class ConfigSectionMap:
    def __init__(self):
        self.my_config_parser = configparser.ConfigParser()
        self.my_config_parser.read('inilocation')
        print(self.my_config_parser.default_section)

    def config_map(self, section):
        dict1 = {}
        options = self.my_config_parser.options(section)
        for option in options:
            try:
                dict1[option] = self.my_config_parser.get(section, option)
                if dict1[option] == -1:
                    print("skip: %s" % option)
            except:
                print("exception on %s!" % option)
                dict1[option] = None
        return dict1

As comment from @officialaimm pointed out, there might be a problem naming a section DEFAULT try change config to

[SomeThingElse]
username: user
password: pass

instead

David Bern
  • 778
  • 6
  • 16
  • thanks but I did try this before and got: print(ConfigSectionMap.config_map("DEFAULT")['password']) TypeError: config_map() missing 1 required positional argument: 'section' – Sam Mar 31 '17 at 09:36
  • aah. that is another problem. – David Bern Mar 31 '17 at 09:40
  • Answer updated. It is expected to get an self, something you get when working with an instance of that class – David Bern Mar 31 '17 at 09:45
  • Thanks alot forgot to instantiate it, but this isn't giving me the password, it's printing DEFAULT. Any idea why? – Sam Mar 31 '17 at 09:50
  • shows this now : options = self.my_config_parser.options(section) AttributeError: 'ConfigSectionMap' object has no attribute 'my_config_parser' – Sam Mar 31 '17 at 09:53
  • Nice thanks, there is an error though now it shows raise NoSectionError(section) from None configparser.NoSectionError: No section: 'DEFAULT' but prints DEFAULT. I don't get this – Sam Mar 31 '17 at 10:04
  • add a print on options self.my_config_parser.sections() If it doesnt show, you got another problem, probably not reading the file correctly – David Bern Mar 31 '17 at 10:08
  • 1
    Apparently, there is a problem with 'DEFAULT' header. Change the header in .ini file to SOMETHING ELSE(NOT DEFAULT) and pass same to the function config_map(). This worked for me, probably will work for you as well! – officialaimm Mar 31 '17 at 10:14
3

To give another answer the last part of your question Or if there is an easier way please show me

OPTION1 = 'test'

save it in config.py

in code

import config
getattr(config, 'OPTION1', 'default value if not found')
David Bern
  • 778
  • 6
  • 16