Modern async Python wrapper for rclone
Project description
rclone-adapter
A modern, async-first Python wrapper for rclone with comprehensive type hints, progress tracking, and structured logging.
Overview
rclone-adapter provides a Pythonic, async-first interface to rclone for cloud storage operations. Instead of running shell commands, you can use intuitive Python methods and async/await patterns to interact with cloud storage providers.
Key Features
- ๐ Async-First Design: Full async/await support with AsyncIterator for streaming progress
- ๐ฆ Bundled rclone: Latest rclone binary included in wheels for all platforms
- ๐ฏ Type Safe: Comprehensive type hints for IDE autocomplete and type checking
- ๐ Progress Tracking: Real-time progress events with adaptive interval throttling
- ๐ง Full Command Support: All 54 rclone subcommands with auto-generated type-safe options
- ๐ Structured Logging: Built-in structured logging with structlog
- ๐ Pretty Output: Terminal-friendly progress bars and formatted output with rich
- โ๏ธ Flexible Configuration: Support for environment variables and rclone config files
- ๐ Well Documented: Comprehensive CLAUDE.md guide for developers
Installation
pip install rclone-adapter
The wheel includes the latest rclone binary for your platform, so you don't need to install rclone separately!
Alternatively, if you prefer to use your system's rclone:
pip install rclone-adapter
# Then install rclone: https://rclone.org/install/
Supported Python Versions
- Python 3.10, 3.11, 3.12, 3.13, 3.14+
Quick Start
Async Usage (Recommended)
import asyncio
from rclone import RClone, RCloneConfig
async def main():
# Create config (uses bundled rclone binary automatically)
config = RCloneConfig(
env_vars={
"RCLONE_S3_PROVIDER": "AWS",
"RCLONE_S3_REGION": "us-west-2",
}
)
# Initialize client
rc = RClone(config)
# Simple API - returns only final result
result = await rc.sync(source="/local/path", dest="s3:mybucket/path")
print(f"Transferred: {result.files_transferred} files ({result.bytes_transferred} bytes)")
# Streaming API - get real-time progress events
async for event in rc.sync_stream(source="/local", dest="s3:mybucket/"):
if hasattr(event, 'progress'):
print(f"Progress: {event.progress:.1%}")
elif hasattr(event, 'message'):
print(f"Info: {event.message}")
asyncio.run(main())
Sync Usage
from rclone import RClone
# For non-async code
rc = RClone()
# Blocking wrapper
result = rc.sync_blocking(
source="/local/path",
dest="s3:mybucket/path"
)
if result.success:
print(f"โ Success! Transferred {result.files_transferred} files")
else:
print(f"โ Failed with {len(result.errors)} errors")
Usage Examples
Copy with Progress Tracking
import asyncio
from rclone import RClone, ProgressEvent, ErrorEvent
async def copy_with_progress():
rc = RClone()
async for event in rc.copy_stream(
source="/source/path",
dest="/dest/path"
):
if isinstance(event, ProgressEvent):
print(f"Progress: {event.bytes_transferred:,} / {event.total_bytes:,} bytes")
elif isinstance(event, ErrorEvent):
print(f"Error: {event.message}")
asyncio.run(copy_with_progress())
Using Environment Variables
from rclone import RClone, RCloneConfig
config = RCloneConfig(
env_vars={
"RCLONE_S3_PROVIDER": "AWS",
"RCLONE_S3_ACCESS_KEY_ID": "your-key",
"RCLONE_S3_SECRET_ACCESS_KEY": "your-secret",
}
)
rc = RClone(config)
result = await rc.sync(source="s3:bucket1/", dest="s3:bucket2/")
Using rclone Config File
from pathlib import Path
from rclone import RClone, RCloneConfig
config = RCloneConfig(
config_file=Path("~/.config/rclone/rclone.conf")
)
rc = RClone(config)
result = await rc.sync(source="gdrive:/", dest="/local/backup/")
Architecture
Core Design
- Async-First: All main operations are async-first with sync wrappers available
- Event Streaming: Operations yield events for progress, errors, and completion
- Type Safe: Pydantic v2 for configuration validation, dataclass models for results
- Modular: Separate modules for client, models, process management, and parsing
Bundled Binary
The wheels include platform-specific rclone binaries:
- Linux x86_64, ARM64
- macOS Intel, Apple Silicon
- Windows x86_64
The find_rclone_binary() utility automatically selects the correct binary for your platform.
Generated Command Options
All 54 rclone subcommands are supported with auto-generated Pydantic models:
SyncOptions,CopyOptions,MoveOptions- File transfer operationsLsOptions,LsdOptions,LsjsonOptions- Listing operationsCheckOptions,ChecksumOptions- Verification operations- And more!
Development
Setting Up Development Environment
# Clone and install in editable mode
git clone https://github.com/dirkpetersen/rclone-adapter.git
cd rclone-adapter
# Install with development dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Run linting
ruff check rclone/ tests/
mypy rclone/ --strict
Project Structure
rclone-adapter/
โโโ rclone/
โ โโโ __init__.py # Main package exports
โ โโโ client.py # RClone async client
โ โโโ models.py # Pydantic models (config, events, results)
โ โโโ process.py # Subprocess management
โ โโโ parser.py # rclone log parsing
โ โโโ util.py # Utility functions
โ โโโ exceptions.py # Exception hierarchy
โ โโโ py.typed # PEP 561 marker for type hints
โ โโโ bin/ # Platform-specific rclone binaries
โ โโโ _generated/ # Auto-generated command options
โโโ tests/ # Test suite
โโโ examples/ # Usage examples
โโโ CLAUDE.md # Developer guide
โโโ README.md # This file
Running Tests
# All tests
pytest tests/
# Unit tests only (no integration tests)
pytest tests/ -m "not integration"
# With coverage
pytest tests/ --cov=rclone --cov-report=html
# Specific test file
pytest tests/test_client.py -v
API Reference
RClone Client
Main async client for rclone operations.
class RClone:
async def sync(
source: str,
dest: str,
options: SyncOptions | None = None
) -> SyncResult
async def sync_stream(
source: str,
dest: str,
options: SyncOptions | None = None
) -> AsyncIterator[ProgressEvent | ErrorEvent | SyncResult]
def sync_blocking(
source: str,
dest: str,
options: SyncOptions | None = None
) -> SyncResult
# Similar methods for: copy, move, ls, lsd, check, etc.
RCloneConfig
Configuration for the client with validation.
config = RCloneConfig(
config_file=Path("~/.config/rclone/rclone.conf"), # Optional
env_vars={ # Optional
"RCLONE_S3_PROVIDER": "AWS",
"RCLONE_S3_REGION": "us-west-2",
},
rclone_path="/usr/bin/rclone", # Optional, auto-detected
log_level="INFO", # Optional
)
Events
Operations yield typed events for progress and errors:
class ProgressEvent:
bytes_transferred: int
total_bytes: int
progress: float # 0.0 to 1.0
transfer_rate: int # bytes/sec
eta_seconds: Optional[int]
current_file: Optional[str]
class ErrorEvent:
message: str
file: Optional[str]
error_category: str # "network", "permission", "not_found", etc.
is_retryable: bool
Results
Operations return typed result objects:
class SyncResult:
success: bool
return_code: int
bytes_transferred: int
files_transferred: int
errors: list[ErrorEvent]
duration_seconds: float
stats: dict # Full rclone stats
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes with tests
- Run linting and type checking:
ruff check --fix rclone/ tests/ mypy rclone/ --strict pytest tests/
- Commit your changes (
git commit -m 'Add amazing feature') - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
See CLAUDE.md for detailed development guidance.
License
MIT License - see LICENSE file for details.
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- rclone Documentation: rclone.org
Related Projects
- rclone - The main rclone project
- python-pwalk - Modern Python packaging template
- froster - Previous rclone wrapper (being replaced)
Changelog
See CHANGELOG.md for release history and version changes.
Status: Alpha (0.1.0) - API is stable but may receive enhancements before 1.0 release.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rclone_adapter-0.1.0.tar.gz.
File metadata
- Download URL: rclone_adapter-0.1.0.tar.gz
- Upload date:
- Size: 23.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48507eed92fddafadf4b29b3a10b7d9a01ca93a61d4956af6443a0f708fba33e
|
|
| MD5 |
4375a3790b1f34c06a962cb521bf7923
|
|
| BLAKE2b-256 |
b2d87ac09a5f0af76a9affb189a89abefd96eaf40d93c62cbb629569c9050e74
|
Provenance
The following attestation bundles were made for rclone_adapter-0.1.0.tar.gz:
Publisher:
publish-pypi.yml on dirkpetersen/rclone-adapter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rclone_adapter-0.1.0.tar.gz -
Subject digest:
48507eed92fddafadf4b29b3a10b7d9a01ca93a61d4956af6443a0f708fba33e - Sigstore transparency entry: 622534065
- Sigstore integration time:
-
Permalink:
dirkpetersen/rclone-adapter@33524944383fc7b18e8fd229527968a8a61c3574 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/dirkpetersen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@33524944383fc7b18e8fd229527968a8a61c3574 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rclone_adapter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rclone_adapter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.3 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d885d555cb87284c071189e9edc8b87d5c8246a16e0d275f054c2aafae16efc6
|
|
| MD5 |
653e38c48a7db11d0a1efd3b67934d38
|
|
| BLAKE2b-256 |
d23c32b1dcb5b6f4d854a5d6e22fe8608770c4bf23eb8daa43ec28cdae45cab6
|
Provenance
The following attestation bundles were made for rclone_adapter-0.1.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on dirkpetersen/rclone-adapter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rclone_adapter-0.1.0-py3-none-any.whl -
Subject digest:
d885d555cb87284c071189e9edc8b87d5c8246a16e0d275f054c2aafae16efc6 - Sigstore transparency entry: 622534068
- Sigstore integration time:
-
Permalink:
dirkpetersen/rclone-adapter@33524944383fc7b18e8fd229527968a8a61c3574 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/dirkpetersen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@33524944383fc7b18e8fd229527968a8a61c3574 -
Trigger Event:
push
-
Statement type: