I'd like a code snippet that gets the proper directory for app data (config files, etc) on all platforms (Win/Mac/Linux at least). For example: %APPDATA%/ on Windows.
If you don't mind using the appdirs module, it should solve your problem. (cost = you either need to install the module or include it directly in your Python application.)
Qt's QStandardPaths documentation lists paths like this.
Using Python 3.8
import sys
import pathlib
def get_datadir() -> pathlib.Path:
"""
Returns a parent directory path
where persistent application data can be stored.
# linux: ~/.local/share
# macOS: ~/Library/Application Support
# windows: C:/Users/<USER>/AppData/Roaming
"""
home = pathlib.Path.home()
if sys.platform == "win32":
return home / "AppData/Roaming"
elif sys.platform == "linux":
return home / ".local/share"
elif sys.platform == "darwin":
return home / "Library/Application Support"
# create your program's directory
my_datadir = get_datadir() / "program-name"
try:
my_datadir.mkdir(parents=True)
except FileExistsError:
pass
The Python documentation recommends the sys.platform.startswith('linux')
"idiom" for compatibility with older versions of Python that returned things like "linux2" or "linux3".
You can use the following function to get user data dir, tested in linux and w10 (returning AppData/Local
dir) it's adapted from the appdirs package:
import sys
from pathlib import Path
from os import getenv
def get_user_data_dir(appname: str) -> Path:
if sys.platform == "win32":
import winreg
key = winreg.OpenKey(
winreg.HKEY_CURRENT_USER,
r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders",
)
dir_, _ = winreg.QueryValueEx(key, "Local AppData")
ans = Path(dir_).resolve(strict=False)
elif sys.platform == "darwin":
ans = Path("~/Library/Application Support/").expanduser()
else:
ans = Path(getenv("XDG_DATA_HOME", "~/.local/share")).expanduser()
return ans.joinpath(appname)
I recommend researching the locations of 'appdata' in the operating systems that you want to use this program on. Once you know the locations you could simple use if statements to detect the os and do_something().
import sys
if sys.platform == "platform_value":
do_something()
elif sys.platform == "platform_value":
do_something()
- System: platform_value
- Linux (2.x and 3.x): 'linux2'
- Windows: 'win32'
- Windows/Cygwin: 'cygwin'
- Mac OS X: 'darwin'
- OS/2: 'os2'
- OS/2 EMX: 'os2emx'
- RiscOS: 'riscos'
- AtheOS: 'atheos'
List is from the official Python docs. (Search for 'sys.platform')
You can use module called appdata:
pip install appdata
from appdata import AppDataPaths
app_paths = AppDataPaths()
app_paths.app_data_path # cross-platform path to AppData folder
- Original question - How can I get the path to the %APPDATA% directory in Python?
- Original answer - https://mcmap.net/q/217189/-how-can-i-get-the-path-to-the-appdata-directory-in-python
appdata
package differ from appdirs
? –
Foucquet I came across a similar problem and I wanted to dynamically resolve all of the Windows % paths without knowing about them prior. You can use os.path.expandvars
to resolve the paths dynamically. Something like this:
from os import path
appdatapath = '%APPDATA%\MyApp'
if '%' in appdatapath:
appdatapath = path.expandvars(appdatapath)
print(appdatapath)
The line at the end will print: C:\Users\\{user}\AppData\Roaming\MyApp
This works for windows however I have not tested on Linux. So long as the paths are defined by the environment than expandvars should be able to find it. You can read more about expand vars here.
If you are after the config directory here is a solution that defaults to ~/.config
unless a platform specific (sys.platform
) entry is available in the method's local platforms: dict
from sys import platform
from os.path import expandvars, join
def platform_config_directory() -> str:
'''
Platform config directory
Entries available in local platforms dict use the current
"best practice" location for config directories.
Default: $HOME/.config (XDG Base Directory Specification)
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
'''
home: str = expandvars('$HOME')
platforms: dict = {
"win32": expandvars('%AppData%'),
"darwin": join(home, 'Library', 'Application Support'),
}
if platform in platforms:
return platforms[platform]
return join(home, '.config')
This works on windows, mac and linux, however allows for easier expansion given the need.
© 2022 - 2024 — McMap. All rights reserved.