geophysics/mtpy — pull request #15 by nietky (2012-10-15 06:34:04+00:00)
Title: Implement framework persistent configuration settings in INI files 

The changes on this branch are meant as a way to tackle all the hardcoded paths that are around. The idea is to basically have all settings that users might want to permanently change per project in an INI file. We really don't want users (including ourselves) changing the source directly for convenience, because then it's reversed every time you update the code.

Can you take a look at it, and let me know what you think of this approach? Should we do it this way? Do you understand my explanation?

So this is how my changes work:

The code that sets everything up is in [mtpy/config.py](https://github.com/geophysics/mtpy/blob/ki.config_framework/mtpy/config.py)

Settings are in one or more INI files. There is a 'master' INI file in the repository, at [mtpy/config/mtpy.ini](https://github.com/geophysics/mtpy/blob/ki.config_framework/mtpy/mtpy.ini). Users can place their own INI files in their $HOME directory, or in the current working directory. The two latter INI files need not have all the settings in them, because ``config.py`` will look at each one in turn, overwriting the settings it finds in the increasingly 'local' files. So the 'master' INI has the lowest priority, and the current working directory INI has the highest priority. It doesn't matter if there are no INI files in the $HOME directory or the working directory.

When config.py is imported it loads the INI file into a ``SafeConfigParser`` object, which is a bit like a dictionary, and makes it available as the ``config`` object in its module namespace. So to access this object from anywhere in ``mtpy`` code, use:

>>> from mtpy.config import config

Changes can't be made during an interpreter session. This might be modified later, but I thought we should just keep it simple for now. The ``config`` object is a bit like a dictionary, but not as nice. It has separate sections, which contain name/value pairs, but to get at the values you need to call the ``get(section, name)`` method. So for an INI file that looks like:

[BIRRP]
bbfile = Z:\instruments\bbconv.txt

to get at the settings:

>>> from mtpy.config import config
>>> config.get('BIRRP', 'bbfile')
'Z:\\instruments\\bbconv.txt'

This is awkward, but I think it is the best cross-platform way to do things. For example, in some module somewhere in ``mtpy`` you
would do the following:

import numpy as np
# other imports etc

from mtpy.config import config

def do_something(arg1, arg2, path_to_program=config.get('blah', 'blah_path')):
'''blah blah'''
pass

The module that this is based on (ConfigParser) is in the standard library. There are other and better choices for doing configuration, but none of them are standard library modules, and they're only slight improvements. I think we are better off sticking with an option that everyone has installed by default. More information about how ``SafeConfigParser`` objects work is here:

http://docs.python.org/library/configparser.html
http://www.doughellmann.com/PyMOTW/ConfigParser/#accessing-configuration-settings

For now, I haven't actually added any settings. I just wanted to propose this as a framework before going ahead and adding settings everywhere.

Also, a minor point, but if for some reason the ``mtpy.ini`` file in the source folder is missing or broken for some reason, ``config.py`` will try to download the latest version from Github.

So... does that make sense? Do you like it?