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:

    [email protected] ~\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)

Swiss army knife for Apple's .tbd file manipulation

Description Inspired by tbdswizzler, this simple python tool for manipulating Apple's .tbd format. Installation python3 -m pip install --user -U pytbd

10 Aug 31, 2022
gitfs is a FUSE file system that fully integrates with git - Version controlled file system

gitfs is a FUSE file system that fully integrates with git. You can mount a remote repository's branch locally, and any subsequent changes made to the files will be automatically committed to the rem

Presslabs 2.3k Jan 08, 2023
Add Ranges and page numbers to IIIF Manifest from a CSV.

Add Ranges and page numbers to IIIF Manifest from CSV specific to a workflow of the Bibliotheca Hertziana.

Raffaele Viglianti 3 Apr 28, 2022
Python package to read and display segregated file names present in a directory based on type of the file

tpyfilestructure Python package to read and display segregated file names present in a directory based on type of the file. Installation You can insta

Tharun Kumar T 2 Nov 28, 2021
A wrapper for DVD file structure and ISO files.

vs-parsedvd DVDs were an error. A wrapper for DVD file structure and ISO files. You can find me in the IEW Discord server

7 Nov 17, 2022
A tiny Configuration File Parser for Python Projects

A tiny Configuration File Parser for Python Projects. Currently working on JSON Config Files only.

Tanmoy Sen Gupta 1 Feb 12, 2022
Maltego transforms to pivot between PE files based on their VirusTotal codeblocks

VirusTotal Codeblocks Maltego Transforms Introduction These Maltego transforms allow you to pivot between different PE files based on codeblocks they

Ariel Jungheit 18 Feb 03, 2022
FileGenerator - File Generator for sites that accepts documents

File Generator for sites that accepts documents This code generates files as per

Shaunak 2 Mar 19, 2022
An universal file format tool kit. At present will handle the ico format problem.

An universal file format tool kit. At present will handle the ico format problem.

Sadam·Sadik 1 Dec 26, 2021
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

8 Dec 06, 2022
Quick and dirty FAT12 filesystem to ZIP file converter

Quick and Dirty FAT12 Filesystem Converter This is a really crappy Python script I wrote to convert a semi-compatible FAT12 filesystem from my HP150's

Tube Time 2 Feb 12, 2022
Import Python modules from any file system path

pathimp Import Python modules from any file system path. Installation pip3 install pathimp Usage import pathimp

Danijar Hafner 2 Nov 29, 2021
Python file organizer application

Python file organizer application

Pak Maneth 1 Jun 21, 2022
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
LightCSV - This CSV reader is implemented in just pure Python.

LightCSV Simple light CSV reader This CSV reader is implemented in just pure Python. It allows to specify a separator, a quote char and column titles

Jose Rodriguez 6 Mar 05, 2022
OneDriveExplorer - A command line and GUI based application for reconstructing the folder strucure of OneDrive from the UserCid.dat file

OneDriveExplorer - A command line and GUI based application for reconstructing the folder strucure of OneDrive from the UserCid.dat file

Brian Maloney 100 Dec 13, 2022
A tool for batch processing large fasta files and accompanying metadata table to upload to repositories via API

Fasta Uploader A tool for batch processing large fasta files and accompanying metadata table to repositories via API The python fasta_uploader.py scri

Centre for Infectious Disease and One Health 1 Dec 09, 2021
A python script generate password files in plain text

KeePass (or any desktop pw manager?) Helper WARNING: This script will generate password files in plain text. ITS NOT SECURE. I needed help remembering

Eric Thomas 1 Nov 21, 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 02, 2022
A Python library that provides basic functions to read / write Aseprite format files

A Python library that provides basic functions to read / write Aseprite format files

Joe Trewin 1 Jan 13, 2022