{"id":32116838,"url":"https://github.com/justindujardin/pathy","last_synced_at":"2025-10-20T16:14:50.473Z","repository":{"id":37039804,"uuid":"246688886","full_name":"justindujardin/pathy","owner":"justindujardin","description":"simple, flexible, offline capable, cloud storage with a Python path-like interface","archived":false,"fork":false,"pushed_at":"2025-04-29T17:25:12.000Z","size":803,"stargazers_count":174,"open_issues_count":8,"forks_count":22,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-14T09:24:20.026Z","etag":null,"topics":["azure","blobs","bucket-apis","bucket-storage-providers","gcs","pathy","s3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/justindujardin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"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,"zenodo":null}},"created_at":"2020-03-11T22:04:23.000Z","updated_at":"2025-07-04T13:11:26.000Z","dependencies_parsed_at":"2023-01-25T01:15:49.117Z","dependency_job_id":"f62228eb-4c69-49b2-b302-47a544ea0b52","html_url":"https://github.com/justindujardin/pathy","commit_stats":{"total_commits":273,"total_committers":7,"mean_commits":39.0,"dds":0.315018315018315,"last_synced_commit":"b39b49206518f7e51490d69a240236c40261aadd"},"previous_names":["justindujardin/gcspath"],"tags_count":46,"template":false,"template_full_name":null,"purl":"pkg:github/justindujardin/pathy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justindujardin%2Fpathy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justindujardin%2Fpathy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justindujardin%2Fpathy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justindujardin%2Fpathy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/justindujardin","download_url":"https://codeload.github.com/justindujardin/pathy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justindujardin%2Fpathy/sbom","scorecard":{"id":543921,"data":{"date":"2025-08-11","repo":{"name":"github.com/justindujardin/pathy","commit":"e95d7c5866ff2c673c859a2d019dd53334c161a9"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.8,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/23 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/python-package.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-package.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/justindujardin/pathy/python-package.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-package.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/justindujardin/pathy/python-package.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-package.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/justindujardin/pathy/python-package.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-package.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/justindujardin/pathy/python-package.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/python-package.yml:58: update your workflow using https://app.stepsecurity.io/secureworkflow/justindujardin/pathy/python-package.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-package.yml:73: update your workflow using https://app.stepsecurity.io/secureworkflow/justindujardin/pathy/python-package.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-package.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/justindujardin/pathy/python-package.yml/master?enable=pin","Warn: pipCommand not pinned by hash: tools/codecov.sh:4","Warn: npmCommand not pinned by hash: tools/deploy.sh:6","Warn: pipCommand not pinned by hash: tools/deploy.sh:15","Warn: pipCommand not pinned by hash: tools/deploy.sh:25","Warn: pipCommand not pinned by hash: tools/deploy.sh:26","Warn: npmCommand not pinned by hash: tools/lint.sh:11","Warn: pipCommand not pinned by hash: tools/setup.sh:7","Warn: pipCommand not pinned by hash: tools/setup.sh:13","Warn: pipCommand not pinned by hash: tools/setup.sh:15","Warn: pipCommand not pinned by hash: tools/setup.sh:16","Warn: pipCommand not pinned by hash: tools/test_package.sh:7","Warn: pipCommand not pinned by hash: tools/test_package.sh:13","Warn: pipCommand not pinned by hash: tools/test_package.sh:18","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of  11 pipCommand dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 17 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"12 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: PYSEC-2024-48 / GHSA-fj7x-q9j7-g6q6"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T08:56:56.553Z","repository_id":37039804,"created_at":"2025-08-20T08:56:56.553Z","updated_at":"2025-08-20T08:56:56.553Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280119948,"owners_count":26275597,"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","status":"online","status_checked_at":"2025-10-20T02:00:06.978Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["azure","blobs","bucket-apis","bucket-storage-providers","gcs","pathy","s3"],"created_at":"2025-10-20T16:14:48.743Z","updated_at":"2025-10-20T16:14:50.461Z","avatar_url":"https://github.com/justindujardin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pathy\n\n[![Build](https://github.com/justindujardin/pathy/actions/workflows/python-package.yml/badge.svg)](https://github.com/justindujardin/pathy/actions/workflows/python-package.yml)\n[![codecov](https://codecov.io/gh/justindujardin/pathy/branch/master/graph/badge.svg)](https://codecov.io/gh/justindujardin/pathy)\n[![Pypi version](https://badgen.net/pypi/v/pathy)](https://pypi.org/project/pathy/)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n\nPathy is a practical Python package with type annotations tailored for managing Cloud Bucket storage through a Path-like interface. It has an intuitive API and supports your [favorite](#google-cloud-storage) [cloud](#azure) [providers](#amazon-s3), facilitating file transfers between local systems and remote buckets. Ideal for seasoned developers, Pathy enables smooth [local file system work](#use_fs) during development, transitioning effortlessly to live APIs for deployment. It also simplifies converting bucket [blobs into local files](#to_local), offering an option for local file caching, and has a familiar CLI interface `pathy`.\n\n## 💾 Installation\n\nYou can install `pathy` from pip:\n\n| Features             |      Install Command       |\n| :------------------- | :------------------------: |\n| Google Cloud Storage |  `pip install pathy[gcs]`  |\n| Amazon S3            |  `pip install pathy[s3]`   |\n| Azure                | `pip install pathy[azure]` |\n\n## 🚀 Quickstart\n\nHere's a quick run-down of how to get started offline if you intend to use Google Cloud Storage buckets when you ship.\n\n```python\nfrom pathy import Pathy, use_fs\n\n# Use the local file-system for quicker development\nuse_fs()\n\n# Create a bucket\nPathy(\"gs://my_bucket\").mkdir(exist_ok=True)\n\n# An excellent blob\ngreeting = Pathy(f\"gs://my_bucket/greeting.txt\")\n\n# But it doesn't exist yet\nassert not greeting.exists()\n\n# Create it by writing some text\ngreeting.write_text(\"Hello World!\")\n\n# Now it exists\nassert greeting.exists()\n\n# Delete it\ngreeting.unlink()\n\n# Now it doesn't\nassert not greeting.exists()\n```\n\n## 🔐 Setup Credentials\n\nFor most cloud operations, you'll need credentials. Here's how to configure your credentials based on the supported cloud providers.\n\n### Google Cloud Storage\n\nGoogle recommends using a JSON credentials file, which you can specify by path:\n\n```python\nfrom google.oauth2 import service_account\nfrom pathy import set_client_params\n\ncredentials = service_account.Credentials.from_service_account_file(\"./my-creds.json\")\nset_client_params(\"gs\", credentials=credentials)\n```\n\n### Amazon S3\n\nS3 uses a JSON credentials file, which you can specify by path:\n\n```python\nfrom pathy import set_client_params\n\nset_client_params(\"s3\", key_id=\"YOUR_ACCESS_KEY_ID\", key_secret=\"YOUR_ACCESS_SECRET\")\n```\n\n### Azure\n\nAzure blob storage can be passed a `connection_string`:\n\n```python\nfrom pathy import set_client_params\n\nset_client_params(\"azure\", connection_string=\"YOUR_CONNECTION_STRING\")\n```\n\nor a `BlobServiceClient` instance:\n\n```python\nfrom azure.storage.blob import BlobServiceClient\nfrom pathy import set_client_params\n\nservice: BlobServiceClient = BlobServiceClient.from_connection_string(\n    \"YOUR_CONNECTION_STRING\"\n)\nset_client_params(\"azure\", service=service)\n```\n\n## ♻️ Semantic Versioning\n\nBefore Pathy reaches v1.0 the project is not guaranteed to have a consistent API, which means that types and classes may move around or be removed. That said, we try to be predictable when it comes to breaking changes, so the project uses semantic versioning to help users avoid breakage.\n\nSpecifically, new releases increase the `patch` semver component for new features and fixes, and the `minor` component when there are breaking changes. If you don't know much about semver strings, they're usually formatted `{major}.{minor}.{patch}` so increasing the `patch` component means incrementing the last number.\n\nConsider a few examples:\n\n| From Version | To Version | Changes are Breaking |\n| :----------: | :--------: | :------------------: |\n|    0.2.0     |   0.2.1    |          No          |\n|    0.3.2     |   0.3.6    |          No          |\n|    0.3.1     |   0.3.17   |          No          |\n|    0.2.2     |   0.3.0    |         Yes          |\n\nIf you are concerned about breaking changes, you can pin the version in your requirements so that it does not go beyond the current semver `minor` component, for example if the current version was `0.11.0`:\n\n```\npathy\u003e=0.11.0,\u003c0.12.0\n```\n\n## 📖 API \n\n\u003c!-- NOTE: The below code is auto-generated. Update source files to change API documentation. --\u003e\n\u003c!-- AUTO_DOCZ_START --\u003e\n\n# Pathy\n\n```python\nPathy(self, paths)\n```\n\nSubclass of `PathBase` that works with bucket APIs.\n\n## exists\n\n```python\nPathy.exists(self: 'Pathy') -\u003e bool\n```\n\nReturns True if the path points to an existing bucket, blob, or prefix.\n\n## fluid\n\n```python\nPathy.fluid(\n    path_candidate: Union[str, Pathy, PathlibPathEx],\n) -\u003e Union[Pathy, PathlibPathEx]\n```\n\nInfer either a Pathy or pathlib.Path from an input path or string.\n\nThe returned type is a union of the potential `FluidPath` types and will\ntype-check correctly against the minimum overlapping APIs of all the input\ntypes.\n\nIf you need to use specific implementation details of a type, \"narrow\" the\nreturn of this function to the desired type, e.g.\n\n```python\nfrom pathlib import Path\nfrom pathy import FluidPath, Pathy\n\nfluid_path: FluidPath = Pathy.fluid(\"gs://my_bucket/foo.txt\")\n# Narrow the type to a specific class\nassert isinstance(fluid_path, Pathy), \"must be Pathy\"\n# Use a member specific to that class\nassert fluid_path.prefix == \"foo.txt/\"\n\n# Or use a file-system path\nposix_path: FluidPath = Pathy.fluid(\"/tmp/foo.txt\")\nassert isinstance(posix_path, Path), \"must be pathlib.Path\"\n```\n\n## from_bucket\n\n```python\nPathy.from_bucket(bucket_name: str, scheme: str = 'gs') -\u003e 'Pathy'\n```\n\nInitialize a Pathy from a bucket name. This helper adds a trailing slash and\nthe appropriate prefix.\n\n```python\nfrom pathy import Pathy\n\nassert str(Pathy.from_bucket(\"one\")) == \"gs://one/\"\nassert str(Pathy.from_bucket(\"two\")) == \"gs://two/\"\n```\n\n## glob\n\n```python\nPathy.glob(\n    self: 'Pathy',\n    pattern: str,\n    case_sensitive: Optional[bool] = None,\n    follow_symlinks: Optional[bool] = None,\n) -\u003e Generator[Pathy, NoneType, NoneType]\n```\n\nPerform a glob match relative to this Pathy instance, yielding all matched\nblobs.\n\n## is_dir\n\n```python\nPathy.is_dir(self: 'Pathy', follow_symlinks: bool = True) -\u003e bool\n```\n\nDetermine if the path points to a bucket or a prefix of a given blob\nin the bucket.\n\nReturns True if the path points to a bucket or a blob prefix.\nReturns False if it points to a blob or the path doesn't exist.\n\n## is_file\n\n```python\nPathy.is_file(self: 'Pathy', follow_symlinks: bool = True) -\u003e bool\n```\n\nDetermine if the path points to a blob in the bucket.\n\nReturns True if the path points to a blob.\nReturns False if it points to a bucket or blob prefix, or if the path doesn’t\nexist.\n\n## ls\n\n```python\nPathy.ls(self: 'Pathy') -\u003e Generator[BlobStat, NoneType, NoneType]\n```\n\nList blob names with stat information under the given path.\n\nThis is considerably faster than using iterdir if you also need\nthe stat information for the enumerated blobs.\n\nYields BlobStat objects for each found blob.\n\n## mkdir\n\n```python\nPathy.mkdir(\n    self,\n    mode: int = 511,\n    parents: bool = False,\n    exist_ok: bool = False,\n) -\u003e None\n```\n\nCreate a bucket from the given path. Since bucket APIs only have implicit\nfolder structures (determined by the existence of a blob with an overlapping\nprefix) this does nothing other than create buckets.\n\nIf parents is False, the bucket will only be created if the path points to\nexactly the bucket and nothing else. If parents is true the bucket will be\ncreated even if the path points to a specific blob.\n\nThe mode param is ignored.\n\nRaises FileExistsError if exist_ok is false and the bucket already exists.\n\n## open\n\n```python\nPathy.open(\n    self: 'Pathy',\n    mode: str = 'r',\n    buffering: int = 8192,\n    encoding: Optional[str] = None,\n    errors: Optional[str] = None,\n    newline: Optional[str] = None,\n) -\u003e IO[Any]\n```\n\nOpen the given blob for streaming. This delegates to the `smart_open`\nlibrary that handles large file streaming for a number of bucket API\nproviders.\n\n## owner\n\n```python\nPathy.owner(self: 'Pathy') -\u003e Optional[str]\n```\n\nReturns the name of the user that owns the bucket or blob\nthis path points to. Returns None if the owner is unknown or\nnot supported by the bucket API provider.\n\n## rename\n\n```python\nPathy.rename(\n    self: 'Pathy',\n    target: Union[str, pathlib_abc.PurePathBase],\n) -\u003e 'Pathy'\n```\n\nRename this path to the given target.\n\nIf the target exists and is a file, it will be replaced silently if the user\nhas permission.\n\nIf path is a blob prefix, it will replace all the blobs with the same prefix\nto match the target prefix.\n\n## replace\n\n```python\nPathy.replace(\n    self: 'Pathy',\n    target: Union[str, pathlib_abc.PurePathBase],\n) -\u003e 'Pathy'\n```\n\nRenames this path to the given target.\n\nIf target points to an existing path, it will be replaced.\n\n## resolve\n\n```python\nPathy.resolve(self, strict: bool = False) -\u003e 'Pathy'\n```\n\nResolve the given path to remove any relative path specifiers.\n\n```python\nfrom pathy import Pathy\n\npath = Pathy(\"gs://my_bucket/folder/../blob\")\nassert path.resolve() == Pathy(\"gs://my_bucket/blob\")\n```\n\n## rmdir\n\n```python\nPathy.rmdir(self: 'Pathy') -\u003e None\n```\n\nRemoves this bucket or blob prefix. It must be empty.\n\n## samefile\n\n```python\nPathy.samefile(\n    self: 'Pathy',\n    other_path: Union[str, bytes, int, pathlib_abc.PathBase],\n) -\u003e bool\n```\n\nDetermine if this path points to the same location as other_path.\n\n## stat\n\n```python\nPathy.stat(self: 'Pathy', follow_symlinks: bool = True) -\u003e pathy.BlobStat\n```\n\nReturns information about this bucket path.\n\n## to_local\n\n```python\nPathy.to_local(\n    blob_path: Union[Pathy, str],\n    recurse: bool = True,\n) -\u003e pathlib.Path\n```\n\nDownload and cache either a blob or a set of blobs matching a prefix.\n\nThe cache is sensitive to the file updated time, and downloads new blobs\nas their updated timestamps change.\n\n## touch\n\n```python\nPathy.touch(self: 'Pathy', mode: int = 438, exist_ok: bool = True) -\u003e None\n```\n\nCreate a blob at this path.\n\nIf the blob already exists, the function succeeds if exist_ok is true\n(and its modification time is updated to the current time), otherwise\nFileExistsError is raised.\n\n## unlink\n\n```python\nPathy.unlink(self: 'Pathy') -\u003e None\n```\n\nDelete a link to a blob in a bucket.\n\n# BlobStat\n\n```python\nBlobStat(\n    self,\n    name: str,\n    size: Optional[int],\n    last_modified: Optional[int],\n) -\u003e None\n```\n\nStat for a bucket item\n\n# use_fs\n\n```python\nuse_fs(\n    root: Optional[str, pathlib_abc.PathBase, pathy.PathlibPathEx, bool] = None,\n) -\u003e Optional[pathy.BucketClientFS]\n```\n\nUse a path in the local file-system to store blobs and buckets.\n\nThis is useful for development and testing situations, and for embedded\napplications.\n\n# get_fs_client\n\n```python\nget_fs_client() -\u003e Optional[pathy.BucketClientFS]\n```\n\nGet the file-system client (or None)\n\n# use_fs_cache\n\n```python\nuse_fs_cache(\n    root: Optional[str, pathlib_abc.PathBase, pathy.PathlibPathEx, bool] = None,\n) -\u003e Optional[pathy.PathlibPathEx]\n```\n\nUse a path in the local file-system to cache blobs and buckets.\n\nThis is useful for when you want to avoid fetching large blobs multiple\ntimes, or need to pass a local file path to a third-party library.\n\n# get_fs_cache\n\n```python\nget_fs_cache() -\u003e Optional[pathy.PathlibPathEx]\n```\n\nGet the folder that holds file-system cached blobs and timestamps.\n\n# set_client_params\n\n```python\nset_client_params(scheme: str, kwargs: Any) -\u003e None\n```\n\nSpecify args to pass when instantiating a service-specific Client\nobject. This allows for passing credentials in whatever way your underlying\nclient library prefers.\n\n# 💻 CLI\n\nPathy command line interface. (v0.11.0)\n\n**Usage**:\n\n```console\n$ [OPTIONS] COMMAND [ARGS]...\n```\n\n**Options**:\n\n- `--install-completion`: Install completion for the current shell.\n- `--show-completion`: Show completion for the current shell, to copy it or customize the installation.\n- `--help`: Show this message and exit.\n\n**Commands**:\n\n- `cp`: Copy a blob or folder of blobs from one...\n- `ls`: List the blobs that exist at a given...\n- `mv`: Move a blob or folder of blobs from one...\n- `rm`: Remove a blob or folder of blobs from a...\n\n## `cp`\n\nCopy a blob or folder of blobs from one bucket to another.\n\n**Usage**:\n\n```console\n$ cp [OPTIONS] FROM_LOCATION TO_LOCATION\n```\n\n**Arguments**:\n\n- `FROM_LOCATION`: [required]\n- `TO_LOCATION`: [required]\n\n**Options**:\n\n- `--help`: Show this message and exit.\n\n## `ls`\n\nList the blobs that exist at a given location.\n\n**Usage**:\n\n```console\n$ ls [OPTIONS] LOCATION\n```\n\n**Arguments**:\n\n- `LOCATION`: [required]\n\n**Options**:\n\n- `-l, --long`: Print long style entries with updated time and size shown.\n- `--help`: Show this message and exit.\n\n## `mv`\n\nMove a blob or folder of blobs from one path to another.\n\n**Usage**:\n\n```console\n$ mv [OPTIONS] FROM_LOCATION TO_LOCATION\n```\n\n**Arguments**:\n\n- `FROM_LOCATION`: [required]\n- `TO_LOCATION`: [required]\n\n**Options**:\n\n- `--help`: Show this message and exit.\n\n## `rm`\n\nRemove a blob or folder of blobs from a given location.\n\n**Usage**:\n\n```console\n$ rm [OPTIONS] LOCATION\n```\n\n**Arguments**:\n\n- `LOCATION`: [required]\n\n**Options**:\n\n- `-r, --recursive`: Recursively remove files and folders.\n- `-v, --verbose`: Print removed files and folders.\n- `--help`: Show this message and exit.\n\n\u003c!-- AUTO_DOCZ_END --\u003e\n\n# Credits\n\nPathy is originally based on the [S3Path](https://github.com/liormizr/s3path) project, which provides a Path interface for S3 buckets.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustindujardin%2Fpathy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjustindujardin%2Fpathy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustindujardin%2Fpathy/lists"}