0

I would like to read following config file having IPs defined for workers and managers. I tried configparser module but it requires key-value pairs. Anyone has any idea to read the below file using python, I would be thankful.

[managers]
1.2.3.4
[workers]
2.3.45.5
3.5.6.7
5.7.8.9

File may have random number of IPs.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Yogesh Jilhawar
  • 5,605
  • 8
  • 44
  • 59
  • `with open("path/to/your/file.ext") as f:` and then parse the file. It's quite easy to find out where a "section" begins, so it shouldn't take more than a few minutes to parse this into a dict. – bruno desthuilliers Jul 04 '18 at 10:57
  • you may wish to have a look at [configparser — Configuration file parser](https://docs.python.org/3/library/configparser.html). See also [Read all the contents in ini file into dictionary with Python](https://stackoverflow.com/questions/3220670/read-all-the-contents-in-ini-file-into-dictionary-with-python) – AcK Jul 04 '18 at 11:06
  • all these solutions are talking about key value pairs. however, I dont have any key value pair in my config file. If I understood your solution wrongly, please correct me. – Yogesh Jilhawar Jul 04 '18 at 11:23

3 Answers3

3

If you reformat your data file as follows, you can then use configparser module to parse it. You can install it by doing pip install configparser

Data file

[managers]
ip = 1.2.3.4
[workers]
ip = 2.3.45.5
     3.5.6.7
     5.7.8.9

Sample Usage

from configparser import ConfigParser
# from ConfigParser import ConfigParser # for python3 
data_file = 'tmp.txt'

config = ConfigParser()
config.read(data_file)

config.sections()
# ['managers', 'workers']

config['managers']['ip']
# '1.2.3.4'

config['workers']['ip']
#'2.3.45.5\n3.5.6.7\n5.7.8.9'

config['workers']['ip'].splitlines()
#['2.3.45.5', '3.5.6.7', '5.7.8.9']
Sunitha
  • 11,777
  • 2
  • 20
  • 23
  • ...Above solution is giving me errors like `AttributeError: instance has no attribute '__getitem__'`. I am using `python 2.7`. Do I need to add extra things in the above solution ?? – Yogesh Jilhawar Jul 04 '18 at 11:39
  • @YogeshJilhawar. Above code works fine for me on both python2.7 and python3. Can you try again by importing configparser as `from backports.configparser import ConfigParser` – Sunitha Jul 04 '18 at 11:51
  • @Sunitha..Yes its working for me too. Thanks for your kind help. – Yogesh Jilhawar Jul 04 '18 at 12:13
0

Using a simple iteration.

Demo:

res = {}
temp = []
with open(filename, "r") as infile:
    for line in infile:                      #Iterate over each line
        line = line.strip()
        if line.startswith("["):             #Check if line is header
            line = line.strip("[]")
            res[line] = []                   #Create Key
            temp.append(line)
        else:
            res[temp[-1]].append(line)        #Append Values.
print(res)

Output:

{'workers': ['2.3.45.5', '3.5.6.7', '5.7.8.9'], 'managers': ['1.2.3.4']}
Rakesh
  • 81,458
  • 17
  • 76
  • 113
0

An elegant way is using typed-settings and ipaddress.

  1. Install typed-settings: pip install typed-settings.
  2. Create a toml file named config.toml.
[managers]
ip = ["1.2.3.4"]

[workers]
ip = ["2.3.45.5", "3.5.6.7", "5.7.8.9"]
  1. Define the data model class and load it.
import ipaddress
import typed_settings as ts


@ts.settings(frozen=True)
class Mangers:
    ip = ts.option(converter=lambda l: [ipaddress.ip_address(i) for i in l])


@ts.settings(frozen=True)
class Workers:
    ip = ts.option(converter=lambda l: [ipaddress.ip_address(i) for i in l])


managers_settings = ts.load(Mangers, appname="managers", config_files=["config.toml"])
workers_settings = ts.load(Workers, appname="workers", config_files=["config.toml"])
print(managers_settings)
print(workers_settings)

# Mangers(ip=[IPv4Address('1.2.3.4')])
# Workers(ip=[IPv4Address('2.3.45.5'), IPv4Address('3.5.6.7'), IPv4Address('5.7.8.9')])