rclone-api 1.5.40__py3-none-any.whl → 1.5.42__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rclone_api/__init__.py +1003 -1003
- rclone_api/config.py +19 -3
- rclone_api/db/__init__.py +3 -3
- rclone_api/detail/walk.py +116 -116
- rclone_api/dir.py +113 -113
- rclone_api/log.py +44 -44
- rclone_api/rclone_impl.py +1360 -1360
- rclone_api/s3/multipart/upload_parts_server_side_merge.py +546 -546
- rclone_api/scan_missing_folders.py +153 -153
- {rclone_api-1.5.40.dist-info → rclone_api-1.5.42.dist-info}/METADATA +1108 -1100
- {rclone_api-1.5.40.dist-info → rclone_api-1.5.42.dist-info}/RECORD +15 -15
- {rclone_api-1.5.40.dist-info → rclone_api-1.5.42.dist-info}/WHEEL +1 -1
- {rclone_api-1.5.40.dist-info → rclone_api-1.5.42.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.5.40.dist-info → rclone_api-1.5.42.dist-info}/licenses/LICENSE +0 -0
- {rclone_api-1.5.40.dist-info → rclone_api-1.5.42.dist-info}/top_level.txt +0 -0
rclone_api/__init__.py
CHANGED
@@ -1,1003 +1,1003 @@
|
|
1
|
-
"""
|
2
|
-
Rclone API - Python interface for the Rclone command-line tool.
|
3
|
-
|
4
|
-
This package provides a high-level API for interacting with Rclone,
|
5
|
-
allowing file operations across various cloud storage providers.
|
6
|
-
The API wraps the rclone command-line tool, providing a Pythonic interface
|
7
|
-
for common operations like copying, listing, and managing remote storage.
|
8
|
-
"""
|
9
|
-
|
10
|
-
# Import core components and utilities
|
11
|
-
from datetime import datetime
|
12
|
-
from pathlib import Path
|
13
|
-
from typing import Generator
|
14
|
-
|
15
|
-
# Import logging utilities
|
16
|
-
from rclone_api import log
|
17
|
-
|
18
|
-
# Import data structures and models
|
19
|
-
from .completed_process import CompletedProcess
|
20
|
-
from .config import Config, Parsed, Section # Configuration handling
|
21
|
-
from .diff import DiffItem, DiffOption, DiffType # File comparison utilities
|
22
|
-
from .dir import Dir # Directory representation
|
23
|
-
from .dir_listing import DirListing # Directory contents representation
|
24
|
-
from .file import File, FileItem # File representation
|
25
|
-
from .file_stream import FilesStream # Streaming file listings
|
26
|
-
from .filelist import FileList # File list utilities
|
27
|
-
from .fs import FSPath, RealFS, RemoteFS # Filesystem utilities
|
28
|
-
from .http_server import HttpFetcher, HttpServer, Range # HTTP serving capabilities
|
29
|
-
|
30
|
-
# Import logging configuration utilities
|
31
|
-
from .log import configure_logging, setup_default_logging
|
32
|
-
from .mount import Mount # Mount remote filesystems
|
33
|
-
from .process import Process # Process management
|
34
|
-
from .remote import Remote # Remote storage representation
|
35
|
-
from .rpath import RPath # Remote path utilities
|
36
|
-
from .s3.types import MultiUploadResult # S3-specific types
|
37
|
-
from .types import ( # Common types
|
38
|
-
ListingOption,
|
39
|
-
Order,
|
40
|
-
PartInfo,
|
41
|
-
SizeResult,
|
42
|
-
SizeSuffix,
|
43
|
-
)
|
44
|
-
|
45
|
-
# Set up default logging configuration when the package is imported
|
46
|
-
setup_default_logging()
|
47
|
-
|
48
|
-
|
49
|
-
def rclone_verbose(val: bool | None) -> bool:
|
50
|
-
"""
|
51
|
-
Get or set the global verbosity setting for rclone operations.
|
52
|
-
|
53
|
-
Controls whether rclone commands will produce detailed output.
|
54
|
-
When enabled, commands will show more information about their operation.
|
55
|
-
|
56
|
-
Args:
|
57
|
-
val: If provided, sets the verbosity level. If None, returns the current setting.
|
58
|
-
|
59
|
-
Returns:
|
60
|
-
The current verbosity setting after any change.
|
61
|
-
"""
|
62
|
-
from rclone_api.rclone_impl import rclone_verbose as _rclone_verbose
|
63
|
-
|
64
|
-
return _rclone_verbose(val)
|
65
|
-
|
66
|
-
|
67
|
-
class Rclone:
|
68
|
-
"""
|
69
|
-
Main interface for interacting with Rclone.
|
70
|
-
|
71
|
-
This class provides methods for all major Rclone operations including
|
72
|
-
file transfers, listing, mounting, and remote management.
|
73
|
-
|
74
|
-
It serves as the primary entry point for the API, wrapping the underlying
|
75
|
-
implementation details and providing a clean, consistent interface.
|
76
|
-
"""
|
77
|
-
|
78
|
-
@staticmethod
|
79
|
-
def upgrade_rclone() -> Path:
|
80
|
-
"""
|
81
|
-
Upgrade the rclone executable to the latest version.
|
82
|
-
|
83
|
-
Downloads the latest rclone binary and replaces the current one.
|
84
|
-
|
85
|
-
If an external rclone is already in your path then although upgrade_rclone
|
86
|
-
will download the latest version, it will not affect the rclone selected.
|
87
|
-
|
88
|
-
Returns:
|
89
|
-
Path to the upgraded rclone executable
|
90
|
-
"""
|
91
|
-
from rclone_api.util import upgrade_rclone
|
92
|
-
|
93
|
-
return upgrade_rclone()
|
94
|
-
|
95
|
-
@staticmethod
|
96
|
-
def find_rclone_conf() -> Path | None:
|
97
|
-
"""Find the rclone configuration file from the environment or default locations."""
|
98
|
-
from rclone_api.config import find_conf_file
|
99
|
-
|
100
|
-
return find_conf_file()
|
101
|
-
|
102
|
-
def __init__(
|
103
|
-
self, rclone_conf: Path | Config | None, rclone_exe: Path | None = None
|
104
|
-
) -> None:
|
105
|
-
"""
|
106
|
-
Initialize the Rclone interface.
|
107
|
-
|
108
|
-
Args:
|
109
|
-
rclone_conf: Path to rclone config file or Config object
|
110
|
-
rclone_exe: Optional path to rclone executable. If None, will search in PATH.
|
111
|
-
"""
|
112
|
-
from rclone_api.rclone_impl import RcloneImpl
|
113
|
-
|
114
|
-
self.impl: RcloneImpl = RcloneImpl(rclone_conf, rclone_exe)
|
115
|
-
|
116
|
-
def webgui(self, other_args: list[str] | None = None) -> Process:
|
117
|
-
"""
|
118
|
-
Launch the Rclone web GUI.
|
119
|
-
|
120
|
-
Starts the built-in web interface for interacting with rclone.
|
121
|
-
|
122
|
-
Args:
|
123
|
-
other_args: Additional command-line arguments to pass to rclone
|
124
|
-
|
125
|
-
Returns:
|
126
|
-
Process object representing the running web GUI
|
127
|
-
"""
|
128
|
-
return self.impl.webgui(other_args=other_args)
|
129
|
-
|
130
|
-
def filesystem(self, src: str) -> RemoteFS:
|
131
|
-
"""
|
132
|
-
Get a RealFS object for interacting with the local filesystem.
|
133
|
-
|
134
|
-
Returns:
|
135
|
-
RealFS object for local filesystem operations
|
136
|
-
"""
|
137
|
-
return self.impl.filesystem(src=src)
|
138
|
-
|
139
|
-
def cwd(self, src: str) -> FSPath:
|
140
|
-
"""
|
141
|
-
Get the local root path for a filesystem.
|
142
|
-
|
143
|
-
Args:
|
144
|
-
src: Source path for the filesystem
|
145
|
-
|
146
|
-
Returns:
|
147
|
-
FSPath object representing the root of the filesystem
|
148
|
-
"""
|
149
|
-
return self.impl.cwd(src=src)
|
150
|
-
|
151
|
-
def launch_server(
|
152
|
-
self,
|
153
|
-
addr: str,
|
154
|
-
user: str | None = None,
|
155
|
-
password: str | None = None,
|
156
|
-
other_args: list[str] | None = None,
|
157
|
-
) -> Process:
|
158
|
-
"""
|
159
|
-
Launch the Rclone server so it can receive commands.
|
160
|
-
|
161
|
-
Starts an rclone server that can be controlled remotely.
|
162
|
-
|
163
|
-
Args:
|
164
|
-
addr: Address and port to listen on (e.g., "localhost:5572")
|
165
|
-
user: Optional username for authentication
|
166
|
-
password: Optional password for authentication
|
167
|
-
other_args: Additional command-line arguments
|
168
|
-
|
169
|
-
Returns:
|
170
|
-
Process object representing the running server
|
171
|
-
"""
|
172
|
-
return self.impl.launch_server(
|
173
|
-
addr=addr, user=user, password=password, other_args=other_args
|
174
|
-
)
|
175
|
-
|
176
|
-
def remote_control(
|
177
|
-
self,
|
178
|
-
addr: str,
|
179
|
-
user: str | None = None,
|
180
|
-
password: str | None = None,
|
181
|
-
capture: bool | None = None,
|
182
|
-
other_args: list[str] | None = None,
|
183
|
-
) -> CompletedProcess:
|
184
|
-
"""
|
185
|
-
Send commands to a running rclone server.
|
186
|
-
|
187
|
-
Args:
|
188
|
-
addr: Address of the rclone server (e.g., "localhost:5572")
|
189
|
-
user: Optional username for authentication
|
190
|
-
password: Optional password for authentication
|
191
|
-
capture: Whether to capture and return command output
|
192
|
-
other_args: Additional command-line arguments
|
193
|
-
|
194
|
-
Returns:
|
195
|
-
CompletedProcess containing the command result
|
196
|
-
"""
|
197
|
-
return self.impl.remote_control(
|
198
|
-
addr=addr,
|
199
|
-
user=user,
|
200
|
-
password=password,
|
201
|
-
capture=capture,
|
202
|
-
other_args=other_args,
|
203
|
-
)
|
204
|
-
|
205
|
-
def obscure(self, password: str) -> str:
|
206
|
-
"""
|
207
|
-
Obscure a password for use in rclone config files.
|
208
|
-
|
209
|
-
Converts a plaintext password to rclone's obscured format.
|
210
|
-
Note that this is not secure encryption, just light obfuscation.
|
211
|
-
|
212
|
-
Args:
|
213
|
-
password: The plaintext password to obscure
|
214
|
-
|
215
|
-
Returns:
|
216
|
-
The obscured password string
|
217
|
-
"""
|
218
|
-
return self.impl.obscure(password=password)
|
219
|
-
|
220
|
-
def config_show(
|
221
|
-
self, remote: str | None = None, obscure: bool = False, no_obscure: bool = False
|
222
|
-
) -> list[Path] | Exception:
|
223
|
-
"""Show the current configuration.
|
224
|
-
|
225
|
-
Args:
|
226
|
-
remote: Optional remote name to show configuration for
|
227
|
-
obscure: Show obscured passwords
|
228
|
-
no_obscure: Show passwords in plain text
|
229
|
-
|
230
|
-
Returns:
|
231
|
-
Configuration as text or an Exception if an error occurred
|
232
|
-
"""
|
233
|
-
return self.impl.config_paths(
|
234
|
-
remote=remote, obscure=obscure, no_obscure=no_obscure
|
235
|
-
)
|
236
|
-
|
237
|
-
def ls_stream(
|
238
|
-
self,
|
239
|
-
src: str,
|
240
|
-
max_depth: int = -1,
|
241
|
-
fast_list: bool = False,
|
242
|
-
) -> FilesStream:
|
243
|
-
"""
|
244
|
-
List files in the given path as a stream of results.
|
245
|
-
|
246
|
-
This method is memory-efficient for large directories as it yields
|
247
|
-
results incrementally rather than collecting them all at once.
|
248
|
-
|
249
|
-
Args:
|
250
|
-
src: Remote path to list
|
251
|
-
max_depth: Maximum recursion depth (-1 for unlimited)
|
252
|
-
fast_list: Use fast list (only recommended for listing entire repositories or small datasets)
|
253
|
-
|
254
|
-
Returns:
|
255
|
-
A stream of file entries that can be iterated over
|
256
|
-
"""
|
257
|
-
return self.impl.ls_stream(src=src, max_depth=max_depth, fast_list=fast_list)
|
258
|
-
|
259
|
-
def save_to_db(
|
260
|
-
self,
|
261
|
-
src: str,
|
262
|
-
db_url: str, # sqalchemy style url, use sqlite:///data.db or mysql://user:pass@localhost/db or postgres://user:pass@localhost/db
|
263
|
-
max_depth: int = -1,
|
264
|
-
fast_list: bool = False,
|
265
|
-
) -> None:
|
266
|
-
"""
|
267
|
-
Save files to a database (sqlite, mysql, postgres).
|
268
|
-
|
269
|
-
Lists all files in the source path and stores their metadata in a database.
|
270
|
-
Useful for creating searchable indexes of remote storage.
|
271
|
-
|
272
|
-
Args:
|
273
|
-
src: Remote path to list, this will be used to populate an entire table, so always use the root-most path.
|
274
|
-
db_url: Database URL, like sqlite:///data.db or mysql://user:pass@localhost/db or postgres://user:pass@localhost/db
|
275
|
-
max_depth: Maximum depth to traverse (-1 for unlimited)
|
276
|
-
fast_list: Use fast list (only use when getting THE entire data repository from the root/bucket)
|
277
|
-
"""
|
278
|
-
return self.impl.save_to_db(
|
279
|
-
src=src, db_url=db_url, max_depth=max_depth, fast_list=fast_list
|
280
|
-
)
|
281
|
-
|
282
|
-
def ls(
|
283
|
-
self,
|
284
|
-
src: Dir | Remote | str | None = None,
|
285
|
-
max_depth: int | None = None,
|
286
|
-
glob: str | None = None,
|
287
|
-
order: Order = Order.NORMAL,
|
288
|
-
listing_option: ListingOption = ListingOption.ALL,
|
289
|
-
) -> DirListing:
|
290
|
-
"""
|
291
|
-
List files and directories at the specified path.
|
292
|
-
|
293
|
-
Provides a detailed listing with file metadata.
|
294
|
-
|
295
|
-
Args:
|
296
|
-
src: Path to list (Dir, Remote, or string path)
|
297
|
-
max_depth: Maximum recursion depth (None for default)
|
298
|
-
glob: Optional glob pattern to filter results
|
299
|
-
order: Sorting order for the results
|
300
|
-
listing_option: What types of entries to include
|
301
|
-
|
302
|
-
Returns:
|
303
|
-
DirListing object containing the results
|
304
|
-
"""
|
305
|
-
return self.impl.ls(
|
306
|
-
src=src,
|
307
|
-
max_depth=max_depth,
|
308
|
-
glob=glob,
|
309
|
-
order=order,
|
310
|
-
listing_option=listing_option,
|
311
|
-
)
|
312
|
-
|
313
|
-
def listremotes(self) -> list[Remote]:
|
314
|
-
"""
|
315
|
-
List all configured remotes.
|
316
|
-
|
317
|
-
Returns a list of all remotes defined in the rclone configuration.
|
318
|
-
|
319
|
-
Returns:
|
320
|
-
List of Remote objects
|
321
|
-
"""
|
322
|
-
return self.impl.listremotes()
|
323
|
-
|
324
|
-
def diff(
|
325
|
-
self,
|
326
|
-
src: str,
|
327
|
-
dst: str,
|
328
|
-
min_size: (
|
329
|
-
str | None
|
330
|
-
) = None, # e. g. "1MB" - see rclone documentation: https://rclone.org/commands/rclone_check/
|
331
|
-
max_size: (
|
332
|
-
str | None
|
333
|
-
) = None, # e. g. "1GB" - see rclone documentation: https://rclone.org/commands/rclone_check/
|
334
|
-
diff_option: DiffOption = DiffOption.COMBINED,
|
335
|
-
fast_list: bool = True,
|
336
|
-
size_only: bool | None = None,
|
337
|
-
checkers: int | None = None,
|
338
|
-
other_args: list[str] | None = None,
|
339
|
-
) -> Generator[DiffItem, None, None]:
|
340
|
-
"""
|
341
|
-
Compare two directories and yield differences.
|
342
|
-
|
343
|
-
Be extra careful with the src and dst values. If you are off by one
|
344
|
-
parent directory, you will get a huge amount of false diffs.
|
345
|
-
|
346
|
-
Args:
|
347
|
-
src: Rclone style src path
|
348
|
-
dst: Rclone style dst path
|
349
|
-
min_size: Minimum file size to check (e.g., "1MB")
|
350
|
-
max_size: Maximum file size to check (e.g., "1GB")
|
351
|
-
diff_option: How to report differences
|
352
|
-
fast_list: Whether to use fast listing
|
353
|
-
size_only: Compare only file sizes, not content
|
354
|
-
checkers: Number of checker threads
|
355
|
-
other_args: Additional command-line arguments
|
356
|
-
|
357
|
-
Yields:
|
358
|
-
DiffItem objects representing each difference found
|
359
|
-
"""
|
360
|
-
return self.impl.diff(
|
361
|
-
src=src,
|
362
|
-
dst=dst,
|
363
|
-
min_size=min_size,
|
364
|
-
max_size=max_size,
|
365
|
-
diff_option=diff_option,
|
366
|
-
fast_list=fast_list,
|
367
|
-
size_only=size_only,
|
368
|
-
checkers=checkers,
|
369
|
-
other_args=other_args,
|
370
|
-
)
|
371
|
-
|
372
|
-
def walk(
|
373
|
-
self,
|
374
|
-
src: Dir | Remote | str,
|
375
|
-
max_depth: int = -1,
|
376
|
-
breadth_first: bool = True,
|
377
|
-
order: Order = Order.NORMAL,
|
378
|
-
) -> Generator[DirListing, None, None]:
|
379
|
-
"""
|
380
|
-
Walk through the given path recursively, yielding directory listings.
|
381
|
-
|
382
|
-
Similar to os.walk(), but for remote storage. Traverses directories
|
383
|
-
and yields their contents.
|
384
|
-
|
385
|
-
Args:
|
386
|
-
src: Remote path, Dir, or Remote object to walk through
|
387
|
-
max_depth: Maximum depth to traverse (-1 for unlimited)
|
388
|
-
breadth_first: If True, use breadth-first traversal, otherwise depth-first
|
389
|
-
order: Sorting order for directory entries
|
390
|
-
|
391
|
-
Yields:
|
392
|
-
DirListing: Directory listing for each directory encountered
|
393
|
-
"""
|
394
|
-
return self.impl.walk(
|
395
|
-
src=src, max_depth=max_depth, breadth_first=breadth_first, order=order
|
396
|
-
)
|
397
|
-
|
398
|
-
def scan_missing_folders(
|
399
|
-
self,
|
400
|
-
src: Dir | Remote | str,
|
401
|
-
dst: Dir | Remote | str,
|
402
|
-
max_depth: int = -1,
|
403
|
-
order: Order = Order.NORMAL,
|
404
|
-
) -> Generator[Dir, None, None]:
|
405
|
-
"""
|
406
|
-
Find folders that exist in source but are missing in destination.
|
407
|
-
|
408
|
-
Useful for identifying directories that need to be created before
|
409
|
-
copying files.
|
410
|
-
|
411
|
-
Args:
|
412
|
-
src: Source directory or Remote to scan
|
413
|
-
dst: Destination directory or Remote to compare against
|
414
|
-
max_depth: Maximum depth to traverse (-1 for unlimited)
|
415
|
-
order: Sorting order for directory entries
|
416
|
-
|
417
|
-
Yields:
|
418
|
-
Dir: Each directory that exists in source but not in destination
|
419
|
-
"""
|
420
|
-
return self.impl.scan_missing_folders(
|
421
|
-
src=src, dst=dst, max_depth=max_depth, order=order
|
422
|
-
)
|
423
|
-
|
424
|
-
def cleanup(
|
425
|
-
self, src: str, other_args: list[str] | None = None
|
426
|
-
) -> CompletedProcess:
|
427
|
-
"""
|
428
|
-
Cleanup any resources used by the Rclone instance.
|
429
|
-
|
430
|
-
Removes temporary files and directories created by rclone.
|
431
|
-
|
432
|
-
Args:
|
433
|
-
src: Path to clean up
|
434
|
-
other_args: Additional command-line arguments
|
435
|
-
|
436
|
-
Returns:
|
437
|
-
CompletedProcess with the result of the cleanup operation
|
438
|
-
"""
|
439
|
-
return self.impl.cleanup(src=src, other_args=other_args)
|
440
|
-
|
441
|
-
def copy_to(
|
442
|
-
self,
|
443
|
-
src: File | str,
|
444
|
-
dst: File | str,
|
445
|
-
check: bool | None = None,
|
446
|
-
verbose: bool | None = None,
|
447
|
-
other_args: list[str] | None = None,
|
448
|
-
) -> CompletedProcess:
|
449
|
-
"""
|
450
|
-
Copy one file from source to destination.
|
451
|
-
|
452
|
-
Warning - this can be slow for large files or when copying between
|
453
|
-
different storage providers.
|
454
|
-
|
455
|
-
Args:
|
456
|
-
src: Rclone style src path
|
457
|
-
dst: Rclone style dst path
|
458
|
-
check: Whether to verify the copy with checksums
|
459
|
-
verbose: Whether to show detailed progress
|
460
|
-
other_args: Additional command-line arguments
|
461
|
-
|
462
|
-
Returns:
|
463
|
-
CompletedProcess with the result of the copy operation
|
464
|
-
"""
|
465
|
-
return self.impl.copy_to(
|
466
|
-
src=src, dst=dst, check=check, verbose=verbose, other_args=other_args
|
467
|
-
)
|
468
|
-
|
469
|
-
def copy_files(
|
470
|
-
self,
|
471
|
-
src: str,
|
472
|
-
dst: str,
|
473
|
-
files: list[str] | Path,
|
474
|
-
check: bool | None = None,
|
475
|
-
max_backlog: int | None = None,
|
476
|
-
verbose: bool | None = None,
|
477
|
-
checkers: int | None = None,
|
478
|
-
transfers: int | None = None,
|
479
|
-
low_level_retries: int | None = None,
|
480
|
-
retries: int | None = None,
|
481
|
-
retries_sleep: str | None = None,
|
482
|
-
metadata: bool | None = None,
|
483
|
-
timeout: str | None = None,
|
484
|
-
max_partition_workers: int | None = None,
|
485
|
-
multi_thread_streams: int | None = None,
|
486
|
-
other_args: list[str] | None = None,
|
487
|
-
) -> list[CompletedProcess]:
|
488
|
-
"""
|
489
|
-
Copy multiple files from source to destination.
|
490
|
-
|
491
|
-
Efficiently copies a list of files, potentially in parallel.
|
492
|
-
|
493
|
-
Args:
|
494
|
-
src: Rclone style src path
|
495
|
-
dst: Rclone style dst path
|
496
|
-
files: List of file paths relative to src, or Path to a file containing the list
|
497
|
-
check: Whether to verify copies with checksums
|
498
|
-
max_backlog: Maximum number of queued transfers
|
499
|
-
verbose: Whether to show detailed progress
|
500
|
-
checkers: Number of checker threads
|
501
|
-
transfers: Number of file transfers to run in parallel
|
502
|
-
low_level_retries: Number of low-level retries
|
503
|
-
retries: Number of high-level retries
|
504
|
-
retries_sleep: Sleep interval between retries (e.g., "10s")
|
505
|
-
metadata: Whether to preserve metadata
|
506
|
-
timeout: IO idle timeout (e.g., "5m")
|
507
|
-
max_partition_workers: Maximum number of partition workers
|
508
|
-
multi_thread_streams: Number of streams for multi-thread copy
|
509
|
-
other_args: Additional command-line arguments
|
510
|
-
|
511
|
-
Returns:
|
512
|
-
List of CompletedProcess objects for each copy operation
|
513
|
-
"""
|
514
|
-
return self.impl.copy_files(
|
515
|
-
src=src,
|
516
|
-
dst=dst,
|
517
|
-
files=files,
|
518
|
-
check=check,
|
519
|
-
max_backlog=max_backlog,
|
520
|
-
verbose=verbose,
|
521
|
-
checkers=checkers,
|
522
|
-
transfers=transfers,
|
523
|
-
low_level_retries=low_level_retries,
|
524
|
-
retries=retries,
|
525
|
-
retries_sleep=retries_sleep,
|
526
|
-
metadata=metadata,
|
527
|
-
timeout=timeout,
|
528
|
-
max_partition_workers=max_partition_workers,
|
529
|
-
multi_thread_streams=multi_thread_streams,
|
530
|
-
other_args=other_args,
|
531
|
-
)
|
532
|
-
|
533
|
-
def copy(
|
534
|
-
self,
|
535
|
-
src: Dir | str,
|
536
|
-
dst: Dir | str,
|
537
|
-
check: bool | None = None,
|
538
|
-
transfers: int | None = None,
|
539
|
-
checkers: int | None = None,
|
540
|
-
multi_thread_streams: int | None = None,
|
541
|
-
low_level_retries: int | None = None,
|
542
|
-
retries: int | None = None,
|
543
|
-
other_args: list[str] | None = None,
|
544
|
-
) -> CompletedProcess:
|
545
|
-
"""
|
546
|
-
Copy files from source to destination.
|
547
|
-
|
548
|
-
Recursively copies all files from src to dst.
|
549
|
-
|
550
|
-
Args:
|
551
|
-
src: Rclone style src path
|
552
|
-
dst: Rclone style dst path
|
553
|
-
check: Whether to verify copies with checksums
|
554
|
-
transfers: Number of file transfers to run in parallel
|
555
|
-
checkers: Number of checker threads
|
556
|
-
multi_thread_streams: Number of streams for multi-thread copy
|
557
|
-
low_level_retries: Number of low-level retries
|
558
|
-
retries: Number of high-level retries
|
559
|
-
other_args: Additional command-line arguments
|
560
|
-
|
561
|
-
Returns:
|
562
|
-
CompletedProcess with the result of the copy operation
|
563
|
-
"""
|
564
|
-
return self.impl.copy(
|
565
|
-
src=src,
|
566
|
-
dst=dst,
|
567
|
-
check=check,
|
568
|
-
transfers=transfers,
|
569
|
-
checkers=checkers,
|
570
|
-
multi_thread_streams=multi_thread_streams,
|
571
|
-
low_level_retries=low_level_retries,
|
572
|
-
retries=retries,
|
573
|
-
other_args=other_args,
|
574
|
-
)
|
575
|
-
|
576
|
-
def purge(self, src: Dir | str) -> CompletedProcess:
|
577
|
-
"""
|
578
|
-
Purge a directory.
|
579
|
-
|
580
|
-
Removes a directory and all its contents.
|
581
|
-
|
582
|
-
Args:
|
583
|
-
src: Rclone style path
|
584
|
-
|
585
|
-
Returns:
|
586
|
-
CompletedProcess with the result of the purge operation
|
587
|
-
"""
|
588
|
-
return self.impl.purge(src=src)
|
589
|
-
|
590
|
-
def delete_files(
|
591
|
-
self,
|
592
|
-
files: str | File | list[str] | list[File],
|
593
|
-
check: bool | None = None,
|
594
|
-
rmdirs=False,
|
595
|
-
verbose: bool | None = None,
|
596
|
-
max_partition_workers: int | None = None,
|
597
|
-
other_args: list[str] | None = None,
|
598
|
-
) -> CompletedProcess:
|
599
|
-
"""
|
600
|
-
Delete files or directories.
|
601
|
-
|
602
|
-
Args:
|
603
|
-
files: Files to delete (single file/path or list)
|
604
|
-
check: Whether to verify deletions
|
605
|
-
rmdirs: Whether to remove empty directories
|
606
|
-
verbose: Whether to show detailed progress
|
607
|
-
max_partition_workers: Maximum number of partition workers
|
608
|
-
other_args: Additional command-line arguments
|
609
|
-
|
610
|
-
Returns:
|
611
|
-
CompletedProcess with the result of the delete operation
|
612
|
-
"""
|
613
|
-
return self.impl.delete_files(
|
614
|
-
files=files,
|
615
|
-
check=check,
|
616
|
-
rmdirs=rmdirs,
|
617
|
-
verbose=verbose,
|
618
|
-
max_partition_workers=max_partition_workers,
|
619
|
-
other_args=other_args,
|
620
|
-
)
|
621
|
-
|
622
|
-
def exists(self, src: Dir | Remote | str | File) -> bool:
|
623
|
-
"""
|
624
|
-
Check if a file or directory exists.
|
625
|
-
|
626
|
-
Args:
|
627
|
-
src: Path to check (Dir, Remote, File, or path string)
|
628
|
-
|
629
|
-
Returns:
|
630
|
-
True if the path exists, False otherwise
|
631
|
-
"""
|
632
|
-
return self.impl.exists(src=src)
|
633
|
-
|
634
|
-
def is_synced(self, src: str | Dir, dst: str | Dir) -> bool:
|
635
|
-
"""
|
636
|
-
Check if two directories are in sync.
|
637
|
-
|
638
|
-
Compares the contents of src and dst to determine if they match.
|
639
|
-
|
640
|
-
Args:
|
641
|
-
src: Source directory (Dir object or path string)
|
642
|
-
dst: Destination directory (Dir object or path string)
|
643
|
-
|
644
|
-
Returns:
|
645
|
-
True if the directories are in sync, False otherwise
|
646
|
-
"""
|
647
|
-
return self.impl.is_synced(src=src, dst=dst)
|
648
|
-
|
649
|
-
def modtime(self, src: str) -> str | Exception:
|
650
|
-
"""
|
651
|
-
Get the modification time of a file or directory.
|
652
|
-
|
653
|
-
Args:
|
654
|
-
src: Path to the file or directory
|
655
|
-
|
656
|
-
Returns:
|
657
|
-
Modification time as a string, or Exception if an error occurred
|
658
|
-
"""
|
659
|
-
return self.impl.modtime(src=src)
|
660
|
-
|
661
|
-
def modtime_dt(self, src: str) -> datetime | Exception:
|
662
|
-
"""
|
663
|
-
Get the modification time of a file or directory as a datetime object.
|
664
|
-
|
665
|
-
Args:
|
666
|
-
src: Path to the file or directory
|
667
|
-
|
668
|
-
Returns:
|
669
|
-
Modification time as a datetime object, or Exception if an error occurred
|
670
|
-
"""
|
671
|
-
return self.impl.modtime_dt(src=src)
|
672
|
-
|
673
|
-
def write_text(
|
674
|
-
self,
|
675
|
-
text: str,
|
676
|
-
dst: str,
|
677
|
-
) -> Exception | None:
|
678
|
-
"""
|
679
|
-
Write text to a file.
|
680
|
-
|
681
|
-
Creates or overwrites the file at dst with the given text.
|
682
|
-
|
683
|
-
Args:
|
684
|
-
text: Text content to write
|
685
|
-
dst: Destination file path
|
686
|
-
|
687
|
-
Returns:
|
688
|
-
None if successful, Exception if an error occurred
|
689
|
-
"""
|
690
|
-
return self.impl.write_text(text=text, dst=dst)
|
691
|
-
|
692
|
-
def write_bytes(
|
693
|
-
self,
|
694
|
-
data: bytes,
|
695
|
-
dst: str,
|
696
|
-
) -> Exception | None:
|
697
|
-
"""
|
698
|
-
Write bytes to a file.
|
699
|
-
|
700
|
-
Creates or overwrites the file at dst with the given binary data.
|
701
|
-
|
702
|
-
Args:
|
703
|
-
data: Binary content to write
|
704
|
-
dst: Destination file path
|
705
|
-
|
706
|
-
Returns:
|
707
|
-
None if successful, Exception if an error occurred
|
708
|
-
"""
|
709
|
-
return self.impl.write_bytes(data=data, dst=dst)
|
710
|
-
|
711
|
-
def read_bytes(self, src: str) -> bytes | Exception:
|
712
|
-
"""
|
713
|
-
Read bytes from a file.
|
714
|
-
|
715
|
-
Args:
|
716
|
-
src: Source file path
|
717
|
-
|
718
|
-
Returns:
|
719
|
-
File contents as bytes, or Exception if an error occurred
|
720
|
-
"""
|
721
|
-
return self.impl.read_bytes(src=src)
|
722
|
-
|
723
|
-
def read_text(self, src: str) -> str | Exception:
|
724
|
-
"""
|
725
|
-
Read text from a file.
|
726
|
-
|
727
|
-
Args:
|
728
|
-
src: Source file path
|
729
|
-
|
730
|
-
Returns:
|
731
|
-
File contents as a string, or Exception if an error occurred
|
732
|
-
"""
|
733
|
-
return self.impl.read_text(src=src)
|
734
|
-
|
735
|
-
def copy_bytes(
|
736
|
-
self,
|
737
|
-
src: str,
|
738
|
-
offset: int | SizeSuffix,
|
739
|
-
length: int | SizeSuffix,
|
740
|
-
outfile: Path,
|
741
|
-
other_args: list[str] | None = None,
|
742
|
-
) -> Exception | None:
|
743
|
-
"""
|
744
|
-
Copy a slice of bytes from the src file to dst.
|
745
|
-
|
746
|
-
Extracts a portion of a file based on offset and length.
|
747
|
-
|
748
|
-
Args:
|
749
|
-
src: Source file path
|
750
|
-
offset: Starting position in the source file
|
751
|
-
length: Number of bytes to copy
|
752
|
-
outfile: Local file path to write the bytes to
|
753
|
-
other_args: Additional command-line arguments
|
754
|
-
|
755
|
-
Returns:
|
756
|
-
None if successful, Exception if an error occurred
|
757
|
-
"""
|
758
|
-
return self.impl.copy_bytes(
|
759
|
-
src=src,
|
760
|
-
offset=offset,
|
761
|
-
length=length,
|
762
|
-
outfile=outfile,
|
763
|
-
other_args=other_args,
|
764
|
-
)
|
765
|
-
|
766
|
-
def copy_dir(
|
767
|
-
self, src: str | Dir, dst: str | Dir, args: list[str] | None = None
|
768
|
-
) -> CompletedProcess:
|
769
|
-
"""
|
770
|
-
Copy a directory from source to destination.
|
771
|
-
|
772
|
-
Recursively copies all files and subdirectories.
|
773
|
-
|
774
|
-
Args:
|
775
|
-
src: Source directory (Dir object or path string)
|
776
|
-
dst: Destination directory (Dir object or path string)
|
777
|
-
args: Additional command-line arguments
|
778
|
-
|
779
|
-
Returns:
|
780
|
-
CompletedProcess with the result of the copy operation
|
781
|
-
"""
|
782
|
-
# convert src to str, also dst
|
783
|
-
return self.impl.copy_dir(src=src, dst=dst, args=args)
|
784
|
-
|
785
|
-
def copy_remote(
|
786
|
-
self, src: Remote, dst: Remote, args: list[str] | None = None
|
787
|
-
) -> CompletedProcess:
|
788
|
-
"""
|
789
|
-
Copy a remote to another remote.
|
790
|
-
|
791
|
-
Copies all contents from one remote storage to another.
|
792
|
-
|
793
|
-
Args:
|
794
|
-
src: Source remote
|
795
|
-
dst: Destination remote
|
796
|
-
args: Additional command-line arguments
|
797
|
-
|
798
|
-
Returns:
|
799
|
-
CompletedProcess with the result of the copy operation
|
800
|
-
"""
|
801
|
-
return self.impl.copy_remote(src=src, dst=dst, args=args)
|
802
|
-
|
803
|
-
def copy_file_s3_resumable(
|
804
|
-
self,
|
805
|
-
src: str, # src:/Bucket/path/myfile.large.zst
|
806
|
-
dst: str, # dst:/Bucket/path/myfile.large.zst
|
807
|
-
part_infos: list[PartInfo] | None = None,
|
808
|
-
upload_threads: int = 8, # Number of reader and writer threads to use
|
809
|
-
merge_threads: int = 4, # Number of threads to use for merging the parts
|
810
|
-
) -> Exception | None:
|
811
|
-
"""
|
812
|
-
Copy a large file to S3 with resumable upload capability.
|
813
|
-
|
814
|
-
This method splits the file into parts for parallel upload and can
|
815
|
-
resume interrupted transfers using a custom algorithm in python.
|
816
|
-
|
817
|
-
Particularly useful for very large files where network interruptions
|
818
|
-
are likely.
|
819
|
-
|
820
|
-
Args:
|
821
|
-
src: Source file path (format: remote:bucket/path/file)
|
822
|
-
dst: Destination file path (format: remote:bucket/path/file)
|
823
|
-
part_infos: Optional list of part information for resuming uploads
|
824
|
-
upload_threads: Number of parallel upload threads
|
825
|
-
merge_threads: Number of threads for merging uploaded parts
|
826
|
-
|
827
|
-
Returns:
|
828
|
-
None if successful, Exception if an error occurred
|
829
|
-
"""
|
830
|
-
return self.impl.copy_file_s3_resumable(
|
831
|
-
src=src,
|
832
|
-
dst=dst,
|
833
|
-
part_infos=part_infos,
|
834
|
-
upload_threads=upload_threads,
|
835
|
-
merge_threads=merge_threads,
|
836
|
-
)
|
837
|
-
|
838
|
-
def mount(
|
839
|
-
self,
|
840
|
-
src: Remote | Dir | str,
|
841
|
-
outdir: Path,
|
842
|
-
allow_writes: bool | None = False,
|
843
|
-
transfers: int | None = None, # number of writes to perform in parallel
|
844
|
-
use_links: bool | None = None,
|
845
|
-
vfs_cache_mode: str | None = None,
|
846
|
-
verbose: bool | None = None,
|
847
|
-
cache_dir: Path | None = None,
|
848
|
-
cache_dir_delete_on_exit: bool | None = None,
|
849
|
-
log: Path | None = None,
|
850
|
-
other_args: list[str] | None = None,
|
851
|
-
) -> Mount:
|
852
|
-
"""
|
853
|
-
Mount a remote or directory to a local path.
|
854
|
-
|
855
|
-
Makes remote storage accessible as a local filesystem.
|
856
|
-
|
857
|
-
Args:
|
858
|
-
src: Remote or directory to mount
|
859
|
-
outdir: Local path to mount to
|
860
|
-
allow_writes: Whether to allow write operations
|
861
|
-
transfers: Number of parallel write operations
|
862
|
-
use_links: Whether to use symbolic links
|
863
|
-
vfs_cache_mode: VFS cache mode (e.g., "full", "minimal")
|
864
|
-
verbose: Whether to show detailed output
|
865
|
-
cache_dir: Directory to use for caching
|
866
|
-
cache_dir_delete_on_exit: Whether to delete cache on exit
|
867
|
-
log: Path to write logs to
|
868
|
-
other_args: Additional command-line arguments
|
869
|
-
|
870
|
-
Returns:
|
871
|
-
Mount object representing the mounted filesystem
|
872
|
-
"""
|
873
|
-
return self.impl.mount(
|
874
|
-
src=src,
|
875
|
-
outdir=outdir,
|
876
|
-
allow_writes=allow_writes,
|
877
|
-
transfers=transfers,
|
878
|
-
use_links=use_links,
|
879
|
-
vfs_cache_mode=vfs_cache_mode,
|
880
|
-
verbose=verbose,
|
881
|
-
cache_dir=cache_dir,
|
882
|
-
cache_dir_delete_on_exit=cache_dir_delete_on_exit,
|
883
|
-
log=log,
|
884
|
-
other_args=other_args,
|
885
|
-
)
|
886
|
-
|
887
|
-
def serve_http(
|
888
|
-
self,
|
889
|
-
src: str,
|
890
|
-
addr: str | None = None,
|
891
|
-
other_args: list[str] | None = None,
|
892
|
-
) -> HttpServer:
|
893
|
-
"""
|
894
|
-
Serve a remote or directory via HTTP.
|
895
|
-
|
896
|
-
Creates an HTTP server that provides access to the specified remote.
|
897
|
-
The returned HttpServer object includes a client for fetching files.
|
898
|
-
|
899
|
-
This is useful for providing web access to remote storage or for
|
900
|
-
accessing remote files from applications that support HTTP but not
|
901
|
-
the remote's native protocol.
|
902
|
-
|
903
|
-
Args:
|
904
|
-
src: Remote or directory to serve
|
905
|
-
addr: Network address and port to serve on (default: localhost:8080)
|
906
|
-
other_args: Additional arguments to pass to rclone
|
907
|
-
|
908
|
-
Returns:
|
909
|
-
HttpServer object with methods for accessing the served content
|
910
|
-
"""
|
911
|
-
return self.impl.serve_http(
|
912
|
-
src=src, cache_mode="minimal", addr=addr, other_args=other_args
|
913
|
-
)
|
914
|
-
|
915
|
-
def size_files(
|
916
|
-
self,
|
917
|
-
src: str,
|
918
|
-
files: list[str],
|
919
|
-
fast_list: bool = False, # Recommend that this is False
|
920
|
-
other_args: list[str] | None = None,
|
921
|
-
check: bool | None = False,
|
922
|
-
verbose: bool | None = None,
|
923
|
-
) -> SizeResult | Exception:
|
924
|
-
"""
|
925
|
-
Get the size of a list of files.
|
926
|
-
|
927
|
-
Calculates the total size of the specified files.
|
928
|
-
|
929
|
-
Args:
|
930
|
-
src: Base path for the files
|
931
|
-
files: List of file paths relative to src
|
932
|
-
fast_list: Whether to use fast listing (not recommended for accuracy)
|
933
|
-
other_args: Additional command-line arguments
|
934
|
-
check: Whether to verify file integrity
|
935
|
-
verbose: Whether to show detailed output
|
936
|
-
|
937
|
-
Returns:
|
938
|
-
SizeResult with size information, or Exception if an error occurred
|
939
|
-
|
940
|
-
Example:
|
941
|
-
size_files("remote:bucket", ["path/to/file1", "path/to/file2"])
|
942
|
-
"""
|
943
|
-
return self.impl.size_files(
|
944
|
-
src=src,
|
945
|
-
files=files,
|
946
|
-
fast_list=fast_list,
|
947
|
-
other_args=other_args,
|
948
|
-
check=check,
|
949
|
-
verbose=verbose,
|
950
|
-
)
|
951
|
-
|
952
|
-
def size_file(self, src: str) -> SizeSuffix | Exception:
|
953
|
-
"""
|
954
|
-
Get the size of a file.
|
955
|
-
|
956
|
-
Args:
|
957
|
-
src: Path to the file
|
958
|
-
|
959
|
-
Returns:
|
960
|
-
SizeSuffix object representing the file size, or Exception if an error occurred
|
961
|
-
"""
|
962
|
-
return self.impl.size_file(src=src)
|
963
|
-
|
964
|
-
|
965
|
-
# Export public API components
|
966
|
-
__all__ = [
|
967
|
-
# Main classes
|
968
|
-
"Rclone", # Primary interface
|
969
|
-
"File", # File representation
|
970
|
-
"Config", # Configuration handling
|
971
|
-
"Remote", # Remote storage
|
972
|
-
"Dir", # Directory representation
|
973
|
-
"RPath", # Remote path utilities
|
974
|
-
"DirListing", # Directory listing
|
975
|
-
"FileList", # File list
|
976
|
-
"FileItem", # File item
|
977
|
-
"Process", # Process management
|
978
|
-
"DiffItem", # Difference item
|
979
|
-
"DiffType", # Difference type
|
980
|
-
# Functions
|
981
|
-
"rclone_verbose", # Verbosity control
|
982
|
-
# Data classes and enums
|
983
|
-
"CompletedProcess", # Process result
|
984
|
-
"DiffOption", # Difference options
|
985
|
-
"ListingOption", # Listing options
|
986
|
-
"Order", # Sorting order
|
987
|
-
"SizeResult", # Size result
|
988
|
-
"Parsed", # Parsed configuration
|
989
|
-
"Section", # Configuration section
|
990
|
-
"MultiUploadResult", # S3 upload result
|
991
|
-
"SizeSuffix", # Size with suffix
|
992
|
-
# Utilities
|
993
|
-
"configure_logging", # Logging configuration
|
994
|
-
"log", # Logging utilities
|
995
|
-
"HttpServer", # HTTP server
|
996
|
-
"Range", # HTTP range
|
997
|
-
"HttpFetcher", # HTTP fetcher
|
998
|
-
"PartInfo", # Part information for uploads
|
999
|
-
"RealFS", # Real filesystem
|
1000
|
-
"RemoteFS", # Remote filesystem
|
1001
|
-
"FSPath", # File object backed by a real or remote filesystem
|
1002
|
-
"FilesStream",
|
1003
|
-
]
|
1
|
+
"""
|
2
|
+
Rclone API - Python interface for the Rclone command-line tool.
|
3
|
+
|
4
|
+
This package provides a high-level API for interacting with Rclone,
|
5
|
+
allowing file operations across various cloud storage providers.
|
6
|
+
The API wraps the rclone command-line tool, providing a Pythonic interface
|
7
|
+
for common operations like copying, listing, and managing remote storage.
|
8
|
+
"""
|
9
|
+
|
10
|
+
# Import core components and utilities
|
11
|
+
from datetime import datetime
|
12
|
+
from pathlib import Path
|
13
|
+
from typing import Generator
|
14
|
+
|
15
|
+
# Import logging utilities
|
16
|
+
from rclone_api import log
|
17
|
+
|
18
|
+
# Import data structures and models
|
19
|
+
from .completed_process import CompletedProcess
|
20
|
+
from .config import Config, Parsed, Section # Configuration handling
|
21
|
+
from .diff import DiffItem, DiffOption, DiffType # File comparison utilities
|
22
|
+
from .dir import Dir # Directory representation
|
23
|
+
from .dir_listing import DirListing # Directory contents representation
|
24
|
+
from .file import File, FileItem # File representation
|
25
|
+
from .file_stream import FilesStream # Streaming file listings
|
26
|
+
from .filelist import FileList # File list utilities
|
27
|
+
from .fs import FSPath, RealFS, RemoteFS # Filesystem utilities
|
28
|
+
from .http_server import HttpFetcher, HttpServer, Range # HTTP serving capabilities
|
29
|
+
|
30
|
+
# Import logging configuration utilities
|
31
|
+
from .log import configure_logging, setup_default_logging
|
32
|
+
from .mount import Mount # Mount remote filesystems
|
33
|
+
from .process import Process # Process management
|
34
|
+
from .remote import Remote # Remote storage representation
|
35
|
+
from .rpath import RPath # Remote path utilities
|
36
|
+
from .s3.types import MultiUploadResult # S3-specific types
|
37
|
+
from .types import ( # Common types
|
38
|
+
ListingOption,
|
39
|
+
Order,
|
40
|
+
PartInfo,
|
41
|
+
SizeResult,
|
42
|
+
SizeSuffix,
|
43
|
+
)
|
44
|
+
|
45
|
+
# Set up default logging configuration when the package is imported
|
46
|
+
setup_default_logging()
|
47
|
+
|
48
|
+
|
49
|
+
def rclone_verbose(val: bool | None) -> bool:
|
50
|
+
"""
|
51
|
+
Get or set the global verbosity setting for rclone operations.
|
52
|
+
|
53
|
+
Controls whether rclone commands will produce detailed output.
|
54
|
+
When enabled, commands will show more information about their operation.
|
55
|
+
|
56
|
+
Args:
|
57
|
+
val: If provided, sets the verbosity level. If None, returns the current setting.
|
58
|
+
|
59
|
+
Returns:
|
60
|
+
The current verbosity setting after any change.
|
61
|
+
"""
|
62
|
+
from rclone_api.rclone_impl import rclone_verbose as _rclone_verbose
|
63
|
+
|
64
|
+
return _rclone_verbose(val)
|
65
|
+
|
66
|
+
|
67
|
+
class Rclone:
|
68
|
+
"""
|
69
|
+
Main interface for interacting with Rclone.
|
70
|
+
|
71
|
+
This class provides methods for all major Rclone operations including
|
72
|
+
file transfers, listing, mounting, and remote management.
|
73
|
+
|
74
|
+
It serves as the primary entry point for the API, wrapping the underlying
|
75
|
+
implementation details and providing a clean, consistent interface.
|
76
|
+
"""
|
77
|
+
|
78
|
+
@staticmethod
|
79
|
+
def upgrade_rclone() -> Path:
|
80
|
+
"""
|
81
|
+
Upgrade the rclone executable to the latest version.
|
82
|
+
|
83
|
+
Downloads the latest rclone binary and replaces the current one.
|
84
|
+
|
85
|
+
If an external rclone is already in your path then although upgrade_rclone
|
86
|
+
will download the latest version, it will not affect the rclone selected.
|
87
|
+
|
88
|
+
Returns:
|
89
|
+
Path to the upgraded rclone executable
|
90
|
+
"""
|
91
|
+
from rclone_api.util import upgrade_rclone
|
92
|
+
|
93
|
+
return upgrade_rclone()
|
94
|
+
|
95
|
+
@staticmethod
|
96
|
+
def find_rclone_conf() -> Path | None:
|
97
|
+
"""Find the rclone configuration file from the environment or default locations."""
|
98
|
+
from rclone_api.config import find_conf_file
|
99
|
+
|
100
|
+
return find_conf_file()
|
101
|
+
|
102
|
+
def __init__(
|
103
|
+
self, rclone_conf: Path | Config | None, rclone_exe: Path | None = None
|
104
|
+
) -> None:
|
105
|
+
"""
|
106
|
+
Initialize the Rclone interface.
|
107
|
+
|
108
|
+
Args:
|
109
|
+
rclone_conf: Path to rclone config file or Config object
|
110
|
+
rclone_exe: Optional path to rclone executable. If None, will search in PATH.
|
111
|
+
"""
|
112
|
+
from rclone_api.rclone_impl import RcloneImpl
|
113
|
+
|
114
|
+
self.impl: RcloneImpl = RcloneImpl(rclone_conf, rclone_exe)
|
115
|
+
|
116
|
+
def webgui(self, other_args: list[str] | None = None) -> Process:
|
117
|
+
"""
|
118
|
+
Launch the Rclone web GUI.
|
119
|
+
|
120
|
+
Starts the built-in web interface for interacting with rclone.
|
121
|
+
|
122
|
+
Args:
|
123
|
+
other_args: Additional command-line arguments to pass to rclone
|
124
|
+
|
125
|
+
Returns:
|
126
|
+
Process object representing the running web GUI
|
127
|
+
"""
|
128
|
+
return self.impl.webgui(other_args=other_args)
|
129
|
+
|
130
|
+
def filesystem(self, src: str) -> RemoteFS:
|
131
|
+
"""
|
132
|
+
Get a RealFS object for interacting with the local filesystem.
|
133
|
+
|
134
|
+
Returns:
|
135
|
+
RealFS object for local filesystem operations
|
136
|
+
"""
|
137
|
+
return self.impl.filesystem(src=src)
|
138
|
+
|
139
|
+
def cwd(self, src: str) -> FSPath:
|
140
|
+
"""
|
141
|
+
Get the local root path for a filesystem.
|
142
|
+
|
143
|
+
Args:
|
144
|
+
src: Source path for the filesystem
|
145
|
+
|
146
|
+
Returns:
|
147
|
+
FSPath object representing the root of the filesystem
|
148
|
+
"""
|
149
|
+
return self.impl.cwd(src=src)
|
150
|
+
|
151
|
+
def launch_server(
|
152
|
+
self,
|
153
|
+
addr: str,
|
154
|
+
user: str | None = None,
|
155
|
+
password: str | None = None,
|
156
|
+
other_args: list[str] | None = None,
|
157
|
+
) -> Process:
|
158
|
+
"""
|
159
|
+
Launch the Rclone server so it can receive commands.
|
160
|
+
|
161
|
+
Starts an rclone server that can be controlled remotely.
|
162
|
+
|
163
|
+
Args:
|
164
|
+
addr: Address and port to listen on (e.g., "localhost:5572")
|
165
|
+
user: Optional username for authentication
|
166
|
+
password: Optional password for authentication
|
167
|
+
other_args: Additional command-line arguments
|
168
|
+
|
169
|
+
Returns:
|
170
|
+
Process object representing the running server
|
171
|
+
"""
|
172
|
+
return self.impl.launch_server(
|
173
|
+
addr=addr, user=user, password=password, other_args=other_args
|
174
|
+
)
|
175
|
+
|
176
|
+
def remote_control(
|
177
|
+
self,
|
178
|
+
addr: str,
|
179
|
+
user: str | None = None,
|
180
|
+
password: str | None = None,
|
181
|
+
capture: bool | None = None,
|
182
|
+
other_args: list[str] | None = None,
|
183
|
+
) -> CompletedProcess:
|
184
|
+
"""
|
185
|
+
Send commands to a running rclone server.
|
186
|
+
|
187
|
+
Args:
|
188
|
+
addr: Address of the rclone server (e.g., "localhost:5572")
|
189
|
+
user: Optional username for authentication
|
190
|
+
password: Optional password for authentication
|
191
|
+
capture: Whether to capture and return command output
|
192
|
+
other_args: Additional command-line arguments
|
193
|
+
|
194
|
+
Returns:
|
195
|
+
CompletedProcess containing the command result
|
196
|
+
"""
|
197
|
+
return self.impl.remote_control(
|
198
|
+
addr=addr,
|
199
|
+
user=user,
|
200
|
+
password=password,
|
201
|
+
capture=capture,
|
202
|
+
other_args=other_args,
|
203
|
+
)
|
204
|
+
|
205
|
+
def obscure(self, password: str) -> str:
|
206
|
+
"""
|
207
|
+
Obscure a password for use in rclone config files.
|
208
|
+
|
209
|
+
Converts a plaintext password to rclone's obscured format.
|
210
|
+
Note that this is not secure encryption, just light obfuscation.
|
211
|
+
|
212
|
+
Args:
|
213
|
+
password: The plaintext password to obscure
|
214
|
+
|
215
|
+
Returns:
|
216
|
+
The obscured password string
|
217
|
+
"""
|
218
|
+
return self.impl.obscure(password=password)
|
219
|
+
|
220
|
+
def config_show(
|
221
|
+
self, remote: str | None = None, obscure: bool = False, no_obscure: bool = False
|
222
|
+
) -> list[Path] | Exception:
|
223
|
+
"""Show the current configuration.
|
224
|
+
|
225
|
+
Args:
|
226
|
+
remote: Optional remote name to show configuration for
|
227
|
+
obscure: Show obscured passwords
|
228
|
+
no_obscure: Show passwords in plain text
|
229
|
+
|
230
|
+
Returns:
|
231
|
+
Configuration as text or an Exception if an error occurred
|
232
|
+
"""
|
233
|
+
return self.impl.config_paths(
|
234
|
+
remote=remote, obscure=obscure, no_obscure=no_obscure
|
235
|
+
)
|
236
|
+
|
237
|
+
def ls_stream(
|
238
|
+
self,
|
239
|
+
src: str,
|
240
|
+
max_depth: int = -1,
|
241
|
+
fast_list: bool = False,
|
242
|
+
) -> FilesStream:
|
243
|
+
"""
|
244
|
+
List files in the given path as a stream of results.
|
245
|
+
|
246
|
+
This method is memory-efficient for large directories as it yields
|
247
|
+
results incrementally rather than collecting them all at once.
|
248
|
+
|
249
|
+
Args:
|
250
|
+
src: Remote path to list
|
251
|
+
max_depth: Maximum recursion depth (-1 for unlimited)
|
252
|
+
fast_list: Use fast list (only recommended for listing entire repositories or small datasets)
|
253
|
+
|
254
|
+
Returns:
|
255
|
+
A stream of file entries that can be iterated over
|
256
|
+
"""
|
257
|
+
return self.impl.ls_stream(src=src, max_depth=max_depth, fast_list=fast_list)
|
258
|
+
|
259
|
+
def save_to_db(
|
260
|
+
self,
|
261
|
+
src: str,
|
262
|
+
db_url: str, # sqalchemy style url, use sqlite:///data.db or mysql://user:pass@localhost/db or postgres://user:pass@localhost/db
|
263
|
+
max_depth: int = -1,
|
264
|
+
fast_list: bool = False,
|
265
|
+
) -> None:
|
266
|
+
"""
|
267
|
+
Save files to a database (sqlite, mysql, postgres).
|
268
|
+
|
269
|
+
Lists all files in the source path and stores their metadata in a database.
|
270
|
+
Useful for creating searchable indexes of remote storage.
|
271
|
+
|
272
|
+
Args:
|
273
|
+
src: Remote path to list, this will be used to populate an entire table, so always use the root-most path.
|
274
|
+
db_url: Database URL, like sqlite:///data.db or mysql://user:pass@localhost/db or postgres://user:pass@localhost/db
|
275
|
+
max_depth: Maximum depth to traverse (-1 for unlimited)
|
276
|
+
fast_list: Use fast list (only use when getting THE entire data repository from the root/bucket)
|
277
|
+
"""
|
278
|
+
return self.impl.save_to_db(
|
279
|
+
src=src, db_url=db_url, max_depth=max_depth, fast_list=fast_list
|
280
|
+
)
|
281
|
+
|
282
|
+
def ls(
|
283
|
+
self,
|
284
|
+
src: Dir | Remote | str | None = None,
|
285
|
+
max_depth: int | None = None,
|
286
|
+
glob: str | None = None,
|
287
|
+
order: Order = Order.NORMAL,
|
288
|
+
listing_option: ListingOption = ListingOption.ALL,
|
289
|
+
) -> DirListing:
|
290
|
+
"""
|
291
|
+
List files and directories at the specified path.
|
292
|
+
|
293
|
+
Provides a detailed listing with file metadata.
|
294
|
+
|
295
|
+
Args:
|
296
|
+
src: Path to list (Dir, Remote, or string path)
|
297
|
+
max_depth: Maximum recursion depth (None for default)
|
298
|
+
glob: Optional glob pattern to filter results
|
299
|
+
order: Sorting order for the results
|
300
|
+
listing_option: What types of entries to include
|
301
|
+
|
302
|
+
Returns:
|
303
|
+
DirListing object containing the results
|
304
|
+
"""
|
305
|
+
return self.impl.ls(
|
306
|
+
src=src,
|
307
|
+
max_depth=max_depth,
|
308
|
+
glob=glob,
|
309
|
+
order=order,
|
310
|
+
listing_option=listing_option,
|
311
|
+
)
|
312
|
+
|
313
|
+
def listremotes(self) -> list[Remote]:
|
314
|
+
"""
|
315
|
+
List all configured remotes.
|
316
|
+
|
317
|
+
Returns a list of all remotes defined in the rclone configuration.
|
318
|
+
|
319
|
+
Returns:
|
320
|
+
List of Remote objects
|
321
|
+
"""
|
322
|
+
return self.impl.listremotes()
|
323
|
+
|
324
|
+
def diff(
|
325
|
+
self,
|
326
|
+
src: str,
|
327
|
+
dst: str,
|
328
|
+
min_size: (
|
329
|
+
str | None
|
330
|
+
) = None, # e. g. "1MB" - see rclone documentation: https://rclone.org/commands/rclone_check/
|
331
|
+
max_size: (
|
332
|
+
str | None
|
333
|
+
) = None, # e. g. "1GB" - see rclone documentation: https://rclone.org/commands/rclone_check/
|
334
|
+
diff_option: DiffOption = DiffOption.COMBINED,
|
335
|
+
fast_list: bool = True,
|
336
|
+
size_only: bool | None = None,
|
337
|
+
checkers: int | None = None,
|
338
|
+
other_args: list[str] | None = None,
|
339
|
+
) -> Generator[DiffItem, None, None]:
|
340
|
+
"""
|
341
|
+
Compare two directories and yield differences.
|
342
|
+
|
343
|
+
Be extra careful with the src and dst values. If you are off by one
|
344
|
+
parent directory, you will get a huge amount of false diffs.
|
345
|
+
|
346
|
+
Args:
|
347
|
+
src: Rclone style src path
|
348
|
+
dst: Rclone style dst path
|
349
|
+
min_size: Minimum file size to check (e.g., "1MB")
|
350
|
+
max_size: Maximum file size to check (e.g., "1GB")
|
351
|
+
diff_option: How to report differences
|
352
|
+
fast_list: Whether to use fast listing
|
353
|
+
size_only: Compare only file sizes, not content
|
354
|
+
checkers: Number of checker threads
|
355
|
+
other_args: Additional command-line arguments
|
356
|
+
|
357
|
+
Yields:
|
358
|
+
DiffItem objects representing each difference found
|
359
|
+
"""
|
360
|
+
return self.impl.diff(
|
361
|
+
src=src,
|
362
|
+
dst=dst,
|
363
|
+
min_size=min_size,
|
364
|
+
max_size=max_size,
|
365
|
+
diff_option=diff_option,
|
366
|
+
fast_list=fast_list,
|
367
|
+
size_only=size_only,
|
368
|
+
checkers=checkers,
|
369
|
+
other_args=other_args,
|
370
|
+
)
|
371
|
+
|
372
|
+
def walk(
|
373
|
+
self,
|
374
|
+
src: Dir | Remote | str,
|
375
|
+
max_depth: int = -1,
|
376
|
+
breadth_first: bool = True,
|
377
|
+
order: Order = Order.NORMAL,
|
378
|
+
) -> Generator[DirListing, None, None]:
|
379
|
+
"""
|
380
|
+
Walk through the given path recursively, yielding directory listings.
|
381
|
+
|
382
|
+
Similar to os.walk(), but for remote storage. Traverses directories
|
383
|
+
and yields their contents.
|
384
|
+
|
385
|
+
Args:
|
386
|
+
src: Remote path, Dir, or Remote object to walk through
|
387
|
+
max_depth: Maximum depth to traverse (-1 for unlimited)
|
388
|
+
breadth_first: If True, use breadth-first traversal, otherwise depth-first
|
389
|
+
order: Sorting order for directory entries
|
390
|
+
|
391
|
+
Yields:
|
392
|
+
DirListing: Directory listing for each directory encountered
|
393
|
+
"""
|
394
|
+
return self.impl.walk(
|
395
|
+
src=src, max_depth=max_depth, breadth_first=breadth_first, order=order
|
396
|
+
)
|
397
|
+
|
398
|
+
def scan_missing_folders(
|
399
|
+
self,
|
400
|
+
src: Dir | Remote | str,
|
401
|
+
dst: Dir | Remote | str,
|
402
|
+
max_depth: int = -1,
|
403
|
+
order: Order = Order.NORMAL,
|
404
|
+
) -> Generator[Dir, None, None]:
|
405
|
+
"""
|
406
|
+
Find folders that exist in source but are missing in destination.
|
407
|
+
|
408
|
+
Useful for identifying directories that need to be created before
|
409
|
+
copying files.
|
410
|
+
|
411
|
+
Args:
|
412
|
+
src: Source directory or Remote to scan
|
413
|
+
dst: Destination directory or Remote to compare against
|
414
|
+
max_depth: Maximum depth to traverse (-1 for unlimited)
|
415
|
+
order: Sorting order for directory entries
|
416
|
+
|
417
|
+
Yields:
|
418
|
+
Dir: Each directory that exists in source but not in destination
|
419
|
+
"""
|
420
|
+
return self.impl.scan_missing_folders(
|
421
|
+
src=src, dst=dst, max_depth=max_depth, order=order
|
422
|
+
)
|
423
|
+
|
424
|
+
def cleanup(
|
425
|
+
self, src: str, other_args: list[str] | None = None
|
426
|
+
) -> CompletedProcess:
|
427
|
+
"""
|
428
|
+
Cleanup any resources used by the Rclone instance.
|
429
|
+
|
430
|
+
Removes temporary files and directories created by rclone.
|
431
|
+
|
432
|
+
Args:
|
433
|
+
src: Path to clean up
|
434
|
+
other_args: Additional command-line arguments
|
435
|
+
|
436
|
+
Returns:
|
437
|
+
CompletedProcess with the result of the cleanup operation
|
438
|
+
"""
|
439
|
+
return self.impl.cleanup(src=src, other_args=other_args)
|
440
|
+
|
441
|
+
def copy_to(
|
442
|
+
self,
|
443
|
+
src: File | str,
|
444
|
+
dst: File | str,
|
445
|
+
check: bool | None = None,
|
446
|
+
verbose: bool | None = None,
|
447
|
+
other_args: list[str] | None = None,
|
448
|
+
) -> CompletedProcess:
|
449
|
+
"""
|
450
|
+
Copy one file from source to destination.
|
451
|
+
|
452
|
+
Warning - this can be slow for large files or when copying between
|
453
|
+
different storage providers.
|
454
|
+
|
455
|
+
Args:
|
456
|
+
src: Rclone style src path
|
457
|
+
dst: Rclone style dst path
|
458
|
+
check: Whether to verify the copy with checksums
|
459
|
+
verbose: Whether to show detailed progress
|
460
|
+
other_args: Additional command-line arguments
|
461
|
+
|
462
|
+
Returns:
|
463
|
+
CompletedProcess with the result of the copy operation
|
464
|
+
"""
|
465
|
+
return self.impl.copy_to(
|
466
|
+
src=src, dst=dst, check=check, verbose=verbose, other_args=other_args
|
467
|
+
)
|
468
|
+
|
469
|
+
def copy_files(
|
470
|
+
self,
|
471
|
+
src: str,
|
472
|
+
dst: str,
|
473
|
+
files: list[str] | Path,
|
474
|
+
check: bool | None = None,
|
475
|
+
max_backlog: int | None = None,
|
476
|
+
verbose: bool | None = None,
|
477
|
+
checkers: int | None = None,
|
478
|
+
transfers: int | None = None,
|
479
|
+
low_level_retries: int | None = None,
|
480
|
+
retries: int | None = None,
|
481
|
+
retries_sleep: str | None = None,
|
482
|
+
metadata: bool | None = None,
|
483
|
+
timeout: str | None = None,
|
484
|
+
max_partition_workers: int | None = None,
|
485
|
+
multi_thread_streams: int | None = None,
|
486
|
+
other_args: list[str] | None = None,
|
487
|
+
) -> list[CompletedProcess]:
|
488
|
+
"""
|
489
|
+
Copy multiple files from source to destination.
|
490
|
+
|
491
|
+
Efficiently copies a list of files, potentially in parallel.
|
492
|
+
|
493
|
+
Args:
|
494
|
+
src: Rclone style src path
|
495
|
+
dst: Rclone style dst path
|
496
|
+
files: List of file paths relative to src, or Path to a file containing the list
|
497
|
+
check: Whether to verify copies with checksums
|
498
|
+
max_backlog: Maximum number of queued transfers
|
499
|
+
verbose: Whether to show detailed progress
|
500
|
+
checkers: Number of checker threads
|
501
|
+
transfers: Number of file transfers to run in parallel
|
502
|
+
low_level_retries: Number of low-level retries
|
503
|
+
retries: Number of high-level retries
|
504
|
+
retries_sleep: Sleep interval between retries (e.g., "10s")
|
505
|
+
metadata: Whether to preserve metadata
|
506
|
+
timeout: IO idle timeout (e.g., "5m")
|
507
|
+
max_partition_workers: Maximum number of partition workers
|
508
|
+
multi_thread_streams: Number of streams for multi-thread copy
|
509
|
+
other_args: Additional command-line arguments
|
510
|
+
|
511
|
+
Returns:
|
512
|
+
List of CompletedProcess objects for each copy operation
|
513
|
+
"""
|
514
|
+
return self.impl.copy_files(
|
515
|
+
src=src,
|
516
|
+
dst=dst,
|
517
|
+
files=files,
|
518
|
+
check=check,
|
519
|
+
max_backlog=max_backlog,
|
520
|
+
verbose=verbose,
|
521
|
+
checkers=checkers,
|
522
|
+
transfers=transfers,
|
523
|
+
low_level_retries=low_level_retries,
|
524
|
+
retries=retries,
|
525
|
+
retries_sleep=retries_sleep,
|
526
|
+
metadata=metadata,
|
527
|
+
timeout=timeout,
|
528
|
+
max_partition_workers=max_partition_workers,
|
529
|
+
multi_thread_streams=multi_thread_streams,
|
530
|
+
other_args=other_args,
|
531
|
+
)
|
532
|
+
|
533
|
+
def copy(
|
534
|
+
self,
|
535
|
+
src: Dir | str,
|
536
|
+
dst: Dir | str,
|
537
|
+
check: bool | None = None,
|
538
|
+
transfers: int | None = None,
|
539
|
+
checkers: int | None = None,
|
540
|
+
multi_thread_streams: int | None = None,
|
541
|
+
low_level_retries: int | None = None,
|
542
|
+
retries: int | None = None,
|
543
|
+
other_args: list[str] | None = None,
|
544
|
+
) -> CompletedProcess:
|
545
|
+
"""
|
546
|
+
Copy files from source to destination.
|
547
|
+
|
548
|
+
Recursively copies all files from src to dst.
|
549
|
+
|
550
|
+
Args:
|
551
|
+
src: Rclone style src path
|
552
|
+
dst: Rclone style dst path
|
553
|
+
check: Whether to verify copies with checksums
|
554
|
+
transfers: Number of file transfers to run in parallel
|
555
|
+
checkers: Number of checker threads
|
556
|
+
multi_thread_streams: Number of streams for multi-thread copy
|
557
|
+
low_level_retries: Number of low-level retries
|
558
|
+
retries: Number of high-level retries
|
559
|
+
other_args: Additional command-line arguments
|
560
|
+
|
561
|
+
Returns:
|
562
|
+
CompletedProcess with the result of the copy operation
|
563
|
+
"""
|
564
|
+
return self.impl.copy(
|
565
|
+
src=src,
|
566
|
+
dst=dst,
|
567
|
+
check=check,
|
568
|
+
transfers=transfers,
|
569
|
+
checkers=checkers,
|
570
|
+
multi_thread_streams=multi_thread_streams,
|
571
|
+
low_level_retries=low_level_retries,
|
572
|
+
retries=retries,
|
573
|
+
other_args=other_args,
|
574
|
+
)
|
575
|
+
|
576
|
+
def purge(self, src: Dir | str) -> CompletedProcess:
|
577
|
+
"""
|
578
|
+
Purge a directory.
|
579
|
+
|
580
|
+
Removes a directory and all its contents.
|
581
|
+
|
582
|
+
Args:
|
583
|
+
src: Rclone style path
|
584
|
+
|
585
|
+
Returns:
|
586
|
+
CompletedProcess with the result of the purge operation
|
587
|
+
"""
|
588
|
+
return self.impl.purge(src=src)
|
589
|
+
|
590
|
+
def delete_files(
|
591
|
+
self,
|
592
|
+
files: str | File | list[str] | list[File],
|
593
|
+
check: bool | None = None,
|
594
|
+
rmdirs=False,
|
595
|
+
verbose: bool | None = None,
|
596
|
+
max_partition_workers: int | None = None,
|
597
|
+
other_args: list[str] | None = None,
|
598
|
+
) -> CompletedProcess:
|
599
|
+
"""
|
600
|
+
Delete files or directories.
|
601
|
+
|
602
|
+
Args:
|
603
|
+
files: Files to delete (single file/path or list)
|
604
|
+
check: Whether to verify deletions
|
605
|
+
rmdirs: Whether to remove empty directories
|
606
|
+
verbose: Whether to show detailed progress
|
607
|
+
max_partition_workers: Maximum number of partition workers
|
608
|
+
other_args: Additional command-line arguments
|
609
|
+
|
610
|
+
Returns:
|
611
|
+
CompletedProcess with the result of the delete operation
|
612
|
+
"""
|
613
|
+
return self.impl.delete_files(
|
614
|
+
files=files,
|
615
|
+
check=check,
|
616
|
+
rmdirs=rmdirs,
|
617
|
+
verbose=verbose,
|
618
|
+
max_partition_workers=max_partition_workers,
|
619
|
+
other_args=other_args,
|
620
|
+
)
|
621
|
+
|
622
|
+
def exists(self, src: Dir | Remote | str | File) -> bool:
|
623
|
+
"""
|
624
|
+
Check if a file or directory exists.
|
625
|
+
|
626
|
+
Args:
|
627
|
+
src: Path to check (Dir, Remote, File, or path string)
|
628
|
+
|
629
|
+
Returns:
|
630
|
+
True if the path exists, False otherwise
|
631
|
+
"""
|
632
|
+
return self.impl.exists(src=src)
|
633
|
+
|
634
|
+
def is_synced(self, src: str | Dir, dst: str | Dir) -> bool:
|
635
|
+
"""
|
636
|
+
Check if two directories are in sync.
|
637
|
+
|
638
|
+
Compares the contents of src and dst to determine if they match.
|
639
|
+
|
640
|
+
Args:
|
641
|
+
src: Source directory (Dir object or path string)
|
642
|
+
dst: Destination directory (Dir object or path string)
|
643
|
+
|
644
|
+
Returns:
|
645
|
+
True if the directories are in sync, False otherwise
|
646
|
+
"""
|
647
|
+
return self.impl.is_synced(src=src, dst=dst)
|
648
|
+
|
649
|
+
def modtime(self, src: str) -> str | Exception:
|
650
|
+
"""
|
651
|
+
Get the modification time of a file or directory.
|
652
|
+
|
653
|
+
Args:
|
654
|
+
src: Path to the file or directory
|
655
|
+
|
656
|
+
Returns:
|
657
|
+
Modification time as a string, or Exception if an error occurred
|
658
|
+
"""
|
659
|
+
return self.impl.modtime(src=src)
|
660
|
+
|
661
|
+
def modtime_dt(self, src: str) -> datetime | Exception:
|
662
|
+
"""
|
663
|
+
Get the modification time of a file or directory as a datetime object.
|
664
|
+
|
665
|
+
Args:
|
666
|
+
src: Path to the file or directory
|
667
|
+
|
668
|
+
Returns:
|
669
|
+
Modification time as a datetime object, or Exception if an error occurred
|
670
|
+
"""
|
671
|
+
return self.impl.modtime_dt(src=src)
|
672
|
+
|
673
|
+
def write_text(
|
674
|
+
self,
|
675
|
+
text: str,
|
676
|
+
dst: str,
|
677
|
+
) -> Exception | None:
|
678
|
+
"""
|
679
|
+
Write text to a file.
|
680
|
+
|
681
|
+
Creates or overwrites the file at dst with the given text.
|
682
|
+
|
683
|
+
Args:
|
684
|
+
text: Text content to write
|
685
|
+
dst: Destination file path
|
686
|
+
|
687
|
+
Returns:
|
688
|
+
None if successful, Exception if an error occurred
|
689
|
+
"""
|
690
|
+
return self.impl.write_text(text=text, dst=dst)
|
691
|
+
|
692
|
+
def write_bytes(
|
693
|
+
self,
|
694
|
+
data: bytes,
|
695
|
+
dst: str,
|
696
|
+
) -> Exception | None:
|
697
|
+
"""
|
698
|
+
Write bytes to a file.
|
699
|
+
|
700
|
+
Creates or overwrites the file at dst with the given binary data.
|
701
|
+
|
702
|
+
Args:
|
703
|
+
data: Binary content to write
|
704
|
+
dst: Destination file path
|
705
|
+
|
706
|
+
Returns:
|
707
|
+
None if successful, Exception if an error occurred
|
708
|
+
"""
|
709
|
+
return self.impl.write_bytes(data=data, dst=dst)
|
710
|
+
|
711
|
+
def read_bytes(self, src: str) -> bytes | Exception:
|
712
|
+
"""
|
713
|
+
Read bytes from a file.
|
714
|
+
|
715
|
+
Args:
|
716
|
+
src: Source file path
|
717
|
+
|
718
|
+
Returns:
|
719
|
+
File contents as bytes, or Exception if an error occurred
|
720
|
+
"""
|
721
|
+
return self.impl.read_bytes(src=src)
|
722
|
+
|
723
|
+
def read_text(self, src: str) -> str | Exception:
|
724
|
+
"""
|
725
|
+
Read text from a file.
|
726
|
+
|
727
|
+
Args:
|
728
|
+
src: Source file path
|
729
|
+
|
730
|
+
Returns:
|
731
|
+
File contents as a string, or Exception if an error occurred
|
732
|
+
"""
|
733
|
+
return self.impl.read_text(src=src)
|
734
|
+
|
735
|
+
def copy_bytes(
|
736
|
+
self,
|
737
|
+
src: str,
|
738
|
+
offset: int | SizeSuffix,
|
739
|
+
length: int | SizeSuffix,
|
740
|
+
outfile: Path,
|
741
|
+
other_args: list[str] | None = None,
|
742
|
+
) -> Exception | None:
|
743
|
+
"""
|
744
|
+
Copy a slice of bytes from the src file to dst.
|
745
|
+
|
746
|
+
Extracts a portion of a file based on offset and length.
|
747
|
+
|
748
|
+
Args:
|
749
|
+
src: Source file path
|
750
|
+
offset: Starting position in the source file
|
751
|
+
length: Number of bytes to copy
|
752
|
+
outfile: Local file path to write the bytes to
|
753
|
+
other_args: Additional command-line arguments
|
754
|
+
|
755
|
+
Returns:
|
756
|
+
None if successful, Exception if an error occurred
|
757
|
+
"""
|
758
|
+
return self.impl.copy_bytes(
|
759
|
+
src=src,
|
760
|
+
offset=offset,
|
761
|
+
length=length,
|
762
|
+
outfile=outfile,
|
763
|
+
other_args=other_args,
|
764
|
+
)
|
765
|
+
|
766
|
+
def copy_dir(
|
767
|
+
self, src: str | Dir, dst: str | Dir, args: list[str] | None = None
|
768
|
+
) -> CompletedProcess:
|
769
|
+
"""
|
770
|
+
Copy a directory from source to destination.
|
771
|
+
|
772
|
+
Recursively copies all files and subdirectories.
|
773
|
+
|
774
|
+
Args:
|
775
|
+
src: Source directory (Dir object or path string)
|
776
|
+
dst: Destination directory (Dir object or path string)
|
777
|
+
args: Additional command-line arguments
|
778
|
+
|
779
|
+
Returns:
|
780
|
+
CompletedProcess with the result of the copy operation
|
781
|
+
"""
|
782
|
+
# convert src to str, also dst
|
783
|
+
return self.impl.copy_dir(src=src, dst=dst, args=args)
|
784
|
+
|
785
|
+
def copy_remote(
|
786
|
+
self, src: Remote, dst: Remote, args: list[str] | None = None
|
787
|
+
) -> CompletedProcess:
|
788
|
+
"""
|
789
|
+
Copy a remote to another remote.
|
790
|
+
|
791
|
+
Copies all contents from one remote storage to another.
|
792
|
+
|
793
|
+
Args:
|
794
|
+
src: Source remote
|
795
|
+
dst: Destination remote
|
796
|
+
args: Additional command-line arguments
|
797
|
+
|
798
|
+
Returns:
|
799
|
+
CompletedProcess with the result of the copy operation
|
800
|
+
"""
|
801
|
+
return self.impl.copy_remote(src=src, dst=dst, args=args)
|
802
|
+
|
803
|
+
def copy_file_s3_resumable(
|
804
|
+
self,
|
805
|
+
src: str, # src:/Bucket/path/myfile.large.zst
|
806
|
+
dst: str, # dst:/Bucket/path/myfile.large.zst
|
807
|
+
part_infos: list[PartInfo] | None = None,
|
808
|
+
upload_threads: int = 8, # Number of reader and writer threads to use
|
809
|
+
merge_threads: int = 4, # Number of threads to use for merging the parts
|
810
|
+
) -> Exception | None:
|
811
|
+
"""
|
812
|
+
Copy a large file to S3 with resumable upload capability.
|
813
|
+
|
814
|
+
This method splits the file into parts for parallel upload and can
|
815
|
+
resume interrupted transfers using a custom algorithm in python.
|
816
|
+
|
817
|
+
Particularly useful for very large files where network interruptions
|
818
|
+
are likely.
|
819
|
+
|
820
|
+
Args:
|
821
|
+
src: Source file path (format: remote:bucket/path/file)
|
822
|
+
dst: Destination file path (format: remote:bucket/path/file)
|
823
|
+
part_infos: Optional list of part information for resuming uploads
|
824
|
+
upload_threads: Number of parallel upload threads
|
825
|
+
merge_threads: Number of threads for merging uploaded parts
|
826
|
+
|
827
|
+
Returns:
|
828
|
+
None if successful, Exception if an error occurred
|
829
|
+
"""
|
830
|
+
return self.impl.copy_file_s3_resumable(
|
831
|
+
src=src,
|
832
|
+
dst=dst,
|
833
|
+
part_infos=part_infos,
|
834
|
+
upload_threads=upload_threads,
|
835
|
+
merge_threads=merge_threads,
|
836
|
+
)
|
837
|
+
|
838
|
+
def mount(
|
839
|
+
self,
|
840
|
+
src: Remote | Dir | str,
|
841
|
+
outdir: Path,
|
842
|
+
allow_writes: bool | None = False,
|
843
|
+
transfers: int | None = None, # number of writes to perform in parallel
|
844
|
+
use_links: bool | None = None,
|
845
|
+
vfs_cache_mode: str | None = None,
|
846
|
+
verbose: bool | None = None,
|
847
|
+
cache_dir: Path | None = None,
|
848
|
+
cache_dir_delete_on_exit: bool | None = None,
|
849
|
+
log: Path | None = None,
|
850
|
+
other_args: list[str] | None = None,
|
851
|
+
) -> Mount:
|
852
|
+
"""
|
853
|
+
Mount a remote or directory to a local path.
|
854
|
+
|
855
|
+
Makes remote storage accessible as a local filesystem.
|
856
|
+
|
857
|
+
Args:
|
858
|
+
src: Remote or directory to mount
|
859
|
+
outdir: Local path to mount to
|
860
|
+
allow_writes: Whether to allow write operations
|
861
|
+
transfers: Number of parallel write operations
|
862
|
+
use_links: Whether to use symbolic links
|
863
|
+
vfs_cache_mode: VFS cache mode (e.g., "full", "minimal")
|
864
|
+
verbose: Whether to show detailed output
|
865
|
+
cache_dir: Directory to use for caching
|
866
|
+
cache_dir_delete_on_exit: Whether to delete cache on exit
|
867
|
+
log: Path to write logs to
|
868
|
+
other_args: Additional command-line arguments
|
869
|
+
|
870
|
+
Returns:
|
871
|
+
Mount object representing the mounted filesystem
|
872
|
+
"""
|
873
|
+
return self.impl.mount(
|
874
|
+
src=src,
|
875
|
+
outdir=outdir,
|
876
|
+
allow_writes=allow_writes,
|
877
|
+
transfers=transfers,
|
878
|
+
use_links=use_links,
|
879
|
+
vfs_cache_mode=vfs_cache_mode,
|
880
|
+
verbose=verbose,
|
881
|
+
cache_dir=cache_dir,
|
882
|
+
cache_dir_delete_on_exit=cache_dir_delete_on_exit,
|
883
|
+
log=log,
|
884
|
+
other_args=other_args,
|
885
|
+
)
|
886
|
+
|
887
|
+
def serve_http(
|
888
|
+
self,
|
889
|
+
src: str,
|
890
|
+
addr: str | None = None,
|
891
|
+
other_args: list[str] | None = None,
|
892
|
+
) -> HttpServer:
|
893
|
+
"""
|
894
|
+
Serve a remote or directory via HTTP.
|
895
|
+
|
896
|
+
Creates an HTTP server that provides access to the specified remote.
|
897
|
+
The returned HttpServer object includes a client for fetching files.
|
898
|
+
|
899
|
+
This is useful for providing web access to remote storage or for
|
900
|
+
accessing remote files from applications that support HTTP but not
|
901
|
+
the remote's native protocol.
|
902
|
+
|
903
|
+
Args:
|
904
|
+
src: Remote or directory to serve
|
905
|
+
addr: Network address and port to serve on (default: localhost:8080)
|
906
|
+
other_args: Additional arguments to pass to rclone
|
907
|
+
|
908
|
+
Returns:
|
909
|
+
HttpServer object with methods for accessing the served content
|
910
|
+
"""
|
911
|
+
return self.impl.serve_http(
|
912
|
+
src=src, cache_mode="minimal", addr=addr, other_args=other_args
|
913
|
+
)
|
914
|
+
|
915
|
+
def size_files(
|
916
|
+
self,
|
917
|
+
src: str,
|
918
|
+
files: list[str],
|
919
|
+
fast_list: bool = False, # Recommend that this is False
|
920
|
+
other_args: list[str] | None = None,
|
921
|
+
check: bool | None = False,
|
922
|
+
verbose: bool | None = None,
|
923
|
+
) -> SizeResult | Exception:
|
924
|
+
"""
|
925
|
+
Get the size of a list of files.
|
926
|
+
|
927
|
+
Calculates the total size of the specified files.
|
928
|
+
|
929
|
+
Args:
|
930
|
+
src: Base path for the files
|
931
|
+
files: List of file paths relative to src
|
932
|
+
fast_list: Whether to use fast listing (not recommended for accuracy)
|
933
|
+
other_args: Additional command-line arguments
|
934
|
+
check: Whether to verify file integrity
|
935
|
+
verbose: Whether to show detailed output
|
936
|
+
|
937
|
+
Returns:
|
938
|
+
SizeResult with size information, or Exception if an error occurred
|
939
|
+
|
940
|
+
Example:
|
941
|
+
size_files("remote:bucket", ["path/to/file1", "path/to/file2"])
|
942
|
+
"""
|
943
|
+
return self.impl.size_files(
|
944
|
+
src=src,
|
945
|
+
files=files,
|
946
|
+
fast_list=fast_list,
|
947
|
+
other_args=other_args,
|
948
|
+
check=check,
|
949
|
+
verbose=verbose,
|
950
|
+
)
|
951
|
+
|
952
|
+
def size_file(self, src: str) -> SizeSuffix | Exception:
|
953
|
+
"""
|
954
|
+
Get the size of a file.
|
955
|
+
|
956
|
+
Args:
|
957
|
+
src: Path to the file
|
958
|
+
|
959
|
+
Returns:
|
960
|
+
SizeSuffix object representing the file size, or Exception if an error occurred
|
961
|
+
"""
|
962
|
+
return self.impl.size_file(src=src)
|
963
|
+
|
964
|
+
|
965
|
+
# Export public API components
|
966
|
+
__all__ = [
|
967
|
+
# Main classes
|
968
|
+
"Rclone", # Primary interface
|
969
|
+
"File", # File representation
|
970
|
+
"Config", # Configuration handling
|
971
|
+
"Remote", # Remote storage
|
972
|
+
"Dir", # Directory representation
|
973
|
+
"RPath", # Remote path utilities
|
974
|
+
"DirListing", # Directory listing
|
975
|
+
"FileList", # File list
|
976
|
+
"FileItem", # File item
|
977
|
+
"Process", # Process management
|
978
|
+
"DiffItem", # Difference item
|
979
|
+
"DiffType", # Difference type
|
980
|
+
# Functions
|
981
|
+
"rclone_verbose", # Verbosity control
|
982
|
+
# Data classes and enums
|
983
|
+
"CompletedProcess", # Process result
|
984
|
+
"DiffOption", # Difference options
|
985
|
+
"ListingOption", # Listing options
|
986
|
+
"Order", # Sorting order
|
987
|
+
"SizeResult", # Size result
|
988
|
+
"Parsed", # Parsed configuration
|
989
|
+
"Section", # Configuration section
|
990
|
+
"MultiUploadResult", # S3 upload result
|
991
|
+
"SizeSuffix", # Size with suffix
|
992
|
+
# Utilities
|
993
|
+
"configure_logging", # Logging configuration
|
994
|
+
"log", # Logging utilities
|
995
|
+
"HttpServer", # HTTP server
|
996
|
+
"Range", # HTTP range
|
997
|
+
"HttpFetcher", # HTTP fetcher
|
998
|
+
"PartInfo", # Part information for uploads
|
999
|
+
"RealFS", # Real filesystem
|
1000
|
+
"RemoteFS", # Remote filesystem
|
1001
|
+
"FSPath", # File object backed by a real or remote filesystem
|
1002
|
+
"FilesStream",
|
1003
|
+
]
|