How to Provide Simple and Clean Global Configuration Variables in Python with YAML
I really despise software that keeps its configuration in the syntax of the language in which the software is written - I’m looking at you, Drupal. Users should not need to know PHP, Python, or Ruby in order to customize settings. That’s why storing settings as YAML is vastly superior since it’s easy for humans to parse at a casual glance. So, what’s the best and most Pythonic way to provide settings globally across a project?
In Python projects, I always ran into a messy problem when trying to share keys and values from YAML across different modules.
An example settings.yaml
:
jenkins:
host: http://jenkins.example.com
user: donny
token: I@m7h3W4lrU$
db:
host: http://mysql.example.com
user: lebowski
repo: /path/to/directory
require:
- ldap
- php
- zip
Together with that YAML dictionary, my first attempt ended up looking something like:
config = os.path.join(os.path.dirname(__file__), "settings.yaml")
with open(config, "r") as f:
settings = yaml.load(f)
some_function(name="foo", expire=False, config=settings)
some_other_function(depth=2, path=settings["repo"], pkg=settings["require"]["ldap"])
So each time some function needed some values from settings, I ended up passing either multiple arguments or the entire dictionary. This added extra arguments to every function in my code and it was quite ugly. Let’s keep it simple. So, I came up with a much, much cleaner and more Pythonic solution that retains the simplicity of YAML while also honoring The Zen of Python.
Create a file named config.py
and place in it:
#!/usr/bin/env python
import yaml
with open("settings.yaml", "r") as f:
settings = yaml.load(f)
Now, everywhere else in your project you can simply import settings like:
from config import settings
That’s it - now your settings can be used anywhere without passing it around as an extra argument.
comments powered by Disqus