A python wrapper for rclone that makes rclone's functionality usable in python applications.
—
System-level operations including installation checking, version management, configuration file handling, and logging control. Essential functions for environment setup and system integration.
Check rclone installation status and retrieve version information with optional update checking.
def is_installed() -> bool:
"""
Checks if rclone is properly installed and accessible in system PATH.
Returns:
bool: True if rclone command is available, False otherwise
"""
def version(check=False, args: List[str] = None) -> Union[str, Tuple[str]]:
"""
Retrieves rclone version information with optional update checking.
Parameters:
- check (bool): Perform online check for latest versions
- args (List[str]): Additional rclone version flags
Returns:
- str: Current version string when check=False
- Tuple[str, str, str]: (current, latest, beta) when check=True
Returns (current, None, None) if online check fails
Raises:
RcloneException: If version command fails
"""Control rclone configuration file location and logging behavior for the wrapper.
def set_config_file(config_file: str):
"""
Sets custom rclone configuration file path for all subsequent operations.
Parameters:
- config_file (str): Path to custom rclone config file
Returns:
None
Note:
Uses singleton pattern - setting persists for entire application session
"""
def set_log_level(level: int):
"""
Sets logging level for the rclone-python wrapper.
Parameters:
- level (int): Python logging level (e.g., logging.DEBUG, logging.INFO)
Returns:
None
"""from rclone_python import rclone
# Check if rclone is installed
if rclone.is_installed():
print("✓ rclone is installed and ready")
# Get version information
current_version = rclone.version()
print(f"Current version: {current_version}")
else:
print("✗ rclone is not installed")
print("Please install rclone from: https://rclone.org/")
exit(1)from rclone_python import rclone
# Get current version only
current = rclone.version()
print(f"Installed version: {current}")
# Check for updates (requires internet connection)
try:
current, latest, beta = rclone.version(check=True)
print(f"Current: {current}")
print(f"Latest stable: {latest}")
print(f"Latest beta: {beta}")
if latest and current != latest:
print("🔄 Update available!")
else:
print("✓ Running latest version")
except Exception as e:
print(f"Update check failed: {e}")from rclone_python import rclone
import os
from pathlib import Path
# Set up custom config directory
config_dir = Path.home() / '.config' / 'myapp' / 'rclone'
config_dir.mkdir(parents=True, exist_ok=True)
config_file = config_dir / 'rclone.conf'
# Use custom config file
rclone.set_config_file(str(config_file))
print(f"Using config file: {config_file}")
# Verify config is being used
remotes = rclone.get_remotes()
print(f"Configured remotes: {remotes}")
# Later operations will use this config file automatically
rclone.create_remote('myremote', rclone.RemoteTypes.onedrive)from rclone_python import rclone
import logging
# Set up debug logging to see all rclone commands
rclone.set_log_level(logging.DEBUG)
# Test with a simple operation
print("Debug logging enabled - you'll see rclone commands:")
rclone.copy('local_file.txt', 'onedrive:backup/')
# Reduce logging for production
rclone.set_log_level(logging.WARNING)
print("Logging reduced to warnings and errors only")from rclone_python import rclone
from rclone_python.remote_types import RemoteTypes
import logging
import sys
import os
def setup_rclone_environment(config_path=None, log_level=logging.INFO):
"""Complete rclone environment setup and validation"""
print("Setting up rclone environment...")
# 1. Check installation
if not rclone.is_installed():
print("✗ rclone not found in PATH")
print("Install from: https://rclone.org/install/")
return False
print("✓ rclone installation found")
# 2. Check version
try:
version = rclone.version()
print(f"✓ rclone version: {version}")
# Optionally check for updates
if os.getenv('CHECK_UPDATES', '').lower() == 'true':
current, latest, beta = rclone.version(check=True)
if latest and current != latest:
print(f"⚠ Update available: {current} → {latest}")
except Exception as e:
print(f"⚠ Version check failed: {e}")
# 3. Set up logging
rclone.set_log_level(log_level)
print(f"✓ Logging level set to: {logging.getLevelName(log_level)}")
# 4. Configure custom config file if provided
if config_path:
rclone.set_config_file(config_path)
print(f"✓ Using config file: {config_path}")
# 5. List available remotes
try:
remotes = rclone.get_remotes()
if remotes:
print(f"✓ Found {len(remotes)} configured remotes: {remotes}")
else:
print("ℹ No remotes configured yet")
except Exception as e:
print(f"⚠ Could not list remotes: {e}")
print("✓ rclone environment setup complete")
return True
# Set up environment
success = setup_rclone_environment(
config_path=os.path.expanduser('~/.config/myapp/rclone.conf'),
log_level=logging.INFO
)
if not success:
sys.exit(1)from rclone_python import rclone
import logging
import atexit
import tempfile
import shutil
class RcloneManager:
"""Manage rclone configuration for an application"""
def __init__(self, app_name, debug=False):
self.app_name = app_name
self.temp_config = None
# Set up logging
log_level = logging.DEBUG if debug else logging.INFO
rclone.set_log_level(log_level)
# Verify rclone is available
if not rclone.is_installed():
raise RuntimeError("rclone is not installed")
# Get version info
self.version = rclone.version()
print(f"Using rclone {self.version}")
def use_temp_config(self):
"""Use a temporary config file (useful for testing)"""
self.temp_config = tempfile.NamedTemporaryFile(
mode='w',
suffix='.conf',
prefix=f'{self.app_name}_rclone_',
delete=False
)
self.temp_config.close()
rclone.set_config_file(self.temp_config.name)
print(f"Using temporary config: {self.temp_config.name}")
# Clean up on exit
atexit.register(self.cleanup)
def use_app_config(self, config_dir=None):
"""Use application-specific config directory"""
if not config_dir:
config_dir = Path.home() / '.config' / self.app_name
config_dir = Path(config_dir)
config_dir.mkdir(parents=True, exist_ok=True)
config_file = config_dir / 'rclone.conf'
rclone.set_config_file(str(config_file))
print(f"Using app config: {config_file}")
def health_check(self):
"""Perform basic health check"""
try:
# Test version command
version = rclone.version()
# Test listing remotes
remotes = rclone.get_remotes()
return {
'status': 'healthy',
'version': version,
'remotes': len(remotes),
'remote_list': remotes
}
except Exception as e:
return {
'status': 'unhealthy',
'error': str(e)
}
def cleanup(self):
"""Clean up temporary resources"""
if self.temp_config and os.path.exists(self.temp_config.name):
os.unlink(self.temp_config.name)
print(f"Cleaned up temporary config: {self.temp_config.name}")
# Usage example
manager = RcloneManager('myapp', debug=True)
manager.use_app_config()
# Perform health check
health = manager.health_check()
print(f"Health check: {health}")from rclone_python import rclone
import sys
import subprocess
import platform
def system_integration_check():
"""Comprehensive system integration verification"""
print("Performing system integration check...")
# 1. Check rclone installation
if not rclone.is_installed():
print("✗ rclone not found")
return False
# 2. Check system details
system_info = {
'platform': platform.system(),
'architecture': platform.machine(),
'python_version': sys.version.split()[0]
}
print(f"✓ System: {system_info['platform']} {system_info['architecture']}")
print(f"✓ Python: {system_info['python_version']}")
# 3. Check rclone details
try:
version = rclone.version()
print(f"✓ rclone: {version}")
# Check if it's in PATH
rclone_path = subprocess.run(
['which', 'rclone'] if system_info['platform'] != 'Windows' else ['where', 'rclone'],
capture_output=True, text=True
)
if rclone_path.returncode == 0:
print(f"✓ rclone path: {rclone_path.stdout.strip()}")
except Exception as e:
print(f"⚠ rclone check failed: {e}")
return False
# 4. Test basic operations
try:
remotes = rclone.get_remotes()
print(f"✓ Basic operations working (found {len(remotes)} remotes)")
except Exception as e:
print(f"⚠ Basic operations failed: {e}")
return False
print("✓ System integration check passed")
return True
# Run integration check
if __name__ == "__main__":
success = system_integration_check()
sys.exit(0 if success else 1)The wrapper uses a singleton pattern for configuration management:
from rclone_python import rclone
from rclone_python.utils import Config
# The Config class is a singleton
config1 = Config('/path/to/config1.conf')
config2 = Config('/path/to/config2.conf') # This won't change the path
# config1 and config2 are the same instance
print(config1 is config2) # True
# To change config, use the set_config_file function
rclone.set_config_file('/path/to/new_config.conf')While not directly exposed by the wrapper, you can influence rclone behavior through environment variables:
import os
from rclone_python import rclone
# Set rclone environment variables before operations
os.environ['RCLONE_CONFIG'] = '/custom/path/rclone.conf'
os.environ['RCLONE_CACHE_DIR'] = '/tmp/rclone_cache'
os.environ['RCLONE_VERBOSE'] = '1'
# These will affect rclone behavior
rclone.copy('source', 'dest')from rclone_python import rclone
from rclone_python.utils import RcloneException
import logging
def diagnose_rclone_issues():
"""Diagnose common rclone issues"""
issues = []
# Check installation
if not rclone.is_installed():
issues.append("rclone not found in PATH")
return issues
# Check version accessibility
try:
version = rclone.version()
except RcloneException as e:
issues.append(f"Version command failed: {e}")
return issues
# Check remote listing
try:
remotes = rclone.get_remotes()
except RcloneException as e:
issues.append(f"Cannot list remotes: {e}")
# Check logging
try:
rclone.set_log_level(logging.DEBUG)
rclone.set_log_level(logging.INFO) # Reset
except Exception as e:
issues.append(f"Logging configuration failed: {e}")
return issues
# Run diagnostics
problems = diagnose_rclone_issues()
if problems:
print("Issues found:")
for issue in problems:
print(f" - {issue}")
else:
print("✓ No issues detected")Install with Tessl CLI
npx tessl i tessl/pypi-rclone-python