LowEndBox - Cheap VPS, Hosting and Dedicated Server Deals

Config Files are Trivial: Python's configparser Module

Python LogoAs you can probably tell by this being the second Python article this weekend, I’ve been doing a bit of Python coding, both at work and at home.  It’s a pleasant language to work in, and one of Python’s big advantages is its “batteries included” philosophy.

In other languages, it’s very common to download and install add-on modules – e.g., Perl’s CPAN or PHP’s Pear, and of course GoLang is practically built from the ground-up to use Github.  With Python, there is certainly a robust add-on module community (see ‘pip’), but there’s also a ton of functionality included out of the box.  If you look at the history of scripting languages, Perl and TCL came with relatively sparse libraries.  After Python, many languages took a more expansive view of what should be shipped.

In today’s tutorial, we’re going to look at Python’s “configparser” module.  The beauty of this module is that you never need to hand-write configuration file parsing logic again.  Hopefully, you’re not writing very much now and are using YAML, JSON, or (shudder) XML or something like that.  If not, or if you want something simpler, you’ll love configparser.

configparser handles .ini files.  Let’s look at a sample one:

[server]
MaxFilesToProcess = 12
InputDir = /tmp/input
OutputDir = /tmp/output

[logging]
LogDir = /tmp/log
Debug = no

I’ve saved this as “leb.ini”.  In this configuration file, there are two “sections” (server and logging) and under each, several configuration items.

Let’s parse this beast!

#!/usr/bin/python3

import configparser
config = configparser.ConfigParser()
config.read('leb.ini')
for section in config.sections():
    print ("Found config section: %s" % (section))

wants_debug = config['logging'].getboolean("Debug")
if wants_debug:
    print ("this is debugging output")
else:
    print ("debugging is not turned on")
print ("I am processing a max of %d files from %s" % ( 
    config["server"].getint("MaxFilesToProcess"), 
    config ["server"]["InputDir"]))
if 'notify_address' in config['logging'].keys():
    print ("notifications are configured")
else:
    print ("notifications are not configured")

I’ve wrapped a couple long lines so they’re more easily readable here.

When run, this script produces this output:

# ./server.py 
Found config section: server
Found config section: logging
debugging is not turned on
I am processing a max of 12 files from /tmp/input
notifications are not configured

Let’s walk through the code.  First, we import configparser, create a ConfigParser object called config, and then tell it to read our leb.ini file.

config.sections() gives us the sections – “server” and “logging”.  In this case.  Note that in an .ini file, everything must be in a section.  You can’t have “naked” configuration items.  You can certainly have only one section if your config is simple, but you must have at least one.

Now we begin referencing these config items.  Note that they’re stored as strings, so if I reference config[“logging”][“Debug”] I’m going to get the string “no”, which is what I put in the .ini file.  What I’m really after is a boolean True or False.  To get that, I use the getboolean() method, which understands yes/no, on/off, true/false, and 1/0 correctly.

I also use getint() to get a configuration item as an integer (or getfloat() to get a float).  Of course, you could also do something like this:

int(config["server"]["MaxFilesToProcess"])

Python will raise a ValueError (as you might expect) if MaxFilesToProcess is not an int and you try either getint() or an int() cast.

Finally, how do we see if a configuration item exists?  Our config variable is just a dictionary, so we can use typical Python dict operations, such as testing if ‘notify_address’ is a key in config[‘logging’].keys().

 

 

 

No Comments

    Leave a Reply

    Some notes on commenting on LowEndBox:

    • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
    • Akismet is used for spam detection. Some comments may be held temporarily for manual approval.
    • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

    Your email address will not be published.