29
29
from synapseclient .core .download import (
30
30
SYNAPSE_DEFAULT_DOWNLOAD_PART_SIZE ,
31
31
DownloadRequest ,
32
+ PresignedUrlInfo ,
32
33
PresignedUrlProvider ,
33
34
_pre_signed_url_expiration_time ,
34
35
download_file ,
@@ -569,13 +570,14 @@ def download_fn(
569
570
570
571
571
572
async def download_from_url_multi_threaded (
572
- file_handle_id : str ,
573
- object_id : str ,
573
+ file_handle_id : Optional [ str ] ,
574
+ object_id : Optional [ str ] ,
574
575
object_type : str ,
575
576
destination : str ,
576
577
* ,
577
578
expected_md5 : str = None ,
578
579
synapse_client : Optional ["Synapse" ] = None ,
580
+ presigned_url : Optional [PresignedUrlInfo ] = None ,
579
581
) -> str :
580
582
"""
581
583
Download a file from the given URL using multiple threads.
@@ -603,17 +605,25 @@ async def download_from_url_multi_threaded(
603
605
604
606
client = Synapse .get_client (synapse_client = synapse_client )
605
607
destination = os .path .abspath (destination )
606
- temp_destination = utils .temp_download_filename (
607
- destination = destination , file_handle_id = file_handle_id
608
- )
609
608
610
- request = DownloadRequest (
611
- file_handle_id = int (file_handle_id ),
612
- object_id = object_id ,
613
- object_type = object_type ,
614
- path = temp_destination ,
615
- debug = client .debug ,
616
- )
609
+ if not presigned_url :
610
+ temp_destination = utils .temp_download_filename (
611
+ destination = destination , file_handle_id = file_handle_id
612
+ )
613
+ request = DownloadRequest (
614
+ file_handle_id = int (file_handle_id ),
615
+ object_id = object_id ,
616
+ object_type = object_type ,
617
+ path = temp_destination ,
618
+ debug = client .debug ,
619
+ )
620
+ # generate a name tuple for presigned url
621
+ else :
622
+ request = DownloadRequest (
623
+ path = temp_destination ,
624
+ debug = client .debug ,
625
+ presigned_url = presigned_url ,
626
+ )
617
627
618
628
await download_file (client = client , download_request = request )
619
629
@@ -643,6 +653,7 @@ def download_from_url(
643
653
file_handle_id : Optional [str ] = None ,
644
654
expected_md5 : Optional [str ] = None ,
645
655
progress_bar : Optional [tqdm ] = None ,
656
+ url_is_presigned : Optional [bool ] = False ,
646
657
* ,
647
658
synapse_client : Optional ["Synapse" ] = None ,
648
659
) -> Union [str , None ]:
@@ -661,6 +672,8 @@ def download_from_url(
661
672
handle id which allows resuming partial downloads of the same file from previous
662
673
sessions
663
674
expected_md5: Optional. If given, check that the MD5 of the downloaded file matches the expected MD5
675
+ progress_bar: Optional progress bar to update during download
676
+ url_is_presigned: If True, the URL is already a pre-signed URL.
664
677
synapse_client: If not passed in and caching was not disabled by
665
678
`Synapse.allow_client_caching(False)` this will use the last created
666
679
instance from the Synapse class constructor.
@@ -768,13 +781,21 @@ def _ftp_report_hook(
768
781
url
769
782
)
770
783
if url_is_expired :
771
- response = get_file_handle_for_download (
772
- file_handle_id = file_handle_id ,
773
- synapse_id = entity_id ,
774
- entity_type = file_handle_associate_type ,
775
- synapse_client = client ,
776
- )
777
- url = response ["preSignedURL" ]
784
+ if url_is_presigned :
785
+ raise SynapseError (
786
+ "The provided pre-signed URL has expired. Please provide a new pre-signed URL."
787
+ )
788
+ else :
789
+ # Get a fresh URL if expired and not presigned
790
+ response = get_file_handle_for_download (
791
+ file_handle_id = file_handle_id ,
792
+ synapse_id = entity_id ,
793
+ entity_type = file_handle_associate_type ,
794
+ synapse_client = client ,
795
+ )
796
+ url = response ["preSignedURL" ]
797
+
798
+ # Make the request with retry
778
799
response = with_retry (
779
800
lambda url = url , range_header = range_header , auth = auth : client ._requests_session .get (
780
801
url = url ,
@@ -801,24 +822,29 @@ def _ftp_report_hook(
801
822
url
802
823
)
803
824
if url_is_expired :
804
- response = get_file_handle_for_download (
805
- file_handle_id = file_handle_id ,
806
- synapse_id = entity_id ,
807
- entity_type = file_handle_associate_type ,
808
- synapse_client = client ,
809
- )
810
- refreshed_url = response ["preSignedURL" ]
811
- response = with_retry (
812
- lambda url = refreshed_url , range_header = range_header , auth = auth : client ._requests_session .get (
813
- url = url ,
814
- headers = client ._generate_headers (range_header ),
815
- stream = True ,
816
- allow_redirects = False ,
817
- auth = auth ,
818
- ),
819
- verbose = client .debug ,
820
- ** STANDARD_RETRY_PARAMS ,
821
- )
825
+ if url_is_presigned :
826
+ raise SynapseError (
827
+ "The provided pre-signed URL has expired. Please provide a new pre-signed URL."
828
+ )
829
+ else :
830
+ response = get_file_handle_for_download (
831
+ file_handle_id = file_handle_id ,
832
+ synapse_id = entity_id ,
833
+ entity_type = file_handle_associate_type ,
834
+ synapse_client = client ,
835
+ )
836
+ refreshed_url = response ["preSignedURL" ]
837
+ response = with_retry (
838
+ lambda url = refreshed_url , range_header = range_header , auth = auth : client ._requests_session .get (
839
+ url = url ,
840
+ headers = client ._generate_headers (range_header ),
841
+ stream = True ,
842
+ allow_redirects = False ,
843
+ auth = auth ,
844
+ ),
845
+ verbose = client .debug ,
846
+ ** STANDARD_RETRY_PARAMS ,
847
+ )
822
848
else :
823
849
raise
824
850
elif err .response .status_code == 404 :
0 commit comments