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
A simple bulk file renamer, written in python.

Python File Editor A simple bulk file renamer, written in python. There are two functions, the bulk rename and the bulk file extention change. Bulk Fi

Sam Bloomfield 2 Dec 22, 2021
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
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
Python library for reading and writing tabular data via streams.

tabulator-py A library for reading and writing tabular data (csv/xls/json/etc). [Important Notice] We have released Frictionless Framework. This frame

Frictionless Data 231 Dec 09, 2022
Lumar - Smart File Creator

Lumar is a free tool for creating and managing files. With Lumar you can quickly create any type of file, add a file content and file size. With Lumar you can also find out if Photoshop or other imag

Paul - FloatDesign 3 Dec 10, 2021
Simple, convenient and cross-platform file date changing library. πŸ“πŸ“…

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

kubinka0505 15 Dec 18, 2022
Nmap XML output to CSV and HTTP/HTTPS URLS.

xml-to-csv-url Convert NMAP's XML output to CSV file and print URL addresses for HTTP/HTTPS ports. NOTE: OS Version Parsing is not working properly ye

1 Dec 21, 2021
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
Simple archive format designed for quickly reading some files without extracting the entire archive

Simple archive format designed for quickly reading some files without extracting the entire archive

Jarred Sumner 336 Dec 30, 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
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
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
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
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
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
Simple addon to create folder structures in blender.

BlenderCreateFolderStructure Simple Add-on to create a folder structure in Blender. Installation Download BlenderCreateFolderStructure.py Open Blender

Dominik Strasser 2 Feb 21, 2022
Publicly Open Amazon AWS S3 Bucket Viewer

S3Viewer Publicly open storage viewer (Amazon S3 Bucket, Azure Blob, FTP server, HTTP Index Of/) s3viewer is a free tool for security researchers that

Sharon Brizinov 377 Dec 02, 2022
Instant Fuzzy File Search for Alfred

List all the files inside a folder using fd, and instantly fuzzy-search through all of them using fzf, all from inside Alfred with a single keyword: fzf.

Mr. Pennyworth 37 Nov 30, 2022
A simple tool to find and replace all the matches of a regular expression in file(s).

FindREp A simple tool to find and replace all the matches of a regular expression in file(s). You can either select the file(s) directly or select a f

Biraj 5 Oct 18, 2022