A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir".

Overview
https://secure.travis-ci.org/ActiveState/appdirs.png

the problem

What directory should your app use for storing user data? If running on macOS, you should use:

~/Library/Application Support/<AppName>

If on Windows (at least English Win XP) that should be:

C:\Documents and Settings\<User>\Application Data\Local Settings\<AppAuthor>\<AppName>

or possibly:

C:\Documents and Settings\<User>\Application Data\<AppAuthor>\<AppName>

for roaming profiles but that is another story.

On Linux (and other Unices) the dir, according to the XDG spec, is:

~/.local/share/<AppName>

appdirs to the rescue

This kind of thing is what the appdirs module is for. appdirs will help you choose an appropriate:

  • user data dir (user_data_dir)
  • user config dir (user_config_dir)
  • user cache dir (user_cache_dir)
  • site data dir (site_data_dir)
  • site config dir (site_config_dir)
  • user log dir (user_log_dir)

and also:

  • is a single module so other Python packages can include their own private copy
  • is slightly opinionated on the directory names used. Look for "OPINION" in documentation and code for when an opinion is being applied.

some example output

On macOS:

>>> from appdirs import *
>>> appname = "SuperApp"
>>> appauthor = "Acme"
>>> user_data_dir(appname, appauthor)
'/Users/trentm/Library/Application Support/SuperApp'
>>> site_data_dir(appname, appauthor)
'/Library/Application Support/SuperApp'
>>> user_cache_dir(appname, appauthor)
'/Users/trentm/Library/Caches/SuperApp'
>>> user_log_dir(appname, appauthor)
'/Users/trentm/Library/Logs/SuperApp'

On Windows 7:

>>> from appdirs import *
>>> appname = "SuperApp"
>>> appauthor = "Acme"
>>> user_data_dir(appname, appauthor)
'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp'
>>> user_data_dir(appname, appauthor, roaming=True)
'C:\\Users\\trentm\\AppData\\Roaming\\Acme\\SuperApp'
>>> user_cache_dir(appname, appauthor)
'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Cache'
>>> user_log_dir(appname, appauthor)
'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Logs'

On Linux:

>>> from appdirs import *
>>> appname = "SuperApp"
>>> appauthor = "Acme"
>>> user_data_dir(appname, appauthor)
'/home/trentm/.local/share/SuperApp
>>> site_data_dir(appname, appauthor)
'/usr/local/share/SuperApp'
>>> site_data_dir(appname, appauthor, multipath=True)
'/usr/local/share/SuperApp:/usr/share/SuperApp'
>>> user_cache_dir(appname, appauthor)
'/home/trentm/.cache/SuperApp'
>>> user_log_dir(appname, appauthor)
'/home/trentm/.cache/SuperApp/log'
>>> user_config_dir(appname)
'/home/trentm/.config/SuperApp'
>>> site_config_dir(appname)
'/etc/xdg/SuperApp'
>>> os.environ['XDG_CONFIG_DIRS'] = '/etc:/usr/local/etc'
>>> site_config_dir(appname, multipath=True)
'/etc/SuperApp:/usr/local/etc/SuperApp'

AppDirs for convenience

>>> from appdirs import AppDirs
>>> dirs = AppDirs("SuperApp", "Acme")
>>> dirs.user_data_dir
'/Users/trentm/Library/Application Support/SuperApp'
>>> dirs.site_data_dir
'/Library/Application Support/SuperApp'
>>> dirs.user_cache_dir
'/Users/trentm/Library/Caches/SuperApp'
>>> dirs.user_log_dir
'/Users/trentm/Library/Logs/SuperApp'

Per-version isolation

If you have multiple versions of your app in use that you want to be able to run side-by-side, then you may want version-isolation for these dirs:

>>> from appdirs import AppDirs
>>> dirs = AppDirs("SuperApp", "Acme", version="1.0")
>>> dirs.user_data_dir
'/Users/trentm/Library/Application Support/SuperApp/1.0'
>>> dirs.site_data_dir
'/Library/Application Support/SuperApp/1.0'
>>> dirs.user_cache_dir
'/Users/trentm/Library/Caches/SuperApp/1.0'
>>> dirs.user_log_dir
'/Users/trentm/Library/Logs/SuperApp/1.0'
Comments
  • Running into issues with appdirs 1.4.1

    Running into issues with appdirs 1.4.1

    Running into issues with appdirs 1.4.1, which appears to have been released today. Am getting the issue below. More details can be found in this log. Issues exist for other Python versions as well.

    FileNotFoundError: [Errno 2] No such file or directory: '/home/travis/virtualenv/python3.6.0/lib/python3.6/site-packages/appdirs-1.4.1.dist-info/METADATA'
    

    cc @alimanfoo

    opened by jakirkham 23
  • Linux fixes

    Linux fixes

    Fixes Issue #16 Bumps version to 1.3.0 Removes gratuitous case mangling on the case-sensitive Linux, since that's not wise Fixes the uterly wrong behaviour in site_data_dir, return result based on XDG_DATA_DIRS and make room for respecting the standard which specifies XDG_DATA_DIRS is a multiple-value variable Add *_config_dir which are distinct on nix-es, according to XDG specs; on Windows and Mac return the corresponding *_data_dir (Fixes Issue #6)

    opened by eddyp 20
  • write tests

    write tests

    test_api.py only tests the type of the return values. we need tests to cover the behaviour of appdirs functions (i.e., return values) on each platform.

    test 
    opened by srid 18
  • Remove unnecessary use of pywin32 for loading Windows folder

    Remove unnecessary use of pywin32 for loading Windows folder

    Another attempt at https://github.com/ActiveState/appdirs/pull/118 cc @pradyunsg

    Closes https://github.com/ActiveState/appdirs/pull/107 (I ran into something similar) Closes https://github.com/ActiveState/appdirs/issues/108

    It's unclear who's maintaining this so cc @zoofood @daved @rawktron @MDrakos @Naatan @autarch @jdufresne

    Could we also get a release? I saw https://github.com/ActiveState/appdirs/issues/79, indicating this library may not be getting the love it deserves. That is quite unfortunate since many projects rely on appdirs:

    ofek@ozone ~\Desktop $ pypinfo --days 365 appdirs
    Served from cache: False
    Data processed: 638.08 GiB
    Data billed: 638.08 GiB
    Estimated cost: $3.12
    
    | download_count |
    | -------------- |
    |     39,354,264 |
    
    opened by ofek 17
  • App name is duplicated on Windows if author name is missing or None

    App name is duplicated on Windows if author name is missing or None

    • Python version: 3.9
    • appdirs version: 1.4.4

    Linux:

    >>> appdirs.user_data_dir('foo')
    '/home/user/.local/share/foo'
    

    Windows:

    >>> appdirs.user_data_dir('foo')
    'C:\\Users\\user\\AppData\\Local\\foo\\foo'
    

    Specifying an empty string as second argument works to avoid this issue.

    opened by 0xallie 6
  • Invalid e-mail in maintainers

    Invalid e-mail in maintainers

    The e-mail address [email protected] as indicated in maintainers points to a non-existent domain.

    $ dig srid.name                                                                                                                                           
    
    ; <<>> DiG 9.10.6 <<>> srid.name
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 46493
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ;; QUESTION SECTION:
    ;srid.name.                     IN      A
    
    ;; Query time: 71 msec
    ;; SERVER: 192.168.162.1#53(192.168.162.1)
    ;; WHEN: Sun Mar 29 09:49:05 EDT 2020
    ;; MSG SIZE  rcvd: 38
    
    opened by jaraco 5
  • python setup.py nosetests fails with gusto

    python setup.py nosetests fails with gusto

    wycliff:appdirs-1.2.0 $ python setup.py nosetests
    running nosetests
    running egg_info
    writing lib/appdirs.egg-info/PKG-INFO
    writing top-level names to lib/appdirs.egg-info/top_level.txt
    writing dependency_links to lib/appdirs.egg-info/dependency_links.txt
    reading manifest file 'lib/appdirs.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    writing manifest file 'lib/appdirs.egg-info/SOURCES.txt'
    running build_ext
    E.EEEEEEE
    ======================================================================
    ERROR: test_api (test_appdirs.DocTestsTestCase)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/home/matej/build/BUILD/appdirs-1.2.0/test/test_appdirs.py", line 18, in test_api
        test = doctest.DocFileTest("api.doctests")
      File "/usr/lib64/python2.7/doctest.py", line 2424, in DocFileTest
        doc, path = _load_testfile(path, package, module_relative)
      File "/usr/lib64/python2.7/doctest.py", line 219, in _load_testfile
        with open(filename) as f:
    IOError: [Errno 2] No such file or directory: '/home/matej/build/BUILD/appdirs-1.2.0/test/api.doctests'
    
    ======================================================================
    ERROR: Failure: TypeError (testmod_paths_from_testdir() takes exactly 1 argument (0 given))
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/nose/loader.py", line 231, in generate
        for test in g():
    TypeError: testmod_paths_from_testdir() takes exactly 1 argument (0 given)
    
    ======================================================================
    ERROR: Failure: TypeError (testmods_from_testdir() takes exactly 1 argument (0 given))
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/nose/loader.py", line 231, in generate
        for test in g():
    TypeError: testmods_from_testdir() takes exactly 1 argument (0 given)
    
    ======================================================================
    ERROR: Failure: TypeError (testcases_from_testmod() takes exactly 1 argument (0 given))
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/nose/loader.py", line 231, in generate
        for test in g():
    TypeError: testcases_from_testmod() takes exactly 1 argument (0 given)
    
    ======================================================================
    ERROR: Failure: TypeError (tests_from_manifest() takes exactly 1 argument (0 given))
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/nose/loader.py", line 231, in generate
        for test in g():
    TypeError: tests_from_manifest() takes exactly 1 argument (0 given)
    
    ======================================================================
    ERROR: Failure: TypeError (tests_from_manifest_and_tags() takes exactly 2 arguments (0 given))
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/nose/loader.py", line 231, in generate
        for test in g():
    TypeError: tests_from_manifest_and_tags() takes exactly 2 arguments (0 given)
    
    ======================================================================
    ERROR: testlib.test
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
        self.test(*self.arg)
    TypeError: test() takes at least 1 argument (0 given)
    
    ======================================================================
    ERROR: testlib.list_tests
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
        self.test(*self.arg)
    TypeError: list_tests() takes exactly 2 arguments (0 given)
    
    ----------------------------------------------------------------------
    Ran 9 tests in 0.076s
    
    FAILED (errors=8)
    wycliff:appdirs-1.2.0 $ 
    
    test 
    opened by mcepl 5
  • Add os.environ fallback for Jython

    Add os.environ fallback for Jython

    This is a proposed fix for issue #154

    Provides an additional fallback for Windows if ctypes, JNA, and winreg all fail.

    Tested and works as expected in Windows 10 with Jython 2.7.2. Also tested to verify prior behavior is unchanged against Jython 2.7.2 with JNA and CPython 3.8.5.

    This also will fix the downstream pip issue, where pip is currently broken in Jython with a standard Java install.

    opened by Kevin-McClusky 4
  • Explicitly decode appdirs.py as UTF-8

    Explicitly decode appdirs.py as UTF-8

    When setup.py reads appdirs.py without an encoding defined, it can sometimes fail having guessed the wrong encoding. For example:

    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc8 in position 129: ordinal not in range(128)
    

    Whereas the builtin open does not accept the encoding argument until 3.0, io.open supports encoding under all versions supported by appdirs.

    opened by neirbowj 4
  • Remove deprecated license_file from setup.cfg

    Remove deprecated license_file from setup.cfg

    Starting with wheel 0.32.0 (2018-09-29), the "license_file" option is deprecated.

    https://wheel.readthedocs.io/en/stable/news.html

    The wheel will continue to include LICENSE, it is now included automatically:

    https://wheel.readthedocs.io/en/stable/user_guide.html#including-license-files-in-the-generated-wheel-file

    opened by jdufresne 4
  • AIX support

    AIX support

    There is a fair amount of Python development on that platform that it is worth adding. Lower priority than other items in the queue, but want to make sure its here.

    opened by zoofood 4
  • Fix config paths on macOS

    Fix config paths on macOS

    It looks like the config dir should be ~/Library/Application Support.

    A few other projects as examples:

    • https://github.com/dirs-dev/dirs-rs/blob/999efde766ed370a60c58145711db728ae9c04e8/src/mac.rs#L8
    • https://github.com/adrg/xdg/blob/31e6a328d142d3b8ed43fda69c4f2b55e77d8e79/paths_darwin.go#L28
    • https://github.com/dirs-dev/directories-jvm/blob/917e954cf94442399409ea384e94d658b57682b6/src/main/java/dev/dirs/BaseDirectories.java#L268

    closes: #185

    opened by Serial-ATA 0
  • macOS `user_config_dir` goes against OS guidelines

    macOS `user_config_dir` goes against OS guidelines

    appdirs.user_config_dir() points to ~/Library/Preferences on macOS: https://github.com/ActiveState/appdirs/blob/193a2cbba58cce2542882fcedd0e49f6763672ed/appdirs.py#L186-L199

    This goes against OS guidelines:

    Preferences

    Contains the user’s preferences. You should never create files in this directory yourself. To get or set preference values, you should always use the NSUserDefaults class or an equivalent system-provided interface.

    src: https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html

    opened by probablykasper 0
  • Full check of win32com

    Full check of win32com

    Description

    There are cases when win32com.shell is available but import of shellcon or shell cause crashes. e.g. when pywin is compiled for different binary. In our case we use appdirs in multiple different pythons where we can't affect it's version.

    Changes

    Try import all needed parts for pywin getter instead of checking just import win32com.shell .

    opened by iLLiCiTiT 0
  • Branch names release vs. master

    Branch names release vs. master

    Description

    There are 2 branches but are incompatible and contain different code. PRs are into master but for pypi is used release. Also I would recommend to create main branch name instead of master.

    opened by iLLiCiTiT 0
  • feature: Support

    feature: Support "well known" user directories

    I haven't found a package that provides that functionality and I think that it might be a good use case to handle it here. All major OSes have some form of default user directories like:

    $HOME/Desktop
    $HOME/Documents
    $HOME/Downloads
    $HOME/Music
    $HOME/Pictures
    $HOME/Public
    $HOME/Videos
    

    The paths may also differ based on system language preferences, so the i18n needs to be handed as well.

    https://wiki.archlinux.org/title/XDG_user_directories https://support.apple.com/guide/mac-help/folders-that-come-with-your-mac-mchlp1143/mac

    opened by B3QL 1
Releases(1.4.4)
  • 1.4.4(May 11, 2020)

    [PR #92] Don't import appdirs from setup.py Project officially classified as Stable which is important for inclusion in other distros such as ActivePython.

    First of several incremental releases to catch up on maintenance.

    Source code(tar.gz)
    Source code(zip)
  • 1.4.3(Mar 7, 2017)

  • 1.4.2(Feb 24, 2017)

    [PR #84] Allow installing without setuptools [PR #86] Fix string delimiters in setup.py description Add Python 3.6 support

    Thanks to the all for helping with diagnosing/discussing the changes to setuptools and the PRs.

    Source code(tar.gz)
    Source code(zip)
  • 1.4.1(Feb 2, 2017)

Dragon Age: Origins toolset to extract/build .erf files, patch language-specific .dlg files, and view the contents of files in the ERF or GFF format

DAOTools This is a set of tools for Dragon Age: Origins modding. It can patch the text lines of .dlg files, extract and build an .erf file, and view t

null 8 Dec 6, 2022
Python Fstab Generator is a small Python script to write and generate /etc/fstab files based on yaml file on Unix-like systems.

PyFstab Generator PyFstab Generator is a small Python script to write and generate /etc/fstab files based on yaml file on Unix-like systems. NOTE : Th

Mahdi 2 Nov 9, 2021
Small Python script to generate a calendar (.ics) file from SIMASTER courses schedule.

simaster.ics Small Python script to generate a calendar (.ics) file from SIMASTER courses schedule. Usage Getting the events.json file from SIMASTER O

Faiz Jazadi 8 Nov 2, 2022
A simple library for temporary storage of small files

TemporaryStorage An simple library for temporary storage of small files. Navigation Install Usage In Python console As a standalone application List o

null 2 Apr 17, 2022
A platform independent file lock for Python

py-filelock This package contains a single module, which implements a platform independent file lock in Python, which provides a simple way of inter-p

Benedikt Schmitt 497 Jan 5, 2023
Python module that parse power builder file (PBD) and analyze code

PowerBuilder-decompile Python module that parse power builder file (PBD) and analyze code (Incomplete) this tool is composed of: pbd_dump.py <pbd file

Samy Sultan 8 Dec 15, 2022
A python module to parse text files with contains secret variables.

A python module to parse text files with contains secret variables.

null 0 Dec 5, 2022
shred - A cross-platform library for securely deleting files beyond recovery.

shred Help the project financially: Donate: https://smartlegion.github.io/donate/ Yandex Money: https://yoomoney.ru/to/4100115206129186 PayPal: https:

null 4 Sep 4, 2021
Simple, convenient and cross-platform file date changing library. 📝📅

Simple, convenient and cross-platform file date changing library.

kubinka0505 15 Dec 18, 2022
This is just a GUI that detects your file's real extension using the filetype module.

Real-file.extnsn This is just a GUI that detects your file's real extension using the filetype module. Requirements Python 3.4 and above filetype modu

null 1 Aug 8, 2021
A simple file module for creating, editing and saving files.

A simple file module for creating, editing and saving files.

null 1 Nov 25, 2021
Python's Filesystem abstraction layer

PyFilesystem2 Python's Filesystem abstraction layer. Documentation Wiki API Documentation GitHub Repository Blog Introduction Think of PyFilesystem's

pyFilesystem 1.8k Jan 2, 2023
A python wrapper for libmagic

python-magic python-magic is a Python interface to the libmagic file type identification library. libmagic identifies file types by checking their hea

Adam Hupp 2.3k Dec 29, 2022
An object-oriented approach to Python file/directory operations.

Unipath An object-oriented approach to file/directory operations Version: 1.1 Home page: https://github.com/mikeorr/Unipath Docs: https://github.com/m

Mike Orr 506 Dec 29, 2022
Python library and shell utilities to monitor filesystem events.

Watchdog Python API and shell utilities to monitor file system events. Works on 3.6+. If you want to use Python 2.6, you should stick with watchdog <

Yesudeep Mangalapilly 5.6k Jan 4, 2023
Better directory iterator and faster os.walk(), now in the Python 3.5 stdlib

scandir, a better directory iterator and faster os.walk() scandir() is a directory iteration function like os.listdir(), except that instead of return

Ben Hoyt 506 Dec 29, 2022
Simple Python File Manager

This script lets you automatically relocate files based on their extensions. Very useful from the downloads folder !

Aimé Risson 22 Dec 27, 2022
Python function to stream unzip all the files in a ZIP archive: without loading the entire ZIP file or any of its files into memory at once

Python function to stream unzip all the files in a ZIP archive: without loading the entire ZIP file or any of its files into memory at once

Department for International Trade 206 Jan 2, 2023
Vericopy - This Python script provides various usage modes for secure local file copying and hashing.

Vericopy This Python script provides various usage modes for secure local file copying and hashing. Hash data is captured and logged for paths before

null 15 Nov 5, 2022