Serialize INI configuration to python dictionary
August 30th, 2009 mysurface Posted in Developer, python | Hits: 220043 | 11 Comments »
A lots of configuration file is in the format of INI, if we manage to serialize INI configuration to python dictionary, we can write python scripts to analyse and generate back to INI files.
Below is the sample of INI configuration: config.ini
#
# GENERAL section contains generic configuration
#
[GENERAL]
IP=192.168.1.4
Port=2143
#
# LOG section contains logging settings
#
[LOG]
LogLevel=5
LogPath=/var/log
LogType=Info Trace Error Debug
I created few python function use to serialize the INI configuration into dictionary. But there are some assumption to make. Assume that the comment of INI is start with char ‘#’. python dictionary do not takes in comments, because comment is not configuration. But what if after I change the configurations in dictionary and want to serialize back to INI file with the original comments stayed in as well? Yes you can remain the comments with the set of python functions I wrote.
Lets look at what function I have.
grep (str_list,pattern,neg=False): is my internal function to filter element in string list (first param).
ParseConfig (name=None): put the INI config filename as param, dictionary object will be returned.
ConfigTemplate (name=None): The construct the INI structure in another dictionary, storing the Section Name as well as your comments.
ConfigWrite (template=[],config=[],filename=”"): This function is to serialize back the python dictionary back to INI file. First param takes in the template dictionary object, second takes in configuration dictionary object.
Lets us look at all functions definition as well as the examples: ParseConfig.py
#/usr/bin/env python
import sys,os,datetime,time,re,string
from StringIO import StringIO
GREP_NEGATIVE=True
def grep (str_list,pattern,neg=False):
"""grep() will return list of match case.
Param: str_list - must be a list of string, each element in list is a new line
can use .split('\n') to obtain list from mutiple line of string
Param: pattern - re pattern can be composed by re.compile()"""
sres=[] #empty list
for s in str_list:
r=re.search(pattern,s,re.VERBOSE)
if r and neg==False:
sres.append(s)
elif (not r) and neg==True:
sres.append(s)
return sres
def ParseConfig (name=None):
global GREP_NEGATIVE
""" Parsing config file to this function, will serialized to dictionary
@name = filename
@return = dictionary"""
configdict={}
loglist=[]
while True:
try:
f = open(name,"r")
except IOError:
print "Err ",name,"not exist"
return None
pass
else:
break
try:
for line in f:
#strip all the whitespaces and write all lines to list.
loglist.append(line.strip(string.whitespace))
finally:
f.close()
# filter out the comment
loglist=grep(loglist,"^\#",GREP_NEGATIVE)
# make a dictionary
xL=[] #current L
itemdict={}
for item in loglist:
L=grep([item],"^\[.*\]$") # section
if L:
xL=[L[0].lstrip("[").rstrip("]")]
itemdict={}
#print xL
else: # items?
if len(xL)>0:
if item:
#split index and values.
iL=item.split("=")
#replace all '\t' to " " in values
iL[1]=string.replace(iL[1],"\t"," ")
# split the values into list
iiL=iL[1].strip(string.whitespace).split(" ")
real_list=[]
for item in iiL:
# read each value in the list, if got something append to the real_list
if len(item.strip(string.whitespace)) is not 0:
real_list.append(item.strip(string.whitespace))
# create another dict into the section
itemdict[iL[0].strip(string.whitespace)]=real_list
configdict[xL[0]]=itemdict
return configdict
pass
def ConfigTemplate (name=None):
try:
f=open(name,"r")
except IOError:
return None
loglist=[]
try:
for line in f:
#strip all the whitespaces and write all lines to list.
theline = line.strip(string.whitespace)
loglist.append(theline)
finally:
f.close()
loglist=grep(loglist,"^\#|^\[")
if len(loglist) is 0:
loglist = None
return loglist
def ConfigWrite (template=[],config=[],filename=""):
global DebugDupConfigWrite
if len(template) is 0 or len(config) is 0 or filename is "":
return False
try:
f = open(filename,"w")
for line in template:
r=re.search("^\#",line,re.VERBOSE)
if r:
f.write(line + "\n")
j=re.search("^\[",line,re.VERBOSE)
if j:
f.write(line + "\n")
# get all section line up
section_name = line.strip(string.whitespace).lstrip("[").rstrip("]")
if config.has_key(section_name):
sec_dict = config[section_name]
#
element_list=[]
for element in sec_dict:
element_list.append(element)
element_list.sort()
for element in element_list:
# index = values....
#print element, sec_dict[element]
f.write(element + " = " + "\t".join(sec_dict[element]) + "\n")
f.write("\n")
else:
pass
#f.write("CAN'T FIND THE ELEMENTS in section[%s]! DATA CORRUPTED.\n" % section_name)
pass # end if j
pass # end for line
f.close()
return True
except:
return False
# sample calling
myDict = ParseConfig ("config.ini")
template = ConfigTemplate ("config.ini")
ConfigWrite(template,myDict,"test.ini")
print "COMPLETE DICTIONARY"
print myDict
print "ALL TAGS"
for c in myDict:
print " ",c
print ""
print "ALL ITEM IN 'GENERAL'"
for d in myDict["GENERAL"]:
print " ",d
print ""
print "ALL ITEM IN 'LOG'"
for d in myDict["LOG"]:
print " ",d
print ""
print "DIRECT ACCESS 'LOG's LOGTYPE'"
print myDict["LOG"]["LogType"]
print "SO, YOU CAN SEE THAT IS THE LIST, IT ITERATE the LIST"
for e in myDict["LOG"]["LogType"]:
print " ",e
print "DIRECT ACCESS 'LOG's LOGTYPE 2nd value'"
print "second value is ",myDict["LOG"]["LogType"][1]
I hope my example is straight forward for you to understand how to use it, wish you enjoy python scripting :)







September 14th, 2009 at 9:37 pm
Tech Blog Link Request – http://www.adamsinfo.com
Hi
For leveraging traffic from the internet, I have manually collected a list of quality blogs with whom I am interested in getting associated.
I liked your blog and i’m interested in having my blog’s text link in your blog roll.
Please let me know your interest in this association and then we can move towards next step.
Sincerely,
Webmaster
Adamsinfo.com
vibha@apnicsolutions.com
July 8th, 2010 at 10:37 pm
I just wanted to say thanks for providing an awesome site with straight up easily digestable Linux commands. This site has been an absolute godsend to me over the last few days. Moving from Windows to Linux environment was daunting but your site proved to be the only resource I actually needed in the end! Thanks so much guys, keep up the good work :)
Chris.
February 9th, 2011 at 8:11 am
Nice post. I study one thing more difficult on completely different blogs everyday. It will all the time be stimulating to read content material from other writers and apply somewhat something from their store. I’d desire to make use of some with the content material on my blog whether you don’t mind. Natually I’ll offer you a link on your internet blog. Thanks for sharing.
March 2nd, 2011 at 12:03 am
Pretty nice post. I just stumbled upon your blog and wanted to say that I have really enjoyed browsing your blog posts. In any case I’ll be subscribing to your feed and I hope you write again soon! cheap shirt wholesale
March 11th, 2011 at 11:36 pm
You´ve got a secret admirer would you please email me with subject
May 19th, 2011 at 2:35 am
I loved as much as you will receive carried out right here. The sketch is tasteful, your authored material stylish. nonetheless, you command get got an edginess over that you wish be delivering the following. unwell unquestionably come more formerly again as exactly the same nearly very often inside case you shield this hike.
July 20th, 2011 at 6:29 am
Good day! I could have sworn I’ve been to this website before but after browsing through some of the post I realized it’s new to me. Anyways, I’m definitely delighted I found it and I’ll be book-marking and checking back often!
September 16th, 2011 at 2:32 am
I undoubtedly did not realize that. Learnt something new today! Thanks for that.
December 11th, 2011 at 11:17 pm
I am impressed, I have to say. Really rarely do I see a blog that’s both educational and entertaining, and let me tell you, you have hit the nail on the head. Your blog is outstanding; the issue is something that not a lot of people are speaking intelligently about. I am very happy that I stumbled across this in my search for something relating to it.
January 31st, 2012 at 10:19 am
The sleeping fox catches no poultry
April 10th, 2013 at 12:01 pm
Please tell me it worked right? I dont desire to sumit it once more if i don’t have to! Either the blog glitced out or i am an idiot, the second selection doesnt surprise me lol. thanks for a excellent blog!