11

Simple case

I have a Python program that I intend to support on both *nix and Windows systems. The program must be configurable, at least globally. Is there a cross-platform way to address the configuration file?

I.e. I want to write instead of

import platform
if platform.system() == "Windows":
    configFilePath = "C:\MyProgram\mainconfig.ini"
else:
    configFilePath = "/etc/myprogram/mainconfig.ini"

something along the lines of

import configmagic
configFile = configmagic("myprogram", "mainconfig")


A slightly more advanced case

Can the same be applied to user-specific configuration? I.e. to keep the configuration in ~user/.myprogram/ under Unix, and in HKEY_LOCAL_USER registry section under Windows?

dpq
  • 9,028
  • 10
  • 49
  • 69
  • Possible dupe of http://stackoverflow.com/questions/200599/whats-the-best-way-to-store-simple-user-settings-in-python and http://stackoverflow.com/questions/965694/whats-the-official-way-of-storing-settings-for-python-programs – rubenvb Jul 12 '10 at 11:59
  • 1
    Thanks for the tip, but it's not really a dupe. Those two questions are about the format of the config file, while my question is about its location. – dpq Jul 12 '10 at 16:54
  • 1
    Don't use ~/.myprogram, use the XDG BaseDir Spec, which defines where you *should* be storing/reading your configurations. (by default, ~/.config/myprogram). – WhyNotHugo May 15 '12 at 03:59

3 Answers3

6

Python will allow forward-slash paths on Windows, and os.path.expanduser works on Windows also, so you can get a user-specific file path using:

config_file = os.path.expanduser("~/foo.ini")

if you want to find a .ini in the user's home directory. I'm not sure how to unify file-based .ini and registry settings.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • Great, and is there a way to solve the first case (global configuration file path)? – dpq Jul 12 '10 at 11:56
2

You may want to use dirspec. It works in GNU/Linux, Mac OS and Windows.

You can get it from: Launchpad

Or installing it from PyPI

pip install dirspec

and in your code use something like:

from dirspec.basedir import get_xdg_config_home
config_path = get_xdg_config_home()

It's used by Ubuntu One, look at this code example from their documentation: https://one.ubuntu.com/developer/data/u1db/tutorial#storing-and-retrieving-tasks

ivanalejandro0
  • 1,689
  • 13
  • 13
1

Current answers provide incomplete solution to your problems (cross-platform + user vs system-wide config).

confuse library answers your needs :

Combine configuration data from multiple sources. Using layering, Confuse allows user-specific configuration to seamlessly override system-wide configuration, which in turn overrides built-in defaults.
[...]
An in-package config_default.yaml can be used to provide bottom-layer defaults using the same syntax that users will see. A runtime overlay allows the program to programmatically override and add configuration values. Look for configuration files in platform-specific paths. Like $XDG_CONFIG_HOME or ~/.config on Unix; “Application Support” on macOS; %APPDATA% on Windows.

kraymer
  • 3,254
  • 1
  • 24
  • 32