A python wrapper for rclone that makes rclone's functionality usable in python applications.
—
Functions for generating, managing, and removing public links to files and directories. Enables sharing of cloud storage content with expiration control where supported by the storage backend.
Generate shareable public links for files and directories, with optional expiration times and link management.
def link(path: str, expire: Union[str, None] = None, unlink=False, args=None) -> str:
"""
Generates, retrieves, or removes public links for files or directories.
Parameters:
- path (str): File or directory path to create/manage link for
- expire (str, optional): Link expiration time (format depends on backend)
- unlink (bool): Remove existing public link instead of creating/retrieving
- args (List[str]): Additional rclone link flags
Returns:
str: Public link URL (empty string when unlink=True)
Raises:
RcloneException: If link operation fails or backend doesn't support public links
"""from rclone_python import rclone
# Generate public link for file
file_link = rclone.link('onedrive:documents/report.pdf')
print(f"Public link: {file_link}")
# Generate link for directory
folder_link = rclone.link('dropbox:shared_folder')
print(f"Folder link: {folder_link}")
# Generate link for single image
image_link = rclone.link('box:photos/vacation.jpg')
print(f"Image link: {image_link}")from rclone_python import rclone
# Create link expiring in 1 hour (format depends on backend)
temp_link = rclone.link('gdrive:temporary_file.zip', expire='1h')
print(f"Temporary link (1h): {temp_link}")
# Create link expiring in 7 days
week_link = rclone.link('onedrive:project_files', expire='7d')
print(f"Week-long link: {week_link}")
# Create link with specific expiration date (backend-specific format)
dated_link = rclone.link('dropbox:presentation.pptx', expire='2024-12-31T23:59:59Z')
print(f"Link expires 2024-12-31: {dated_link}")from rclone_python import rclone
# Create link
file_path = 'box:shared/document.pdf'
public_link = rclone.link(file_path)
print(f"Created link: {public_link}")
# Later, remove the public link
rclone.link(file_path, unlink=True)
print("Public link removed")
# Verify link is removed (this may fail if no link exists)
try:
removed_link = rclone.link(file_path)
print(f"Link still exists: {removed_link}")
except Exception:
print("Link successfully removed")from rclone_python import rclone
def create_links_for_directory(base_path, expire_time=None):
"""Create public links for all files in a directory"""
# Get all files in directory
files = rclone.ls(base_path, files_only=True)
links = {}
for file in files:
file_path = f"{base_path}/{file['Name']}" if not base_path.endswith(':') else f"{base_path}{file['Name']}"
try:
link_url = rclone.link(file_path, expire=expire_time)
links[file['Name']] = link_url
print(f"✓ {file['Name']}: {link_url}")
except Exception as e:
print(f"✗ {file['Name']}: Failed - {e}")
return links
# Create links for all files in a folder
public_links = create_links_for_directory('onedrive:presentation_materials', expire='2d')
# Save links to file
with open('public_links.txt', 'w') as f:
for filename, link in public_links.items():
f.write(f"{filename}: {link}\n")from rclone_python import rclone
import secrets
import json
from datetime import datetime, timedelta
def create_secure_share(file_path, recipient_email, expire_hours=24):
"""Create secure file share with tracking"""
# Generate unique share ID
share_id = secrets.token_urlsafe(16)
# Create expiring public link
expire_time = f"{expire_hours}h"
public_link = rclone.link(file_path, expire=expire_time)
# Create share record
share_record = {
'share_id': share_id,
'file_path': file_path,
'recipient': recipient_email,
'created': datetime.now().isoformat(),
'expires': (datetime.now() + timedelta(hours=expire_hours)).isoformat(),
'public_link': public_link,
'accessed': False
}
# Save share record (in real app, use database)
shares_file = 'active_shares.json'
try:
with open(shares_file, 'r') as f:
shares = json.load(f)
except FileNotFoundError:
shares = {}
shares[share_id] = share_record
with open(shares_file, 'w') as f:
json.dump(shares, f, indent=2)
print(f"Secure share created:")
print(f" Share ID: {share_id}")
print(f" Recipient: {recipient_email}")
print(f" Expires: {share_record['expires']}")
print(f" Link: {public_link}")
return share_id, public_link
def revoke_share(share_id):
"""Revoke a secure share"""
shares_file = 'active_shares.json'
try:
with open(shares_file, 'r') as f:
shares = json.load(f)
except FileNotFoundError:
print("No active shares found")
return
if share_id not in shares:
print(f"Share {share_id} not found")
return
share = shares[share_id]
# Remove public link
try:
rclone.link(share['file_path'], unlink=True)
print(f"✓ Public link removed for {share['file_path']}")
except Exception as e:
print(f"⚠ Failed to remove link: {e}")
# Remove from active shares
del shares[share_id]
with open(shares_file, 'w') as f:
json.dump(shares, f, indent=2)
print(f"Share {share_id} revoked")
# Create secure share
share_id, link = create_secure_share(
'confidential:report.pdf',
'colleague@company.com',
expire_hours=48
)
# Later, revoke the share
# revoke_share(share_id)from rclone_python import rclone
import requests
from urllib.parse import urlparse
def test_public_link(file_path):
"""Test if public link is accessible"""
try:
# Generate link
link_url = rclone.link(file_path)
print(f"Generated link: {link_url}")
# Parse URL to validate format
parsed = urlparse(link_url)
if not parsed.scheme or not parsed.netloc:
print("⚠ Invalid link format")
return False
# Test accessibility (HEAD request to avoid downloading)
try:
response = requests.head(link_url, timeout=10)
if response.status_code == 200:
print("✓ Link is accessible")
# Check content type if available
content_type = response.headers.get('content-type', 'unknown')
print(f" Content-Type: {content_type}")
# Check content length if available
content_length = response.headers.get('content-length')
if content_length:
size_mb = int(content_length) / (1024 * 1024)
print(f" Size: {size_mb:.2f} MB")
return True
else:
print(f"✗ Link returned status code: {response.status_code}")
return False
except requests.RequestException as e:
print(f"✗ Link test failed: {e}")
return False
except Exception as e:
print(f"✗ Failed to generate link: {e}")
return False
# Test public link accessibility
test_public_link('onedrive:public/document.pdf')from rclone_python import rclone
def create_backend_optimized_link(file_path, backend_type='onedrive'):
"""Create links optimized for specific backends"""
backend_configs = {
'onedrive': {
'expire_format': '2024-12-31T23:59:59Z', # ISO format
'args': ['--onedrive-link-type', 'view'] # View-only link
},
'dropbox': {
'expire_format': '2024-12-31', # Date only
'args': ['--dropbox-shared-links']
},
'googledrive': {
'expire_format': None, # Doesn't support expiration
'args': ['--drive-shared-with-me']
}
}
config = backend_configs.get(backend_type, {})
# Create link with backend-specific options
try:
link_url = rclone.link(
file_path,
expire=config.get('expire_format'),
args=config.get('args', [])
)
print(f"Created {backend_type} link: {link_url}")
return link_url
except Exception as e:
print(f"Failed to create {backend_type} link: {e}")
return None
# Create backend-specific links
onedrive_link = create_backend_optimized_link('onedrive:file.pdf', 'onedrive')
dropbox_link = create_backend_optimized_link('dropbox:file.pdf', 'dropbox')Public link support varies by storage backend:
from rclone_python import rclone
# OneDrive with specific link type
onedrive_view_link = rclone.link(
'onedrive:document.pdf',
args=['--onedrive-link-type', 'view', '--onedrive-link-scope', 'anonymous']
)
# Dropbox with password (if supported)
dropbox_protected_link = rclone.link(
'dropbox:sensitive.zip',
expire='7d',
args=['--dropbox-shared-links']
)
# S3 pre-signed URL
s3_presigned_link = rclone.link(
's3:bucket/file.pdf',
expire='3600', # Seconds for S3
args=['--s3-shared-credentials-file', '/path/to/credentials']
)from rclone_python import rclone
from rclone_python.utils import RcloneException
def safe_link_creation(file_path, expire=None):
"""Safely create public link with error handling"""
try:
link_url = rclone.link(file_path, expire=expire)
print(f"✓ Link created: {link_url}")
return link_url
except RcloneException as e:
if "not supported" in str(e).lower():
print(f"✗ Public links not supported for this backend")
elif "not found" in str(e).lower():
print(f"✗ File not found: {file_path}")
elif "permission" in str(e).lower():
print(f"✗ Permission denied for: {file_path}")
else:
print(f"✗ Link creation failed: {e}")
return None
except Exception as e:
print(f"✗ Unexpected error: {e}")
return None
# Safe link creation
link = safe_link_creation('onedrive:may_not_exist.pdf', expire='1d')Install with Tessl CLI
npx tessl i tessl/pypi-rclone-python