Little brown configgy things, with short stuffy assignments and great long sections. I don't know what all the fuss is about, I could tame one of those.
configtamer is a config file format, and accompanying Python parser.
configtamer is a powerful, flexible configuration file format. It's meant to be straightforward to write and clear to read, allowing complex configurations but making the simple ones simple.
A config file can be as simple as a list of key/values:
document_root: /var/www/htdocs
logs_dir: /var/log/foobar
access_log: {logs_dir}/access.log
error_log: {logs_dir}/error.log
And here is how it would be parsed:
>>> import configtamer
>>> config = configtamer.parse("example.config")
>>> config.document_root
'/var/www.htdocs'
>>> config.error_log
'/var/log/foobar/error.log
You can also use sections in your config file, and tell one section to fall back to another section's values:
production:
code_dir: /var/src/some_project
wsgi_dir: {code_dir}/app.wsgi
servers:
dbservers = db1, db2
webservers: web1,
web2,
web42,
development [default: production]:
code_dir: ~/code/some_project/
servers:
dbservers: devserver1
webservers: {dbservers}
>>> config = configtamer.parse("example.config")
>>> config.production.wsgi_dir
'/var/src/some_project/app.wsgi'
>>> config.development.wsgi_dir
'~/code/some_project//app.wsgi'
>>> config.production.dbservers
'db1, db2'
It's good to be able to apply some structure to the config file. But note that config.production.dbservers is returned as a string (as are all other values). You can tell configtamer that this was supposed to be a list, and it will behave correctly (even allowing trailling commas and whitespace):
>>> config.production.dbservers.as_list()
['db1', 'db2']
>>> config.production.webservers.as_list()
['web1', 'web2', 'web42']
You can use as_list
(and as_int
, as_bool
etc), but that can get
tiresome. It also doesn't give the person writing the configuration
a clue as to which type of value they whould use.
For that, configtamer lets you use an annotated example as specs:
production:
debug: True [optional, default=True]
code_dir: /path/to/code [path]
wsgi_dir: {code_dir}/app.wsgi [path]
instances = 2 [optional, int, default=1]
servers:
dbservers = db1, db2 [list]
webservers: web1,
web2,
web42, [list]
Given the specs above (which you can include in your software's documentation), here's how parsing would work:
>>> parser = configtamer.parser("example.specs")
>>> config = parser.parse("example.config")
>>> config.production.wsgi_dir
'/var/src/some_project/app.wsgi'
>>> config.development.wsgi_dir
'~/code/some_project/app.wsgi'
>>> config.production.dbservers
['db1', 'db2']
>>> config.production.webservers
['web1', 'web2', 'web42']
>>> config.development.instances
1
A few things are worth noting, here: accessing
config.production.dbservers
directly already treats the value as a
list. Also, had you noticed in the previous examples that
config.development.wsgi_dir
had a duplicated slash? configtamer now knows
that this is a path and fixes that. Finally,
config.development.instances
uses the default integer value set in
the specs, even though it wasn't specified anywhere in the
configuration.
Please look at the full documentation on... TODO :)
(It's coming, I promise! I haven't even settled on the name yet ;))
- Works on Python 2 (>= 2.7) and Python 3 (>= 3.3)
- Hierarchical key interpolation, using curly braces: {section.subsection.subsubsection.some_key}
- Configuration keys can be accessed as attributes or dict keys:
config.some_key == config['some_key']
- Annotated example files can be used as specification (for value type, optional and default values etc).
Of course! I got it at Harrods. And it lights up saying "Config Tamer" in great big neon letters.
ConfigParser is not hierarchical. "Intrinsic defaults" are defined in code (as a dict passed into the ConfigParser object), instead of separately, as a specification.
In ConfigParser you can't access options as attributes, and not even (in Python 2) as dict keys.
Hasn't been updated in nearly 4 years.
These are not really configuration formats, they are data description formats. You can use them for config, of course, but they are more verbose than necessary, and distract from the config itself.
Seriously?