{"id":34862638,"url":"https://github.com/pwwang/panpath","last_synced_at":"2026-04-16T23:03:44.737Z","repository":{"id":329314337,"uuid":"1119018521","full_name":"pwwang/panpath","owner":"pwwang","description":"Universal sync/async local/cloud path library with pathlib-compatible interface for Python","archived":false,"fork":false,"pushed_at":"2026-02-07T02:10:22.000Z","size":3285,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-07T12:53:36.204Z","etag":null,"topics":["async","async-cloudpath","async-path","cloudpath","path","pathlib","pathlib-methods"],"latest_commit_sha":null,"homepage":"https://pwwang.github.io/panpath/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pwwang.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-18T16:07:06.000Z","updated_at":"2026-02-07T01:14:45.000Z","dependencies_parsed_at":"2026-01-06T16:07:39.602Z","dependency_job_id":null,"html_url":"https://github.com/pwwang/panpath","commit_stats":null,"previous_names":["pwwang/panpath"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/pwwang/panpath","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwwang%2Fpanpath","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwwang%2Fpanpath/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwwang%2Fpanpath/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwwang%2Fpanpath/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pwwang","download_url":"https://codeload.github.com/pwwang/panpath/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwwang%2Fpanpath/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31907728,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"ssl_error","status_checked_at":"2026-04-16T18:21:47.142Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["async","async-cloudpath","async-path","cloudpath","path","pathlib","pathlib-methods"],"created_at":"2025-12-25T21:30:45.601Z","updated_at":"2026-04-16T23:03:44.705Z","avatar_url":"https://github.com/pwwang.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PanPath\n\nUniversal sync/async local/cloud path library with pathlib-compatible interface for Python.\n\n## Features\n\n- 🔄 **Unified Interface**: Single API for local and cloud storage (S3, Google Cloud Storage, Azure Blob Storage)\n- ⚡ **Sync \u0026 Async**: Choose synchronous or asynchronous operations based on your needs\n- 🎯 **Pathlib Compatible**: Drop-in replacement for `pathlib.Path` for local files\n- 🔌 **Lazy Loading**: Cloud clients instantiated only when needed\n- 🌐 **Cross-Storage Operations**: Copy/move files between different storage backends seamlessly\n- 📁 **Bulk Operations**: Efficient `rmtree`, `copy`, `copytree` for directories\n- 🧪 **Testable**: Local mock infrastructure for testing without cloud resources\n- 📦 **Optional Dependencies**: Install only what you need\n\n## Installation\n\n```bash\n# Core library (local paths only)\npip install panpath\n\n# With sync S3 support\npip install panpath[s3]\n\n# With async S3 support\npip install panpath[async-s3]\n\n# With all sync backends\npip install panpath[all-sync]\n\n# With all async backends\npip install panpath[all-async]\n\n# With everything\npip install panpath[all]\n```\n\n## Quick Start\n\n### Synchronous Usage\n\n```python\nfrom panpath import PanPath\n\n# Local files (pathlib.Path compatible)\nlocal = PanPath(\"/path/to/file.txt\")\ncontent = local.read_text()\n\n# S3 (synchronous)\ns3_file = PanPath(\"s3://bucket/key/file.txt\")\ncontent = s3_file.read_text()\n\n# Google Cloud Storage (synchronous)\ngs_file = PanPath(\"gs://bucket/path/file.txt\")\ncontent = gs_file.read_text()\n\n# Azure Blob Storage (synchronous)\nazure_file = PanPath(\"az://container/path/file.txt\")\ncontent = azure_file.read_text()\n```\n\n### Asynchronous Usage\n\n```python\nfrom panpath import PanPath\n\n# All path classes support async methods with a_ prefix\ns3_path = PanPath(\"s3://bucket/key/file.txt\")\ncontent = await s3_path.a_read_text()\n\n# Works for all cloud storage providers\ngs_path = PanPath(\"gs://bucket/path/file.txt\")\ncontent = await gs_path.a_read_text()\n\n# Async local files\nlocal_path = PanPath(\"/path/to/file.txt\")\nasync with local_path.a_open(\"r\") as f:\n    content = await f.read()\n```\n\n### Path Operations\n\n```python\nfrom panpath import PanPath\n\n# Path operations preserve type\ns3_path = PanPath(\"s3://bucket/data/file.txt\")\nparent = s3_path.parent  # Returns S3Path\nsibling = s3_path.parent / \"other.txt\"  # Returns S3Path\n\n# Each path supports both sync and async methods\ncontent = s3_path.read_text()  # Synchronous\ncontent = await s3_path.a_read_text()  # Asynchronous\n```\n\n### Bulk Operations and Cross-Storage Transfers\n\n```python\nfrom panpath import PanPath\n\n# Copy between different cloud providers\ns3_file = PanPath(\"s3://my-bucket/data.csv\")\ns3_file.copy(\"gs://other-bucket/data.csv\")  # S3 → GCS\n\n# Download entire directory from cloud\ncloud_dir = PanPath(\"s3://bucket/dataset/\")\ncloud_dir.copytree(\"/tmp/dataset/\")  # Downloads all files\n\n# Upload local directory to cloud\nlocal_dir = PanPath(\"/home/user/project/\")\nlocal_dir.copytree(\"az://container/project/\")  # Uploads to Azure\n\n# Remove directory recursively\ntemp_dir = PanPath(\"gs://bucket/temp/\")\ntemp_dir.rmtree()  # Deletes all files in temp/\n\n# Move between cloud providers (copy + delete)\ns3_data = PanPath(\"s3://old-bucket/data/\")\ns3_data.rename(\"gs://new-bucket/data/\")  # Migrates to GCS\n```\n\nSee [bulk-operations.md](docs/guide/bulk-operations.md) for detailed documentation and examples.\n\n## URI Schemes\n\n- `file://` or no prefix → Local filesystem\n- `s3://` → Amazon S3\n- `gs://` → Google Cloud Storage\n- `az://` or `azure://` → Azure Blob Storage\n\n## Architecture\n\nPanPath uses a factory pattern to dispatch path creation based on URI scheme:\n\n- `PanPath(pathlib.Path)` - Root factory and base class\n- `LocalPath(PanPath)` - Local filesystem paths\n- `CloudPath(PanPath)` - Base for all cloud storage paths\n- `GSPath(CloudPath)`, `S3Path(CloudPath)`, `AzurePath(CloudPath)` - Cloud-specific implementations\n\nEach path class provides both synchronous methods and asynchronous methods (prefixed with `a_`). Cloud paths use lazy client instantiation - SDK clients are only created on first I/O operation.\n\n## Type Hints\n\nPanPath provides comprehensive type hints:\n\n```python\nfrom panpath import PanPath\nfrom panpath.s3_path import S3Path\n\n# Type checker knows return type based on URI scheme\npath: S3Path = PanPath(\"s3://bucket/key\")\n```\n\n## Testing\n\nUse local mock infrastructure for testing without cloud credentials:\n\n```python\nimport pytest\nfrom panpath.testing import use_local_mocks\n\n@use_local_mocks()\ndef test_s3_operations():\n    path = PanPath(\"s3://test-bucket/file.txt\")\n    path.write_text(\"test content\")\n    assert path.read_text() == \"test content\"\n```\n\n## Migration Guide\n\n### From pathlib\n\n```python\n# Before\nfrom pathlib import Path\npath = Path(\"/local/file.txt\")\n\n# After (drop-in replacement)\nfrom panpath import PanPath\npath = PanPath(\"/local/file.txt\")\n```\n\n### From cloudpathlib\n\n```python\n# Before\nfrom cloudpathlib import S3Path\npath = S3Path(\"s3://bucket/key\")\n\n# After\nfrom panpath import PanPath\npath = PanPath(\"s3://bucket/key\")\n```\n\n### From aiopath\n\n```python\n# Before\nfrom aiopath import AsyncPath\npath = AsyncPath(\"/local/file.txt\")\n# await path.read_text()\n\n# After\nfrom panpath import PanPath\npath = PanPath(\"/local/file.txt\")\n# await path.a_read_text()\n```\n\n## License\n\nMIT License - see LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwwang%2Fpanpath","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpwwang%2Fpanpath","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwwang%2Fpanpath/lists"}