Steven Hepting
Steven Hepting

Reputation: 12504

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

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?

Upvotes: 72

Views: 55302

Answers (14)

Ben L
Ben L

Reputation: 355

The accepted answer "settings.py" only takes care of "reading" config information. The information is stored by human (or other program) before the python program is running, and the information (usually) is loaded at the starting phase of the program.

But they can't handle the situation that during the program, the settings are changed, and the information need to store for future use.

An INI file, or a JSON file, or an XML file would be capable of reading from and writing into. ConfigParser can take care of INI files. JSON has many functions to perform the same tasks.

I would suggest to use JSON for it's popularity, versatility (easy to fit in different format of the settings).

Upvotes: 0

charls
charls

Reputation: 39

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'

Upvotes: 0

Cobry
Cobry

Reputation: 4548

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:\Users\Me\Desktop' "})

# 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')

Upvotes: 8

Natesh bhat
Natesh bhat

Reputation: 13257

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')) ;

Upvotes: 7

brianz
brianz

Reputation: 7448

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.

Upvotes: 32

dbader
dbader

Reputation: 10501

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.

Upvotes: 2

Zippo
Zippo

Reputation: 16440

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

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

Upvotes: 16

jhufford
jhufford

Reputation: 500

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.

Upvotes: 13

drdaeman
drdaeman

Reputation: 11489

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).

Upvotes: 21

Kamil Kisiel
Kamil Kisiel

Reputation: 20481

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.

Upvotes: 4

lprsd
lprsd

Reputation: 87205

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.

Upvotes: 41

Checksum
Checksum

Reputation: 3240

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.

Upvotes: 0

SilentGhost
SilentGhost

Reputation: 319949

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

Upvotes: 0

Shane C. Mason
Shane C. Mason

Reputation: 7615

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.

Upvotes: 6

Related Questions