Nathan
Nathan

Reputation: 525

Loading a config file from operation system independent place in python

under Linux I put my configs in "~/.programname". Where should I place it in windows? What would be the recommendated way of opening the config file OS independent in python?

Thanks! Nathan

Upvotes: 7

Views: 3787

Answers (5)

trin94
trin94

Reputation: 212

My approach when using Python's Pathlib library:

config = environ.get('APPDATA') or environ.get('XDG_CONFIG_HOME')
config = Path(config) if config else Path.home() / ".config"

Upvotes: 2

MestreLion
MestreLion

Reputation: 13686

Some improvements over LeadStorm's great answer:

Code can be simpler using os.environ.get() and short-circuiting or:

configpath = os.path.join(
    os.environ.get('APPDATA') or
    os.environ.get('XDG_CONFIG_HOME') or
    os.path.join(os.environ['HOME'], '.config'),
    "programname"
)

Additionally, if you're willing to use the external libraries, xdg package can make things even easier on Linux and Mac:

import xdg.BaseDirectory as xdg
configpath = os.path.join(os.environ.get('APPDATA') or xdg.xdg_config_home,
                          "programname")

But this only solves part of your problem: you still need to create that directory if it does not exists, right?

On Windows, you're on your own. But on Linux and Mac, xdg.save_config_path() do os.path.join() for you, and create the directory with appropriate permissions, if needed, and return its path, all in a single step. Awesome!

if 'APPDATA' in os.environ:
    configpath = os.path.join(os.environ['APPDATA'], "programname")
    os.makedirs(configpath, exist_ok=True)
else:
    configpath = xdg.save_config_path("programname")

Upvotes: 10

Eric Palakovich Carr
Eric Palakovich Carr

Reputation: 23308

Try:

os.path.expanduser('~/.programname')

On linux this will return:

>>> import os
>>> os.path.expanduser('~/.programname')
'/home/user/.programname'

On windows this will return:

>>> import os
>>> os.path.expanduser('~/.programname')
'C:\\Documents and Settings\\user/.programname'

Which is a little ugly, so you'll probably want to do this:

>>> import os
>>> os.path.join(os.path.expanduser('~'), '.programname')
'C:\\Documents and Settings\\user\\.programname'

EDIT: For what it's worth, the following apps on my Windows machine create their config folders in my Documents and Settings\user folder:

  • Android
  • AgroUML
  • Gimp
  • IPython

EDIT 2: Oh wow, I just noticed I put /user/.programname instead of /home/user/.programname for the linux example. Fixed.

Upvotes: 5

LeafStorm
LeafStorm

Reputation: 3127

On Windows, you store it in os.environ['APPDATA']. On Linux, however, it's now recommended to store config files in os.environ['XDG_CONFIG_HOME'], which defaults to ~/.config. So, for example, building on JAB's example:

if 'APPDATA' in os.environ:
    confighome = os.environ['APPDATA']
elif 'XDG_CONFIG_HOME' in os.environ:
    confighome = os.environ['XDG_CONFIG_HOME']
else:
    confighome = os.path.join(os.environ['HOME'], '.config')
configpath = os.path.join(confighome, 'programname')

The XDG base directory standard was created so that configuration could all be kept in one place without cluttering your home directory with dotfiles. Most new Linux apps support it.

Upvotes: 14

JAB
JAB

Reputation: 21079

Generally, configuration and data files for programs on Windows go in the %APPDATA% directory (or are supposed to), usually in a subdirectory with the name of the program. "%APPDATA%", of course, is just an environment variable that maps to the current user's Application Data folder. I don't know if it exists on Linux (though I assume it doesn't), so to do it across platforms (Windows/Linux/MacOS)...

import os

if 'APPDATA' in os.environ.keys():
   envar = 'APPDATA'
else:
   envar = 'HOME'

configpath = os.path.join(os.environ[envar], '.programname')

Upvotes: 0

Related Questions