rclone-api 1.1.45__tar.gz → 1.1.47__tar.gz

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.
Files changed (86) hide show
  1. {rclone_api-1.1.45 → rclone_api-1.1.47}/PKG-INFO +1 -1
  2. {rclone_api-1.1.45 → rclone_api-1.1.47}/pyproject.toml +1 -1
  3. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/mount.py +13 -0
  4. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/profile/mount_copy_bytes.py +25 -5
  5. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/rclone.py +45 -25
  6. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api.egg-info/PKG-INFO +1 -1
  7. {rclone_api-1.1.45 → rclone_api-1.1.47}/.aiderignore +0 -0
  8. {rclone_api-1.1.45 → rclone_api-1.1.47}/.github/workflows/lint.yml +0 -0
  9. {rclone_api-1.1.45 → rclone_api-1.1.47}/.github/workflows/push_macos.yml +0 -0
  10. {rclone_api-1.1.45 → rclone_api-1.1.47}/.github/workflows/push_ubuntu.yml +0 -0
  11. {rclone_api-1.1.45 → rclone_api-1.1.47}/.github/workflows/push_win.yml +0 -0
  12. {rclone_api-1.1.45 → rclone_api-1.1.47}/.gitignore +0 -0
  13. {rclone_api-1.1.45 → rclone_api-1.1.47}/.pylintrc +0 -0
  14. {rclone_api-1.1.45 → rclone_api-1.1.47}/.vscode/launch.json +0 -0
  15. {rclone_api-1.1.45 → rclone_api-1.1.47}/.vscode/settings.json +0 -0
  16. {rclone_api-1.1.45 → rclone_api-1.1.47}/.vscode/tasks.json +0 -0
  17. {rclone_api-1.1.45 → rclone_api-1.1.47}/LICENSE +0 -0
  18. {rclone_api-1.1.45 → rclone_api-1.1.47}/MANIFEST.in +0 -0
  19. {rclone_api-1.1.45 → rclone_api-1.1.47}/README.md +0 -0
  20. {rclone_api-1.1.45 → rclone_api-1.1.47}/clean +0 -0
  21. {rclone_api-1.1.45 → rclone_api-1.1.47}/install +0 -0
  22. {rclone_api-1.1.45 → rclone_api-1.1.47}/lint +0 -0
  23. {rclone_api-1.1.45 → rclone_api-1.1.47}/requirements.testing.txt +0 -0
  24. {rclone_api-1.1.45 → rclone_api-1.1.47}/setup.cfg +0 -0
  25. {rclone_api-1.1.45 → rclone_api-1.1.47}/setup.py +0 -0
  26. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/__init__.py +0 -0
  27. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/assets/example.txt +0 -0
  28. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/cli.py +0 -0
  29. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/cmd/copy_large_s3.py +0 -0
  30. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/cmd/list_files.py +0 -0
  31. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/completed_process.py +0 -0
  32. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/config.py +0 -0
  33. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/convert.py +0 -0
  34. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/deprecated.py +0 -0
  35. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/diff.py +0 -0
  36. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/dir.py +0 -0
  37. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/dir_listing.py +0 -0
  38. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/exec.py +0 -0
  39. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/experimental/flags.py +0 -0
  40. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/experimental/flags_base.py +0 -0
  41. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/file.py +0 -0
  42. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/filelist.py +0 -0
  43. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/group_files.py +0 -0
  44. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/process.py +0 -0
  45. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/remote.py +0 -0
  46. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/rpath.py +0 -0
  47. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/s3/api.py +0 -0
  48. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/s3/basic_ops.py +0 -0
  49. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/s3/chunk_file.py +0 -0
  50. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/s3/chunk_types.py +0 -0
  51. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/s3/create.py +0 -0
  52. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/s3/types.py +0 -0
  53. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/s3/upload_file_multipart.py +0 -0
  54. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/scan_missing_folders.py +0 -0
  55. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/types.py +0 -0
  56. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/util.py +0 -0
  57. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api/walk.py +0 -0
  58. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api.egg-info/SOURCES.txt +0 -0
  59. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  60. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api.egg-info/entry_points.txt +0 -0
  61. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api.egg-info/requires.txt +0 -0
  62. {rclone_api-1.1.45 → rclone_api-1.1.47}/src/rclone_api.egg-info/top_level.txt +0 -0
  63. {rclone_api-1.1.45 → rclone_api-1.1.47}/test +0 -0
  64. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/archive/test_paramiko.py.disabled +0 -0
  65. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_cmd_list_files.py +0 -0
  66. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_copy.py +0 -0
  67. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_copy_bytes.py +0 -0
  68. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_copy_file_resumable_s3.py +0 -0
  69. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_copy_files.py +0 -0
  70. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_diff.py +0 -0
  71. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_group_files.py +0 -0
  72. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_is_synced.py +0 -0
  73. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_ls.py +0 -0
  74. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_mount.py +0 -0
  75. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_mount_s3.py +0 -0
  76. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_obscure.py +0 -0
  77. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_rclone_config.py +0 -0
  78. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_remote_control.py +0 -0
  79. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_remotes.py +0 -0
  80. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_s3.py +0 -0
  81. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_scan_missing_folders.py +0 -0
  82. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_size_files.py +0 -0
  83. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_size_suffix.py +0 -0
  84. {rclone_api-1.1.45 → rclone_api-1.1.47}/tests/test_walk.py +0 -0
  85. {rclone_api-1.1.45 → rclone_api-1.1.47}/tox.ini +0 -0
  86. {rclone_api-1.1.45 → rclone_api-1.1.47}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.1.45
3
+ Version: 1.1.47
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  License: BSD 3-Clause License
@@ -23,7 +23,7 @@ dependencies = [
23
23
  ]
24
24
 
25
25
  # Change this with the version number bump.
26
- version = "1.1.45"
26
+ version = "1.1.47"
27
27
 
28
28
  [tool.setuptools]
29
29
  package-dir = {"" = "src"}
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import platform
3
+ import shutil
3
4
  import subprocess
4
5
  import time
5
6
  import warnings
@@ -19,6 +20,8 @@ class Mount:
19
20
  mount_path: Path
20
21
  process: Process
21
22
  read_only: bool
23
+ cache_dir: Path | None = None
24
+ cache_dir_delete_on_exit: bool | None = None
22
25
  _closed: bool = False
23
26
 
24
27
  def __post_init__(self):
@@ -32,6 +35,8 @@ class Mount:
32
35
  return
33
36
  self._closed = True
34
37
  clean_mount(self, verbose=False, wait=wait)
38
+ if self.cache_dir and self.cache_dir_delete_on_exit:
39
+ _cache_dir_delete_on_exit(self.cache_dir)
35
40
 
36
41
  def __enter__(self) -> "Mount":
37
42
  return self
@@ -179,3 +184,11 @@ def clean_mount(mount: Mount | Path, verbose: bool = False, wait=True) -> None:
179
184
  else:
180
185
  if verbose:
181
186
  print(f"{mount_path} successfully cleaned up.")
187
+
188
+
189
+ def _cache_dir_delete_on_exit(cache_dir: Path) -> None:
190
+ if cache_dir.exists():
191
+ try:
192
+ shutil.rmtree(cache_dir)
193
+ except Exception as e:
194
+ warnings.warn(f"Error removing cache directory {cache_dir}: {e}")
@@ -2,6 +2,7 @@
2
2
  Unit test file.
3
3
  """
4
4
 
5
+ import argparse
5
6
  import os
6
7
  import shutil
7
8
  import time
@@ -14,6 +15,11 @@ from dotenv import load_dotenv
14
15
  from rclone_api import Config, Rclone, SizeSuffix
15
16
 
16
17
 
18
+ @dataclass
19
+ class Args:
20
+ direct_io: bool
21
+
22
+
17
23
  @dataclass
18
24
  class Credentials:
19
25
  BUCKET_KEY_SECRET: str
@@ -105,7 +111,12 @@ def _init() -> None:
105
111
 
106
112
 
107
113
  def _run_profile(
108
- rclone: Rclone, src_file: str, transfers: int, size: int, log_dir: Path
114
+ rclone: Rclone,
115
+ src_file: str,
116
+ transfers: int,
117
+ size: int,
118
+ log_dir: Path,
119
+ direct_io: bool = True,
109
120
  ) -> None:
110
121
 
111
122
  mount_log = log_dir / f"mount_{SizeSuffix(size)}_threads_{transfers}.log"
@@ -119,7 +130,7 @@ def _run_profile(
119
130
  src=src_file,
120
131
  offset=0,
121
132
  length=size,
122
- direct_io=True,
133
+ direct_io=direct_io,
123
134
  transfers=transfers,
124
135
  mount_log=mount_log,
125
136
  )
@@ -154,7 +165,7 @@ def _run_profile(
154
165
  print(f"Time: {diff:.1f} seconds")
155
166
 
156
167
 
157
- def test_profile_copy_bytes() -> None:
168
+ def test_profile_copy_bytes(args: Args) -> None:
158
169
  print("Running test_profile_copy_bytes")
159
170
  config, creds = _generate_rclone_config()
160
171
  print("Config:")
@@ -179,7 +190,7 @@ def test_profile_copy_bytes() -> None:
179
190
  # sftp mount
180
191
  src_file = "src:aa_misc_data/aa_misc_data/world_lending_library_2024_11.tar.zst"
181
192
 
182
- mount_root_path = Path("logs") / "mount"
193
+ mount_root_path = Path("rclone_logs") / "mount"
183
194
  if mount_root_path.exists():
184
195
  shutil.rmtree(mount_root_path)
185
196
 
@@ -190,15 +201,24 @@ def test_profile_copy_bytes() -> None:
190
201
  src_file=src_file,
191
202
  transfers=transfers,
192
203
  size=size,
204
+ direct_io=args.direct_io,
193
205
  log_dir=mount_root_path,
194
206
  )
195
207
  print("done")
196
208
 
197
209
 
210
+ def _parse_args() -> Args:
211
+ parser = argparse.ArgumentParser(description="Profile copy_bytes")
212
+ parser.add_argument("--direct-io", help="Use direct IO", action="store_true")
213
+ args = parser.parse_args()
214
+ return Args(direct_io=args.direct_io)
215
+
216
+
198
217
  def main() -> None:
199
218
  """Main entry point."""
200
219
  _init()
201
- test_profile_copy_bytes()
220
+ args = _parse_args()
221
+ test_profile_copy_bytes(args)
202
222
 
203
223
 
204
224
  if __name__ == "__main__":
@@ -852,30 +852,35 @@ class Rclone:
852
852
  if direct_io:
853
853
  other_args += ["--direct-io"]
854
854
 
855
- try:
856
- # use scoped mount to do the read, then write the bytes to the destination
857
- with self.scoped_mount(
858
- src_parent_path,
859
- tmp_mnt,
860
- use_links=True,
861
- verbose=mount_log is not None,
862
- vfs_cache_mode="minimal",
863
- other_args=other_args,
864
- log=mount_log,
865
- ):
866
- src_file_mnt = tmp_mnt / src_file
867
- with open(src_file_mnt, "rb") as f:
868
- f.seek(offset)
869
- data = f.read(length)
870
- if outfile is None:
871
- return data
872
- with open(outfile, "wb") as out:
873
- out.write(data)
874
- del data
875
- return bytes(0)
876
-
877
- except Exception as e:
878
- return e
855
+ with TemporaryDirectory() as tmpdir:
856
+ cache_dir = Path(tmpdir) / "cache"
857
+ other_args += ["--cache-dir", str(cache_dir.absolute())]
858
+ try:
859
+ # use scoped mount to do the read, then write the bytes to the destination
860
+ with self.scoped_mount(
861
+ src_parent_path,
862
+ tmp_mnt,
863
+ use_links=True,
864
+ verbose=mount_log is not None,
865
+ vfs_cache_mode="minimal",
866
+ other_args=other_args,
867
+ log=mount_log,
868
+ cache_dir=cache_dir,
869
+ cache_dir_delete_on_exit=True,
870
+ ):
871
+ src_file_mnt = tmp_mnt / src_file
872
+ with open(src_file_mnt, "rb") as f:
873
+ f.seek(offset)
874
+ data = f.read(length)
875
+ if outfile is None:
876
+ return data
877
+ with open(outfile, "wb") as out:
878
+ out.write(data)
879
+ del data
880
+ return bytes(0)
881
+
882
+ except Exception as e:
883
+ return e
879
884
 
880
885
  def copy_dir(
881
886
  self, src: str | Dir, dst: str | Dir, args: list[str] | None = None
@@ -909,6 +914,8 @@ class Rclone:
909
914
  use_links: bool | None = None,
910
915
  vfs_cache_mode: str | None = None,
911
916
  verbose: bool | None = None,
917
+ cache_dir: Path | None = None,
918
+ cache_dir_delete_on_exit: bool | None = None,
912
919
  log: Path | None = None,
913
920
  other_args: list[str] | None = None,
914
921
  ) -> Mount:
@@ -941,6 +948,9 @@ class Rclone:
941
948
  if vfs_cache_mode:
942
949
  cmd_list.append("--vfs-cache-mode")
943
950
  cmd_list.append(vfs_cache_mode)
951
+ if cache_dir:
952
+ cmd_list.append("--cache-dir")
953
+ cmd_list.append(str(cache_dir.absolute()))
944
954
  if debug_fuse:
945
955
  cmd_list.append("--debug-fuse")
946
956
  if verbose:
@@ -949,7 +959,13 @@ class Rclone:
949
959
  cmd_list += other_args
950
960
  proc = self._launch_process(cmd_list, log=log)
951
961
  mount_read_only = not allow_writes
952
- mount: Mount = Mount(mount_path=outdir, process=proc, read_only=mount_read_only)
962
+ mount: Mount = Mount(
963
+ mount_path=outdir,
964
+ process=proc,
965
+ read_only=mount_read_only,
966
+ cache_dir=cache_dir,
967
+ cache_dir_delete_on_exit=cache_dir_delete_on_exit,
968
+ )
953
969
  return mount
954
970
 
955
971
  @contextmanager
@@ -962,6 +978,8 @@ class Rclone:
962
978
  vfs_cache_mode: str | None = None,
963
979
  verbose: bool | None = None,
964
980
  log: Path | None = None,
981
+ cache_dir: Path | None = None,
982
+ cache_dir_delete_on_exit: bool | None = None,
965
983
  other_args: list[str] | None = None,
966
984
  ) -> Generator[Mount, None, None]:
967
985
  """Like mount, but can be used in a context manager."""
@@ -973,6 +991,8 @@ class Rclone:
973
991
  use_links=use_links,
974
992
  vfs_cache_mode=vfs_cache_mode,
975
993
  verbose=verbose,
994
+ cache_dir=cache_dir,
995
+ cache_dir_delete_on_exit=cache_dir_delete_on_exit,
976
996
  log=log,
977
997
  other_args=other_args,
978
998
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.1.45
3
+ Version: 1.1.47
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  License: BSD 3-Clause License
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes