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)

BOOTH宛先印刷用CSVから色々な便利なリストを作成してCSVで出力するプログラムです。

BOOTH注文リスト作成スクリプト このPythonスクリプトは、BOOTHの「宛名印刷用CSV」から、 未発送の注文 今月の注文 特定期間の注文 を抽出した上で、各注文を商品毎に一覧化したCSVとして出力するスクリプトです。 簡単な使い方 ダウンロード 通常は、Relaseから、booth_ord

hinananoha 1 Nov 28, 2021
OnedataFS is a PyFilesystem interface to Onedata virtual file system

OnedataFS OnedataFS is a PyFilesystem interface to Onedata virtual file system. As a PyFilesystem concrete class, OnedataFS allows you to work with On

onedata 0 Jan 10, 2022
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
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
csv2ir is a script to convert ir .csv files to .ir files for the flipper.

csv2ir csv2ir is a script to convert ir .csv files to .ir files for the flipper. For a repo of .ir files, please see https://github.com/logickworkshop

Alex 38 Dec 31, 2022
An easy-to-use library for emulating code in minidump files.

dumpulator Note: This is a work-in-progress prototype, please treat it as such. An easy-to-use library for emulating code in minidump files. Example T

Duncan Ogilvie 362 Dec 31, 2022
A simple file module for creating, editing and saving files.

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

1 Nov 25, 2021
MHS2 Save file editing tools. Transfers save files between players, switch and pc version, encrypts and decrypts.

SaveTools MHS2 Save file editing tools. Transfers save files between players, switch and pc version, encrypts and decrypts. Credits Written by Asteris

31 Nov 17, 2022
A simple Python code that takes input from a csv file and makes it into a vcf file.

Contacts-Maker A simple Python code that takes input from a csv file and makes it into a vcf file. Imagine a college or a large community where each y

1 Feb 13, 2022
Singer is an open source standard for moving data between databases, web APIs, files, queues, and just about anything else you can think of.

Singer is an open source standard for moving data between databases, web APIs, files, queues, and just about anything else you can think of. Th

Singer 1.1k Jan 05, 2023
A bot discord that can create directories, file, rename, move, navigate throw directories etc....

File Manager Discord What is the purpose of this program ? This program is made for a Discord bot. Its purpose is to organize the messages sent in a c

1 Feb 02, 2022
Python virtual filesystem for SQLite to read from and write to S3

Python virtual filesystem for SQLite to read from and write to S3

Department for International Trade 70 Jan 04, 2023
A python script to convert an ucompressed Gnucash XML file to a text file for Ledger and hledger.

README 1 gnucash2ledger gnucash2ledger is a Python script based on the Github Gist by nonducor (nonducor/gcash2ledger.py). This Python script will tak

Thomas Freeman 0 Jan 28, 2022
A Python script to backup your favorite Discord gifs

About the project Discord recently felt like it would be a good idea to limit the favorites to 250, which made me lose most of my gifs... Luckily for

4 Aug 03, 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

1 Aug 08, 2021
Yadl - it is a simple library for working with both dotenv files and environment variables.

Yadl Yadl - it is a simple library for working with both dotenv files and environment variables. Features Validation of whitespaces. Validation of num

Ivan Kapranov 3 Oct 19, 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
CredSweeper is a tool to detect credentials in any directories or files.

CredSweeper is a tool to detect credentials in any directories or files. CredSweeper could help users to detect unwanted exposure of credentials (such as personal information, token, passwords, api k

Samsung 54 Dec 13, 2022
Various technical documentation, in electronically parseable format

a-pile-of-documentation Various technical documentation, in electronically parseable format. You will need Python 3 to run the scripts and programs in

Jonathan Campbell 2 Nov 20, 2022
ValveVMF - A python library to parse Valve's VMF files

ValveVMF ValveVMF is a Python library for parsing .vmf files for the Source Engi

pySourceSDK 2 Jan 02, 2022