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
Platform-Specific Details
Linux (x86_64, ARM64):
- Wheels include bundled rclone binaries - no separate installation needed
pip install rclone-adapteris all you need!
macOS, Windows:
- Source distribution (
sdist) available, but no pre-built wheels yet - Install rclone separately: https://rclone.org/install/
- Then:
pip install rclone-adapter
Using system rclone (any platform):
- If you prefer your system's rclone installation, it will be used automatically
- The bundled binary is used as a fallback if system rclone is not found
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.
Latest Release: v0.1.0 (2025-10-19)
- Initial public release on PyPI
- Full async/await support
- All 54 rclone subcommands
- Linux wheels with bundled rclone binaries
- Comprehensive test suite and CI/CD
Metadata
Release files for rclone-adapter 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rclone_adapter-0.2.0.tar.gz | 23.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rclone_adapter-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.5 MB
Release files / rclone_adapter-0.2.0.tar.gz
| Download URL | rclone_adapter-0.2.0.tar.gz |
|---|---|
| Size | 23.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
45f7df9b9019ed46f7e29fd29a3997194a57a5d50b0a23859cd591138bd181d9
|
|
BLAKE2b-256 checksum How to use checksums |
665b41eb6130a7b7a96604030c3031cea0a89c91e91ff9f1367b9ffaa5c805ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2025.
Transparency logRelease files / rclone_adapter-0.2.0-py3-none-any.whl
| Download URL | rclone_adapter-0.2.0-py3-none-any.whl |
|---|---|
| Size | 23.3 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dd6efd116a17180916feebc0526c274fd0cf5191e403afab6497d48e4258136c
|
|
BLAKE2b-256 checksum How to use checksums |
6bbceebd03e25188540a3e03197438204ac522c80a3d012e47d3d234fc1f5210
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2025.
Transparency log