What's the official way of storing settings for Python programs?

Question:

Django uses real Python files for settings, Trac uses a .ini file, and some other pieces of software uses XML files to hold this information.

Are one of these approaches blessed by Guido and/or the Python community more than another?

Asked By: Steven Hepting

||

Answers:

I am not sure that there is an ‘official’ way (it is not mentioned in the Zen of Python 🙂 )- I tend to use the Config Parser module myself and I think that you will find that pretty common. I prefer that over the python file approach because you can write back to it and dynamically reload if you want.

Answered By: Shane C. Mason

why would Guido blessed something that is out of his scope? No there is nothing particular blessed.

Answered By: SilentGhost

It is more of convenience. There is no official way per say. But using XML files would make sense as they can be manipulated by various other applications/libraries.

Answered By: Checksum

Depends on the predominant intended audience.

If it is programmers who change the file anyway, just use python files like settings.py

If it is end users then, think about ini files.

Answered By: lprsd

It depends largely on how complicated your configuration is. If you’re doing a simple key-value mapping and you want the capability to edit the settings with a text editor, I think ConfigParser is the way to go.

If your settings are complicated and include lists and nested data structures, I’d use XML or JSON and create a configuration editor.

For really complicated things where the end user isn’t expected to change the settings much, or is more trusted, just create a set of Python classes and evaluate a Python script to get the configuration.

Answered By: Kamil Kisiel

Don’t know if this can be considered “official”, but it is in standard library: 14.2. ConfigParser — Configuration file parser.

This is, obviously, not an universal solution, though. Just use whatever feels most appropriate to the task, without any necessary complexity (and — especially — Turing-completeness! Think about automatic or GUI configurators).

Answered By: drdaeman

Just one more option, PyQt. Qt has a platform independent way of storing settings with the QSettings class. Underneath the hood, on windows it uses the registry and in linux it stores the settings in a hidden conf file. QSettings works very well and is pretty seemless.

Answered By: jhufford

As many have said, there is no “offical” way. There are, however, many choices. There was a talk at PyCon this year about many of the available options.

Answered By: brianz

I use a shelf ( http://docs.python.org/library/shelve.html ):

shelf = shelve.open(filename)
shelf["users"] = ["David", "Abraham"]
shelf.sync() # Save
Answered By: Zippo

For web applications I like using OS environment variables: os.environ.get('CONFIG_OPTION')

This works especially well for settings that vary between deploys. You can read more about the rationale behind using env vars here: http://www.12factor.net/config

Of course, this only works for read-only values because changes to the environment are usually not persistent. But if you don’t need write access they are a very good solution.

Answered By: dbader

There is no blessed solution as far as I know. There is no right or wrong way to storing app settings neither, xml, json or all types of files are fine as long as you are confortable with. For python I personally use pypref it’s very easy, cross platform and straightforward.

pypref is very useful as one can store static and dynamic settings and preferences …

from pypref import Preferences

#  create singleton preferences instance
pref = Preferences(filename="preferences_test.py")

# create preferences dict
pdict = {'preference 1': 1, 12345: 'I am a number'}

# set preferences. This would automatically create preferences_test.py 
# in your home directory. Go and check it.
pref.set_preferences(pdict)

# lets update the preferences. This would automatically update 
# preferences_test.py file, you can verify that. 
pref.update_preferences({'preference 1': 2})

# lets get some preferences. This would return the value of the preference if
# it is defined or default value if it is not.
print pref.get('preference 1')

# In some cases we must use raw strings. This is most likely needed when
# working with paths in a windows systems or when a preference includes
# especial characters. That's how to do it ...
pref.update_preferences({'my path': " r'C:UsersMeDesktop' "})

# Sometimes preferences to change dynamically or to be evaluated real time.
# This also can be done by using dynamic property. In this example password
# generator preference is set using uuid module. dynamic dictionary
# must include all modules name that must be imported upon evaluating
# a dynamic preference
pre = {'password generator': "str(uuid.uuid1())"}
dyn = {'password generator': ['uuid',]}
pref.update_preferences(preferences=pre, dynamic=dyn)

# lets pull 'password generator' preferences twice and notice how
# passwords are different at every pull
print pref.get('password generator')
print pref.get('password generator')

# those preferences can be accessed later. Let's simulate that by creating
# another preferences instances which will automatically detect the 
# existance of a preferences file and connect to it
newPref = Preferences(filename="preferences_test.py")

# let's print 'my path' preference
print newPref.get('my path')
Answered By: Cobry

One of the easiest ways which is use is using the json module.
Save the file in config.json with the details as shown below.

Saving data in the json file:

{

    "john"  : {
        "number" : "948075049" , 
        "password":"thisisit" 
    }    
}

Reading from json file:

import json

#open the config.json file 

with open('config.json') as f:
    mydata = json.load(f) ; 

#Now mydata is a python dictionary 

print("username is " , mydata.get('john').get('number') , " password is " , mydata.get('john').get('password')) ;
Answered By: Natesh bhat

Not an official one but this way works well for all my Python projects.

pip install python-settings

Docs here: https://github.com/charlsagente/python-settings

You need a settings.py file with all your defined constants like:

# settings.py

DATABASE_HOST = '10.0.0.1'

Then you need to either set an env variable (export SETTINGS_MODULE=settings) or manually calling the configure method:

# something_else.py

from python_settings import settings
from . import settings as my_local_settings

settings.configure(my_local_settings) # configure() receives a python module

The utility also supports Lazy initialization for heavy to load objects, so when you run your python project it loads faster since it only evaluates the settings variable when its needed

# settings.py

from python_settings import LazySetting
from my_awesome_library import HeavyInitializationClass # Heavy to initialize object

LAZY_INITIALIZATION = LazySetting(HeavyInitializationClass, "127.0.0.1:4222") 
# LazySetting(Class, *args, **kwargs)

Just configure once and now call your variables where is needed:

# my_awesome_file.py

from python_settings import settings 

print(settings.DATABASE_HOST) # Will print '10.0.0.1'
Answered By: charls
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.