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)

Search for files under the specified directory. Extract the file name and file path and import them as data.

Search for files under the specified directory. Extract the file name and file path and import them as data. Based on that, search for the file, select it and open it.

G-jon FujiYama 2 Jan 10, 2022
Extract an archive file (zip file or tar file) stored on AWS S3

S3 Extract Extract an archive file (zip file or tar file) stored on AWS S3. Details Downloads archive from S3 into memory, then extract and re-upload

Evan 1 Dec 14, 2021
A Certificate renaming tool made for IEEE CS SBC, SJCE.

PDF Batch Renamer Made for IEEE CS SBC, SJCE How to use? Before using the python script, ensure that pytesseract, pdf2image, opencv and other supporti

Ashwin Kumar U 2 Nov 14, 2021
Fast Python reader and editor for ASAM MDF / MF4 (Measurement Data Format) files

asammdf is a fast parser and editor for ASAM (Association for Standardization of Automation and Measuring Systems) MDF (Measurement Data Format) files

Daniel Hrisca 440 Dec 31, 2022
Object-oriented file system path manipulation

path (aka path pie, formerly path.py) implements path objects as first-class entities, allowing common operations on files to be invoked on those path

Jason R. Coombs 1k Dec 28, 2022
Organizer is a python program that organizes your downloads folder

Organizer Organizer is a python program that organizes your downloads folder, it can run as a service and so will start along with the system, and the

Gustavo 2 Oct 18, 2021
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
Organize the files into the relevant sub-folders

This program can be used to organize files in a directory by their file extension. And move duplicate files to a duplicates folder.

Thushara Thiwanka 2 Dec 15, 2021
Creates folders into a directory to categorize files in that directory by file extensions and move all things from sub-directories to current directory.

Categorize and Uncategorize Your Folders Table of Content TL;DR just take me to how to install. What are Extension Categorizer and Folder Dumper Insta

Furkan Baytekin 1 Oct 17, 2021
This program can help you to move and rename many files at once

This program can help you to rename and save many files in a folder in seconds, but don't give the same name to files, it can delete both files.

João Assalim 1 Oct 10, 2022
A JupyterLab extension that allows opening files and directories with external desktop applications.

A JupyterLab extension that allows opening files and directories with external desktop applications.

martinRenou 0 Oct 14, 2021
Annotate your Python requirements.txt file with summaries of each package.

Summarize Requirements 🐍 📜 Annotate your Python requirements.txt file with a short summary of each package. This tool: takes a Python requirements.t

Zeke Sikelianos 8 Apr 22, 2022
Object-oriented file system path manipulation

path (aka path pie, formerly path.py) implements path objects as first-class entities, allowing common operations on files to be invoked on those path

Jason R. Coombs 1k Dec 28, 2022
pydicom - Read, modify and write DICOM files with python code

pydicom is a pure Python package for working with DICOM files. It lets you read, modify and write DICOM data in an easy "pythonic" way.

DICOM in Python 1.5k Jan 04, 2023
Ini adalah program python untuk mengubah background foto dalam 1 folder, tidak perlu satu satu

Myherokuapp my web drive You can see my web drive and can request film/Application do you want in here my blog you can visit my blog RemBg ini adalah

XnuxersXploitXen 13 Dec 01, 2022
Some-tasks - Files for some of the tasks for the group sessions

Files for some of the tasks for the group sessions Here you can find some of the

<a href=[email protected] Computer Networks"> 0 Aug 25, 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
Pti-file-format - Reverse engineering the Polyend Tracker instrument file format

pti-file-format Reverse engineering the Polyend Tracker instrument file format.

Jaap Roes 14 Dec 30, 2022
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 function to construct a ZIP archive with on the fly - without having to store the entire ZIP in memory or disk

Python function to construct a ZIP archive with on the fly - without having to store the entire ZIP in memory or disk

Department for International Trade 34 Jan 05, 2023