@@ -55,7 +55,7 @@ def checksum(
55
55
MD5 checksum
56
56
57
57
Raises:
58
- FileNotFoundError : if file does not exist on backend
58
+ BackendError : if an error is raised on the backend
59
59
ValueError: if ``path`` contains invalid character
60
60
61
61
Examples:
@@ -64,10 +64,12 @@ def checksum(
64
64
65
65
"""
66
66
utils .check_path_for_allowed_chars (path )
67
- if not self ._exists (path , version ):
68
- utils .raise_file_not_found_error (path , version = version )
69
67
70
- return self ._checksum (path , version )
68
+ return utils .call_function_on_backend (
69
+ self ._checksum ,
70
+ path ,
71
+ version ,
72
+ )
71
73
72
74
def _exists (
73
75
self ,
@@ -92,6 +94,7 @@ def exists(
92
94
``True`` if file exists
93
95
94
96
Raises:
97
+ BackendError: if an error is raised on the backend
95
98
ValueError: if ``path`` contains invalid character
96
99
97
100
Examples:
@@ -101,7 +104,11 @@ def exists(
101
104
"""
102
105
utils .check_path_for_allowed_chars (path )
103
106
104
- return self ._exists (path , version )
107
+ return utils .call_function_on_backend (
108
+ self ._exists ,
109
+ path ,
110
+ version ,
111
+ )
105
112
106
113
def get_archive (
107
114
self ,
@@ -129,7 +136,7 @@ def get_archive(
129
136
extracted files
130
137
131
138
Raises:
132
- FileNotFoundError : if archive does not exist on backend
139
+ BackendError : if an error is raised on the backend
133
140
FileNotFoundError: if ``tmp_root`` does not exist
134
141
PermissionError: if the user lacks write permissions
135
142
for ``dst_path``
@@ -195,7 +202,7 @@ def get_file(
195
202
full path to local file
196
203
197
204
Raises:
198
- FileNotFoundError : if ``src_path`` does not exist on backend
205
+ BackendError : if an error is raised on the backend
199
206
PermissionError: if the user lacks write permissions
200
207
for ``dst_path``
201
208
ValueError: if ``src_path`` contains invalid character
@@ -210,13 +217,25 @@ def get_file(
210
217
211
218
"""
212
219
utils .check_path_for_allowed_chars (src_path )
213
- if not self ._exists (src_path , version ):
214
- utils .raise_file_not_found_error (src_path , version = version )
215
220
216
- dst_path = audeer .safe_path (dst_path )
217
- audeer .mkdir (os .path .dirname (dst_path ))
218
-
219
- self ._get_file (src_path , dst_path , version , verbose )
221
+ dst_path = audeer .path (dst_path )
222
+ dst_root = os .path .dirname (dst_path )
223
+
224
+ audeer .mkdir (dst_root )
225
+ if (
226
+ not os .access (dst_root , os .W_OK ) or
227
+ (os .path .exists (dst_path ) and not os .access (dst_root , os .W_OK ))
228
+ ): # pragma: no Windows cover
229
+ msg = f"Permission denied: '{ dst_path } '"
230
+ raise PermissionError (msg )
231
+
232
+ utils .call_function_on_backend (
233
+ self ._get_file ,
234
+ src_path ,
235
+ dst_path ,
236
+ version ,
237
+ verbose ,
238
+ )
220
239
221
240
return dst_path
222
241
@@ -264,7 +283,8 @@ def latest_version(
264
283
version string
265
284
266
285
Raises:
267
- RuntimeError: if ``path`` does not exist on backend
286
+ BackendError: if an error is raised on the backend
287
+ RuntimeError: if no version is found
268
288
ValueError: if ``path`` contains invalid character
269
289
270
290
Examples:
@@ -288,11 +308,7 @@ def _ls(
288
308
self ,
289
309
folder : str ,
290
310
) -> typing .List [typing .Tuple [str , str , str ]]: # pragma: no cover
291
- r"""List all files under folder.
292
-
293
- Return an empty list if no files match or folder does not exist.
294
-
295
- """
311
+ r"""List all files under folder."""
296
312
raise NotImplementedError ()
297
313
298
314
def ls (
@@ -323,7 +339,7 @@ def ls(
323
339
list of tuples (path, version)
324
340
325
341
Raises:
326
- FileNotFoundError : if ``folder`` does not exist
342
+ BackendError : if an error is raised on the backend
327
343
ValueError: if ``folder`` contains invalid character
328
344
329
345
Examples:
@@ -340,16 +356,9 @@ def ls(
340
356
utils .check_path_for_allowed_chars (folder )
341
357
if not folder .endswith ('/' ):
342
358
folder += '/'
343
- paths = self ._ls ( folder )
359
+ paths = utils . call_function_on_backend ( self ._ls , folder )
344
360
paths = sorted (paths )
345
361
346
- if len (paths ) == 0 :
347
- if folder == '/' :
348
- # special case that there are no files on the backend
349
- return []
350
- else :
351
- utils .raise_file_not_found_error (folder )
352
-
353
362
if pattern :
354
363
paths = [(p , v ) for p , v in paths if fnmatch .fnmatch (p , pattern )]
355
364
@@ -399,10 +408,12 @@ def put_archive(
399
408
verbose: show debug messages
400
409
401
410
Raises:
402
- FileNotFoundError: if one or more files do not exist
403
- FileNotFoundError: if ``tmp_root`` does not exist
404
- ValueError: if ``dst_path`` contains invalid character
411
+ BackendError: if an error is raised on the backend
412
+ FileNotFoundError: if ``src_root``,
413
+ ``tmp_root``,
414
+ or one or more ``files`` do not exist
405
415
RuntimeError: if extension of ``dst_path`` is not supported
416
+ ValueError: if ``dst_path`` contains invalid character
406
417
407
418
Examples:
408
419
>>> backend.exists('a.tar.gz', '1.0.0')
@@ -414,16 +425,23 @@ def put_archive(
414
425
415
426
"""
416
427
utils .check_path_for_allowed_chars (dst_path )
417
- src_root = audeer .safe_path (src_root )
428
+ src_root = audeer .path (src_root )
429
+
430
+ if not os .path .exists (src_root ):
431
+ utils .raise_file_not_found_error (src_root )
418
432
419
- if isinstance (files , str ):
420
- files = [files ]
433
+ files = audeer .to_list (files )
421
434
422
435
for file in files :
423
436
path = os .path .join (src_root , file )
424
437
if not os .path .exists (path ):
425
438
utils .raise_file_not_found_error (path )
426
439
440
+ if tmp_root is not None :
441
+ tmp_root = audeer .path (tmp_root )
442
+ if not os .path .exists (tmp_root ):
443
+ utils .raise_file_not_found_error (tmp_root )
444
+
427
445
with tempfile .TemporaryDirectory (dir = tmp_root ) as tmp :
428
446
429
447
archive = audeer .path (tmp , os .path .basename (dst_path ))
@@ -475,6 +493,7 @@ def put_file(
475
493
file path on backend
476
494
477
495
Raises:
496
+ BackendError: if an error is raised on the backend
478
497
FileNotFoundError: if ``src_path`` does not exist
479
498
ValueError: if ``dst_path`` contains invalid character
480
499
@@ -493,10 +512,16 @@ def put_file(
493
512
494
513
# skip if file with same checksum already exists
495
514
if not (
496
- self ._exists (dst_path , version )
497
- and self ._checksum (dst_path , version ) == utils .md5 (src_path )
515
+ self .exists (dst_path , version )
516
+ and self .checksum (dst_path , version ) == utils .md5 (src_path )
498
517
):
499
- self ._put_file (src_path , dst_path , version , verbose )
518
+ utils .call_function_on_backend (
519
+ self ._put_file ,
520
+ src_path ,
521
+ dst_path ,
522
+ version ,
523
+ verbose ,
524
+ )
500
525
501
526
def _remove_file (
502
527
self ,
@@ -518,7 +543,7 @@ def remove_file(
518
543
version: version string
519
544
520
545
Raises:
521
- FileNotFoundError : if ``path`` does not exist on backend
546
+ BackendError : if an error is raised on the backend
522
547
ValueError: if ``path`` contains invalid character
523
548
524
549
Examples:
@@ -530,10 +555,12 @@ def remove_file(
530
555
531
556
"""
532
557
utils .check_path_for_allowed_chars (path )
533
- if not self ._exists (path , version ):
534
- utils .raise_file_not_found_error (path , version = version )
535
558
536
- path = self ._remove_file (path , version )
559
+ utils .call_function_on_backend (
560
+ self ._remove_file ,
561
+ path ,
562
+ version ,
563
+ )
537
564
538
565
@property
539
566
def sep (self ) -> str :
@@ -587,6 +614,7 @@ def versions(
587
614
list of versions in ascending order
588
615
589
616
Raises:
617
+ BackendError: if an error is raised on the backend
590
618
ValueError: if ``path`` contains invalid character
591
619
592
620
Examples:
@@ -596,6 +624,9 @@ def versions(
596
624
"""
597
625
utils .check_path_for_allowed_chars (path )
598
626
599
- vs = self ._versions (path )
627
+ vs = utils .call_function_on_backend (
628
+ self ._versions ,
629
+ path ,
630
+ )
600
631
601
632
return audeer .sort_versions (vs )
0 commit comments