rclone-api 1.1.59__py2.py3-none-any.whl → 1.1.61__py2.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.
@@ -6,7 +6,6 @@ import argparse
6
6
  import os
7
7
  import shutil
8
8
  import time
9
- from concurrent.futures import Future, ThreadPoolExecutor
10
9
  from dataclasses import dataclass
11
10
  from pathlib import Path
12
11
 
@@ -108,7 +107,8 @@ def _run_profile(
108
107
  offset: SizeSuffix,
109
108
  size: SizeSuffix,
110
109
  log_dir: Path,
111
- direct_io: bool = True,
110
+ num: int,
111
+ direct_io: bool,
112
112
  ) -> None:
113
113
 
114
114
  mount_log = log_dir / f"mount_{SizeSuffix(size)}_threads_{transfers}.log"
@@ -118,12 +118,14 @@ def _run_profile(
118
118
  print("#" * 80)
119
119
  net_io_start = psutil.net_io_counters()
120
120
  start = time.time()
121
+ chunk_size = size // transfers
121
122
  bytes_or_err: bytes | Exception = rclone.copy_bytes(
122
123
  src=src_file,
123
124
  offset=offset.as_int(),
124
125
  length=size.as_int(),
126
+ chunk_size=chunk_size,
125
127
  direct_io=direct_io,
126
- transfers=transfers,
128
+ max_threads=transfers,
127
129
  mount_log=mount_log,
128
130
  )
129
131
  diff = time.time() - start
@@ -137,9 +139,11 @@ def _run_profile(
137
139
  assert len(bytes_or_err) == size.as_int(), f"Length: {len(bytes_or_err)} != {size}"
138
140
 
139
141
  # print io stats
140
- bytes_sent = net_io_end.bytes_sent - net_io_start.bytes_sent
141
- bytes_recv = net_io_end.bytes_recv - net_io_start.bytes_recv
142
- packets_sent = net_io_end.packets_sent - net_io_start.packets_sent
142
+ # disabling num for now
143
+ num = 1
144
+ bytes_sent = (net_io_end.bytes_sent - net_io_start.bytes_sent) // num
145
+ bytes_recv = (net_io_end.bytes_recv - net_io_start.bytes_recv) // num
146
+ packets_sent = (net_io_end.packets_sent - net_io_start.packets_sent) // num
143
147
  efficiency = size.as_int() / (bytes_recv)
144
148
  efficiency_100 = efficiency * 100
145
149
  efficiency_str = f"{efficiency_100:.2f}"
@@ -164,6 +168,7 @@ def test_profile_copy_bytes(
164
168
  transfer_list: list[int] | None,
165
169
  mount_root_path: Path,
166
170
  size: SizeSuffix | None,
171
+ num: int,
167
172
  ) -> None:
168
173
 
169
174
  if size:
@@ -197,6 +202,7 @@ def test_profile_copy_bytes(
197
202
  size=SizeSuffix(sz),
198
203
  direct_io=args.direct_io,
199
204
  log_dir=mount_root_path,
205
+ num=num,
200
206
  )
201
207
  print("done")
202
208
 
@@ -227,8 +233,8 @@ def main() -> None:
227
233
  shutil.rmtree(mount_root_path)
228
234
 
229
235
  args = _parse_args()
230
- transfer_list = [1]
231
- parallel_workers = args.num
236
+ transfer_list = [args.num]
237
+ # parallel_workers = args.num
232
238
 
233
239
  def task(
234
240
  offset: SizeSuffix,
@@ -244,14 +250,17 @@ def main() -> None:
244
250
  mount_root_path=mount_root_path,
245
251
  transfer_list=transfer_list,
246
252
  size=args.size,
253
+ num=args.num,
247
254
  )
248
255
 
249
- with ThreadPoolExecutor(max_workers=parallel_workers) as _:
250
- tasks: list[Future] = []
251
- for i in range(parallel_workers):
252
- offset = SizeSuffix(i * 1024 * 1024 * 256)
253
- future = ThreadPoolExecutor().submit(lambda: task(offset=offset))
254
- tasks.append(future)
256
+ task(SizeSuffix(0))
257
+
258
+ # with ThreadPoolExecutor(max_workers=parallel_workers) as _:
259
+ # tasks: list[Future] = []
260
+ # for i in range(parallel_workers):
261
+ # offset = SizeSuffix(i * 1024 * 1024 * 256)
262
+ # future = ThreadPoolExecutor().submit(lambda: task(offset=offset))
263
+ # tasks.append(future)
255
264
 
256
265
 
257
266
  if __name__ == "__main__":
rclone_api/rclone.py CHANGED
@@ -815,7 +815,7 @@ class Rclone:
815
815
  )
816
816
  return out
817
817
 
818
- def copy_bytes(
818
+ def _copy_bytes(
819
819
  self,
820
820
  src: str,
821
821
  offset: int,
@@ -844,7 +844,7 @@ class Rclone:
844
844
  max_read_ahead = SizeSuffix(vfs_read_chunk_size.as_int())
845
845
 
846
846
  # other_args += ["--vfs-read-chunk-size", str(vfs_read_chunk_size)]
847
- other_args += ["--vfs-read-chunk-size", str(0)]
847
+ other_args += ["--vfs-read-chunk-size", str(vfs_read_chunk_size)]
848
848
  other_args += ["--vfs-read-chunk-size-limit", str(vfs_read_chunk_size_limit)]
849
849
  other_args += ["--vfs-read-chunk-streams", str(vfs_read_chunk_streams)]
850
850
  other_args += ["--vfs-disk-space-total-size", str(vfs_disk_space_total_size)]
@@ -883,6 +883,64 @@ class Rclone:
883
883
  except Exception as e:
884
884
  return e
885
885
 
886
+ def copy_bytes(
887
+ self,
888
+ src: str,
889
+ offset: int,
890
+ length: int,
891
+ chunk_size: SizeSuffix,
892
+ max_threads: int = 1,
893
+ # If outfile is supplied then bytes are written to this file and success returns bytes(0)
894
+ outfile: Path | None = None,
895
+ mount_log: Path | None = None,
896
+ direct_io: bool = True,
897
+ ) -> bytes | Exception:
898
+ """Copy bytes from a file to another file."""
899
+ # determine number of threads from chunk size
900
+ threads = min(max_threads, length // chunk_size.as_int())
901
+
902
+ if threads == 1:
903
+ return self._copy_bytes(
904
+ src,
905
+ offset,
906
+ length,
907
+ transfers=1,
908
+ outfile=outfile,
909
+ mount_log=mount_log,
910
+ direct_io=direct_io,
911
+ )
912
+ else:
913
+ futures: list[Future] = []
914
+ with ThreadPoolExecutor(max_workers=threads) as executor:
915
+ for i in range(threads):
916
+ start = i * chunk_size.as_int()
917
+ end = start + chunk_size.as_int()
918
+ if i == threads - 1:
919
+ end = length
920
+ future = executor.submit(
921
+ self._copy_bytes,
922
+ src,
923
+ offset + start,
924
+ end - start,
925
+ transfers=1,
926
+ outfile=None,
927
+ mount_log=mount_log,
928
+ direct_io=direct_io,
929
+ )
930
+ futures.append(future)
931
+ data: bytes = b""
932
+ for future in futures:
933
+ chunk: bytes | Exception = future.result()
934
+ if isinstance(chunk, Exception):
935
+ return chunk
936
+ data += chunk
937
+ if outfile is not None:
938
+ with open(outfile, "wb") as out:
939
+ out.write(data)
940
+ del data
941
+ return bytes(0)
942
+ return data
943
+
886
944
  def copy_dir(
887
945
  self, src: str | Dir, dst: str | Dir, args: list[str] | None = None
888
946
  ) -> CompletedProcess:
rclone_api/types.py CHANGED
@@ -170,3 +170,11 @@ class SizeSuffix:
170
170
  raise ZeroDivisionError("Division by zero is undefined")
171
171
  # Use floor division to maintain integer arithmetic.
172
172
  return SizeSuffix(self._size // other_int._size)
173
+
174
+ # support / division
175
+ def __floordiv__(self, other: "int | SizeSuffix") -> "SizeSuffix":
176
+ other_int = SizeSuffix(other)
177
+ if other_int._size == 0:
178
+ raise ZeroDivisionError("Division by zero is undefined")
179
+ # Use floor division to maintain integer arithmetic.
180
+ return SizeSuffix(self._size // other_int._size)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.1.59
3
+ Version: 1.1.61
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  License: BSD 3-Clause License
@@ -13,11 +13,11 @@ rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
13
13
  rclone_api/group_files.py,sha256=H92xPW9lQnbNw5KbtZCl00bD6iRh9yRbCuxku4j_3dg,8036
14
14
  rclone_api/mount.py,sha256=5XiFwP7tst4h8cGQstZMJ0u5VzqFQ4YehnDl2AFP11A,10057
15
15
  rclone_api/process.py,sha256=rBj_S86jC6nqCYop-jq8r9eMSteKeObxUrJMgH8LZvI,5084
16
- rclone_api/rclone.py,sha256=eHIxAseumxEFHiJytdpRZ88gGy5qx3IKkU3yKYueWNA,43906
16
+ rclone_api/rclone.py,sha256=_bXkNBKeAVfjEOmX7bEwpxlXaJURJ3RguY1TJzwIBzM,46038
17
17
  rclone_api/remote.py,sha256=O9WDUFQy9f6oT1HdUbTixK2eg0xtBBm8k4Xl6aa6K00,431
18
18
  rclone_api/rpath.py,sha256=8ZA_1wxWtskwcy0I8V2VbjKDmzPkiWd8Q2JQSvh-sYE,2586
19
19
  rclone_api/scan_missing_folders.py,sha256=Kulca2Q6WZodt00ATFHkmqqInuoPvBkhTcS9703y6po,4740
20
- rclone_api/types.py,sha256=AWVIoCaRkUBCXOQffxdkFCOeUhPwolQh9d2albyAGHc,4730
20
+ rclone_api/types.py,sha256=2x9APG861HFrMwt5AIpxYI_ahDY09vUjGMtTE5xHlEs,5085
21
21
  rclone_api/util.py,sha256=_Z-GUMVXnHYOGdo2dy2ie2P5fGgyg8KdGjHKicx68Ko,4573
22
22
  rclone_api/walk.py,sha256=-54NVE8EJcCstwDoaC_UtHm73R2HrZwVwQmsnv55xNU,3369
23
23
  rclone_api/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
@@ -25,7 +25,7 @@ rclone_api/cmd/copy_large_s3.py,sha256=-rfedi-ZzPUdCSP8ai9LRL0y1xVkvN-viQQlk8HVU
25
25
  rclone_api/cmd/list_files.py,sha256=x8FHODEilwKqwdiU1jdkeJbLwOqUkUQuDWPo2u_zpf0,741
26
26
  rclone_api/experimental/flags.py,sha256=qCVD--fSTmzlk9hloRLr0q9elzAOFzPsvVpKM3aB1Mk,2739
27
27
  rclone_api/experimental/flags_base.py,sha256=ajU_czkTcAxXYU-SlmiCfHY7aCQGHvpCLqJ-Z8uZLk0,2102
28
- rclone_api/profile/mount_copy_bytes.py,sha256=ZfwKJ9hYQgFN8Xo2IWTQwvcTJf_DZgTxqVSHWUFrWUc,7522
28
+ rclone_api/profile/mount_copy_bytes.py,sha256=KJhn2ufpRwT9c9bH_q2RWvklw5x63nvI-UMtv9O8CPg,7717
29
29
  rclone_api/s3/api.py,sha256=qxtRDUpHYqJ7StJRtP8U_PbF_BvYRg705568SyvF-R0,3770
30
30
  rclone_api/s3/basic_ops.py,sha256=hK3366xhVEzEcjz9Gk_8lFx6MRceAk72cax6mUrr6ko,2104
31
31
  rclone_api/s3/chunk_file.py,sha256=D6wM9Nuu73LNGC8JCCfevqjF3qdZ21mQxYQClFLZLMU,3726
@@ -33,9 +33,9 @@ rclone_api/s3/chunk_types.py,sha256=LbXayXY1KgVU1LkdbASD_BQ7TpVpwVnzMjtz--8LBaE,
33
33
  rclone_api/s3/create.py,sha256=wgfkapv_j904CfKuWyiBIWJVxfAx_ftemFSUV14aT68,3149
34
34
  rclone_api/s3/types.py,sha256=yBnJ38Tjk6RlydJ-sqZ7DSfyFloy8KDYJ0mv3vlOzLE,1388
35
35
  rclone_api/s3/upload_file_multipart.py,sha256=y9azNAU8QH5Ovwz33V2HZwNmJdlFjJg-jrXLZ1gtMds,10364
36
- rclone_api-1.1.59.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
37
- rclone_api-1.1.59.dist-info/METADATA,sha256=QqrdtjJ4QCKu2FgqOVTNYX1z9J65tfdF7EsKUqvrHcg,4537
38
- rclone_api-1.1.59.dist-info/WHEEL,sha256=rF4EZyR2XVS6irmOHQIJx2SUqXLZKRMUrjsg8UwN-XQ,109
39
- rclone_api-1.1.59.dist-info/entry_points.txt,sha256=TV8kwP3FRzYwUEr0RLC7aJh0W03SAefIJNXTJ-FdMIQ,200
40
- rclone_api-1.1.59.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
41
- rclone_api-1.1.59.dist-info/RECORD,,
36
+ rclone_api-1.1.61.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
37
+ rclone_api-1.1.61.dist-info/METADATA,sha256=K94aUUT1DvHqha4sUrmbKR18VbBosxwPVUW0tQLAKqU,4537
38
+ rclone_api-1.1.61.dist-info/WHEEL,sha256=rF4EZyR2XVS6irmOHQIJx2SUqXLZKRMUrjsg8UwN-XQ,109
39
+ rclone_api-1.1.61.dist-info/entry_points.txt,sha256=TV8kwP3FRzYwUEr0RLC7aJh0W03SAefIJNXTJ-FdMIQ,200
40
+ rclone_api-1.1.61.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
41
+ rclone_api-1.1.61.dist-info/RECORD,,