@@ -197,7 +197,6 @@ def copy(
197
197
destination_object = destination_object or source_object
198
198
199
199
if source_bucket == destination_bucket and source_object == destination_object :
200
-
201
200
raise ValueError (
202
201
f"Either source/destination bucket or source/destination object must be different, "
203
202
f"not both the same: bucket={ source_bucket } , object={ source_object } "
@@ -282,6 +281,7 @@ def download(
282
281
chunk_size : int | None = None ,
283
282
timeout : int | None = DEFAULT_TIMEOUT ,
284
283
num_max_attempts : int | None = 1 ,
284
+ user_project : str | None = None ,
285
285
) -> bytes :
286
286
...
287
287
@@ -294,6 +294,7 @@ def download(
294
294
chunk_size : int | None = None ,
295
295
timeout : int | None = DEFAULT_TIMEOUT ,
296
296
num_max_attempts : int | None = 1 ,
297
+ user_project : str | None = None ,
297
298
) -> str :
298
299
...
299
300
@@ -305,6 +306,7 @@ def download(
305
306
chunk_size : int | None = None ,
306
307
timeout : int | None = DEFAULT_TIMEOUT ,
307
308
num_max_attempts : int | None = 1 ,
309
+ user_project : str | None = None ,
308
310
) -> str | bytes :
309
311
"""
310
312
Downloads a file from Google Cloud Storage.
@@ -320,6 +322,8 @@ def download(
320
322
:param chunk_size: Blob chunk size.
321
323
:param timeout: Request timeout in seconds.
322
324
:param num_max_attempts: Number of attempts to download the file.
325
+ :param user_project: The identifier of the Google Cloud project to bill for the request.
326
+ Required for Requester Pays buckets.
323
327
"""
324
328
# TODO: future improvement check file size before downloading,
325
329
# to check for local space availability
@@ -330,7 +334,7 @@ def download(
330
334
try :
331
335
num_file_attempts += 1
332
336
client = self .get_conn ()
333
- bucket = client .bucket (bucket_name )
337
+ bucket = client .bucket (bucket_name , user_project = user_project )
334
338
blob = bucket .blob (blob_name = object_name , chunk_size = chunk_size )
335
339
336
340
if filename :
@@ -395,6 +399,7 @@ def provide_file(
395
399
object_name : str | None = None ,
396
400
object_url : str | None = None ,
397
401
dir : str | None = None ,
402
+ user_project : str | None = None ,
398
403
) -> Generator [IO [bytes ], None , None ]:
399
404
"""
400
405
Downloads the file to a temporary directory and returns a file handle.
@@ -406,13 +411,20 @@ def provide_file(
406
411
:param object_name: The object to fetch.
407
412
:param object_url: File reference url. Must start with "gs: //"
408
413
:param dir: The tmp sub directory to download the file to. (passed to NamedTemporaryFile)
414
+ :param user_project: The identifier of the Google Cloud project to bill for the request.
415
+ Required for Requester Pays buckets.
409
416
:return: File handler
410
417
"""
411
418
if object_name is None :
412
419
raise ValueError ("Object name can not be empty" )
413
420
_ , _ , file_name = object_name .rpartition ("/" )
414
421
with NamedTemporaryFile (suffix = file_name , dir = dir ) as tmp_file :
415
- self .download (bucket_name = bucket_name , object_name = object_name , filename = tmp_file .name )
422
+ self .download (
423
+ bucket_name = bucket_name ,
424
+ object_name = object_name ,
425
+ filename = tmp_file .name ,
426
+ user_project = user_project ,
427
+ )
416
428
tmp_file .flush ()
417
429
yield tmp_file
418
430
@@ -423,6 +435,7 @@ def provide_file_and_upload(
423
435
bucket_name : str = PROVIDE_BUCKET ,
424
436
object_name : str | None = None ,
425
437
object_url : str | None = None ,
438
+ user_project : str | None = None ,
426
439
) -> Generator [IO [bytes ], None , None ]:
427
440
"""
428
441
Creates temporary file, returns a file handle and uploads the files content on close.
@@ -433,6 +446,8 @@ def provide_file_and_upload(
433
446
:param bucket_name: The bucket to fetch from.
434
447
:param object_name: The object to fetch.
435
448
:param object_url: File reference url. Must start with "gs: //"
449
+ :param user_project: The identifier of the Google Cloud project to bill for the request.
450
+ Required for Requester Pays buckets.
436
451
:return: File handler
437
452
"""
438
453
if object_name is None :
@@ -442,7 +457,12 @@ def provide_file_and_upload(
442
457
with NamedTemporaryFile (suffix = file_name ) as tmp_file :
443
458
yield tmp_file
444
459
tmp_file .flush ()
445
- self .upload (bucket_name = bucket_name , object_name = object_name , filename = tmp_file .name )
460
+ self .upload (
461
+ bucket_name = bucket_name ,
462
+ object_name = object_name ,
463
+ filename = tmp_file .name ,
464
+ user_project = user_project ,
465
+ )
446
466
447
467
def upload (
448
468
self ,
@@ -458,6 +478,7 @@ def upload(
458
478
num_max_attempts : int = 1 ,
459
479
metadata : dict | None = None ,
460
480
cache_control : str | None = None ,
481
+ user_project : str | None = None ,
461
482
) -> None :
462
483
"""
463
484
Uploads a local file or file data as string or bytes to Google Cloud Storage.
@@ -474,6 +495,8 @@ def upload(
474
495
:param num_max_attempts: Number of attempts to try to upload the file.
475
496
:param metadata: The metadata to be uploaded with the file.
476
497
:param cache_control: Cache-Control metadata field.
498
+ :param user_project: The identifier of the Google Cloud project to bill for the request.
499
+ Required for Requester Pays buckets.
477
500
"""
478
501
479
502
def _call_with_retry (f : Callable [[], None ]) -> None :
@@ -506,7 +529,7 @@ def _call_with_retry(f: Callable[[], None]) -> None:
506
529
continue
507
530
508
531
client = self .get_conn ()
509
- bucket = client .bucket (bucket_name )
532
+ bucket = client .bucket (bucket_name , user_project = user_project )
510
533
blob = bucket .blob (blob_name = object_name , chunk_size = chunk_size )
511
534
512
535
if metadata :
@@ -596,7 +619,6 @@ def is_updated_after(self, bucket_name: str, object_name: str, ts: datetime) ->
596
619
"""
597
620
blob_update_time = self .get_blob_update_time (bucket_name , object_name )
598
621
if blob_update_time is not None :
599
-
600
622
if not ts .tzinfo :
601
623
ts = ts .replace (tzinfo = timezone .utc )
602
624
self .log .info ("Verify object date: %s > %s" , blob_update_time , ts )
@@ -618,7 +640,6 @@ def is_updated_between(
618
640
"""
619
641
blob_update_time = self .get_blob_update_time (bucket_name , object_name )
620
642
if blob_update_time is not None :
621
-
622
643
if not min_ts .tzinfo :
623
644
min_ts = min_ts .replace (tzinfo = timezone .utc )
624
645
if not max_ts .tzinfo :
@@ -639,7 +660,6 @@ def is_updated_before(self, bucket_name: str, object_name: str, ts: datetime) ->
639
660
"""
640
661
blob_update_time = self .get_blob_update_time (bucket_name , object_name )
641
662
if blob_update_time is not None :
642
-
643
663
if not ts .tzinfo :
644
664
ts = ts .replace (tzinfo = timezone .utc )
645
665
self .log .info ("Verify object date: %s < %s" , blob_update_time , ts )
@@ -681,16 +701,18 @@ def delete(self, bucket_name: str, object_name: str) -> None:
681
701
682
702
self .log .info ("Blob %s deleted." , object_name )
683
703
684
- def delete_bucket (self , bucket_name : str , force : bool = False ) -> None :
704
+ def delete_bucket (self , bucket_name : str , force : bool = False , user_project : str | None = None ) -> None :
685
705
"""
686
706
Delete a bucket object from the Google Cloud Storage.
687
707
688
708
:param bucket_name: name of the bucket which will be deleted
689
709
:param force: false not allow to delete non empty bucket, set force=True
690
710
allows to delete non empty bucket
711
+ :param user_project: The identifier of the Google Cloud project to bill for the request.
712
+ Required for Requester Pays buckets.
691
713
"""
692
714
client = self .get_conn ()
693
- bucket = client .bucket (bucket_name )
715
+ bucket = client .bucket (bucket_name , user_project = user_project )
694
716
695
717
self .log .info ("Deleting %s bucket" , bucket_name )
696
718
try :
@@ -707,6 +729,7 @@ def list(
707
729
prefix : str | List [str ] | None = None ,
708
730
delimiter : str | None = None ,
709
731
match_glob : str | None = None ,
732
+ user_project : str | None = None ,
710
733
):
711
734
"""
712
735
List all objects from the bucket with the given a single prefix or multiple prefixes.
@@ -718,6 +741,8 @@ def list(
718
741
:param delimiter: (Deprecated) filters objects based on the delimiter (for e.g '.csv')
719
742
:param match_glob: (Optional) filters objects based on the glob pattern given by the string
720
743
(e.g, ``'**/*/.json'``).
744
+ :param user_project: The identifier of the Google Cloud project to bill for the request.
745
+ Required for Requester Pays buckets.
721
746
:return: a stream of object names matching the filtering criteria
722
747
"""
723
748
if delimiter and delimiter != "/" :
@@ -739,6 +764,7 @@ def list(
739
764
prefix = prefix_item ,
740
765
delimiter = delimiter ,
741
766
match_glob = match_glob ,
767
+ user_project = user_project ,
742
768
)
743
769
)
744
770
else :
@@ -750,6 +776,7 @@ def list(
750
776
prefix = prefix ,
751
777
delimiter = delimiter ,
752
778
match_glob = match_glob ,
779
+ user_project = user_project ,
753
780
)
754
781
)
755
782
return objects
@@ -762,6 +789,7 @@ def _list(
762
789
prefix : str | None = None ,
763
790
delimiter : str | None = None ,
764
791
match_glob : str | None = None ,
792
+ user_project : str | None = None ,
765
793
) -> List :
766
794
"""
767
795
List all objects from the bucket with the give string prefix in name.
@@ -773,10 +801,12 @@ def _list(
773
801
:param delimiter: (Deprecated) filters objects based on the delimiter (for e.g '.csv')
774
802
:param match_glob: (Optional) filters objects based on the glob pattern given by the string
775
803
(e.g, ``'**/*/.json'``).
804
+ :param user_project: The identifier of the Google Cloud project to bill for the request.
805
+ Required for Requester Pays buckets.
776
806
:return: a stream of object names matching the filtering criteria
777
807
"""
778
808
client = self .get_conn ()
779
- bucket = client .bucket (bucket_name )
809
+ bucket = client .bucket (bucket_name , user_project = user_project )
780
810
781
811
ids = []
782
812
page_token = None
0 commit comments