{"id":16646633,"url":"https://github.com/alexdelorenzo/app_paths","last_synced_at":"2025-04-09T16:08:09.682Z","repository":{"id":71775990,"uuid":"386102071","full_name":"alexdelorenzo/app_paths","owner":"alexdelorenzo","description":"📂 Like appdirs, but with pathlib, path creation and async support.","archived":false,"fork":false,"pushed_at":"2023-10-31T09:49:18.000Z","size":43,"stargazers_count":5,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-09T16:07:58.182Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://alexdelorenzo.dev","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexdelorenzo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["alexdelorenzo"]}},"created_at":"2021-07-14T23:26:51.000Z","updated_at":"2024-12-23T09:49:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"b3a2d54f-80ce-4df9-ace6-4e39a2433825","html_url":"https://github.com/alexdelorenzo/app_paths","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdelorenzo%2Fapp_paths","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdelorenzo%2Fapp_paths/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdelorenzo%2Fapp_paths/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdelorenzo%2Fapp_paths/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexdelorenzo","download_url":"https://codeload.github.com/alexdelorenzo/app_paths/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248065286,"owners_count":21041871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-12T08:42:41.087Z","updated_at":"2025-04-09T16:08:09.658Z","avatar_url":"https://github.com/alexdelorenzo.png","language":"Python","funding_links":["https://github.com/sponsors/alexdelorenzo","https://www.buymeacoffee.com/alexdelorenzo"],"categories":[],"sub_categories":[],"readme":"# Get and create paths for your app\n`app_paths` builds upon [`appdirs`](https://pypi.org/project/appdirs/) and automatically creates canonical file system paths for storing app and user data on Windows, macOS, Linux and *BSD.\n\nInstead of just strings, `app_paths` gives developers `Path` objects from [`pathlib`](https://docs.python.org/3/library/pathlib.html) or [`aiopath`](https://github.com/alexdelorenzo/aiopath), and it handles path creation efficiently. It also adds [async support](https://www.python.org/dev/peps/pep-0492/).\n\nThis project uses [`📁 aiopath`](https://github.com/alexdelorenzo/aiopath) as an async [`pathlib`](https://docs.python.org/3/library/pathlib.html) replacement.\n\n## Use case\nFirst, let's take a look at [`appdirs`](https://pypi.org/project/appdirs/):\n```python\nfrom pathlib import Path\nfrom appdirs import AppDirs\n\n\ndirs = AppDirs('app', 'My Name', '0.1.0')\n\n# appdirs will return uncreated paths as strings\nuser_data: str = dirs.user_data_dir\nassert isinstance(user_data, str)\n\nprint(user_data)  # '/home/user/.cache/app/0.1.0'\n```\n\n`appdirs` can generate paths as strings for an app. It does one thing, and it does that one thing well on multiple platforms.\n\n```python3\nuser_data_path = Path(user_data)\n\n# appdirs does not create paths\nassert not user_data_path.exists()\n```\n\nHowever, it's up to app developers to handle creating paths on users' file systems. It's also up to developers to decide how they want to manipulate those paths, using abstractions like [`os.path`](https://docs.python.org/3/library/os.path.html), [`pathlib`](https://docs.python.org/3/library/pathlib.html) or [`aiopath`](https://github.com/alexdelorenzo/aiopath). Developers also have to think about how to efficiently perform path creation.\n\n`app_paths` takes care of all of that for you.\n\n`app_paths` automatically gives you [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html) handles for your paths in synchronous apps, and [`aiopath.AsyncPath`](https://github.com/alexdelorenzo/aiopath) handles for async apps. \n\n```python3\nfrom app_paths import AppPaths\n\n\npaths = AppPaths.get_paths('app', 'My Name', '0.1.0')\n\n# app_paths can return paths\nuser_data: Path = paths.user_data_path\nassert isinstance(user_data, Path)\n\nprint(user_data)  # '/home/user/.cache/app/0.1.0'\n```\n\n`app_paths` can create paths on the file system dynamically, and it will cache results so excess I/O isn't performed.\n\n```python3\n# app_paths can return uncreated paths\nassert not user_data.exists()\n\n# but it can also dynamically create paths on the fly\nuser_data: Path = paths.user_data\nassert user_data.exists()\n```\n\nIt can do batch creation of app paths, and it will use efficient concurrent I/O in both synchronous and async Python programs.\n\n```python3\n# create user app paths concurrently\nawait paths.create_user()\n\n# to run the following you must have write access to all paths\n# create site app paths concurrently\nawait paths.create_site()\n\n# create user and site paths concurrently\nawait paths.create_all()\n```\n\nHere's how you can do the above asynchronously:\n```python3\nfrom app_paths import AsyncAppPaths\nfrom aiopath import AsyncPath\n\n\npaths = await AsyncAppPaths.get_paths('app', 'My Name', '0.1.0')\n\n# app_paths can return AsyncPaths\nuser_data: AsyncPath = paths.user_data_path\nassert isinstance(user_data, AsyncPath)\n\nprint(user_data)  # '/home/user/.cache/app/0.1.0'\n\n# app_paths can return uncreated paths\nassert not await user_data.exists()\n\n# but it can also dynamically create paths on the fly\nuser_data: AsyncPath = await paths.user_data\nassert await user_data.exists()\n\n# create user app paths concurrently\nawait paths.create_user()\n\n# to run the following you must have write access to all paths\n# create site app paths concurrently\nawait paths.create_site()\n\n# create user and site paths concurrently\nawait paths.create_all()\n```\n\n# Installation\n## Requirements\n - Windows, macOS or a POSIX compatible operating system\n - Python 3.8+\n\n## PyPI\n```bash\n$ python3 -m pip install app_paths\n```\n\n# Support\nWant to support this project and [other open-source projects](https://github.com/alexdelorenzo) like it?\n\n\u003ca href=\"https://www.buymeacoffee.com/alexdelorenzo\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" alt=\"Buy Me A Coffee\" height=\"60px\" style=\"height: 60px !important;width: 217px !important;max-width:25%\" \u003e\u003c/a\u003e\n\n# License\nSee `LICENSE`. If you'd like to use this project with a different license, please get in touch.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexdelorenzo%2Fapp_paths","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexdelorenzo%2Fapp_paths","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexdelorenzo%2Fapp_paths/lists"}