As 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().
Related Posts:
- Merry Christmas from LowEndBox! - December 25, 2024
- We are Social Butterflies!Check Us Out Wherever You Browse, View, or Tap! - December 23, 2024
- Let’s Celebrate the Winter Solstice with Awesome Deals and a Free Bonus Code for RackNerd’s Giveaway! - December 22, 2024
Leave a Reply