Skip to content

Commit d4a98e8

Browse files
committed
all pre-signed url to be downloaded directly
1 parent 0fc3f75 commit d4a98e8

File tree

2 files changed

+76
-39
lines changed

2 files changed

+76
-39
lines changed

synapseclient/core/download/download_async.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class DownloadRequest(NamedTuple):
5959
object_type: str
6060
path: str
6161
debug: bool = False
62+
presigned_url: Optional["PresignedUrlInfo"] = None
6263

6364

6465
async def download_file(
@@ -270,7 +271,12 @@ async def download_file(self) -> None:
270271
"""
271272
Splits up and downloads a file in chunks from a URL.
272273
"""
273-
url_provider = PresignedUrlProvider(self._syn, request=self._download_request)
274+
if self._download_request.presigned_url:
275+
url_provider = self._download_request.presigned_url
276+
else:
277+
url_provider = PresignedUrlProvider(
278+
self._syn, request=self._download_request
279+
)
274280

275281
file_size = await with_retry_time_based_async(
276282
function=lambda: _get_file_size_wrapper(
@@ -282,9 +288,14 @@ async def download_file(self) -> None:
282288
retry_max_wait_before_failure=30,
283289
read_response_content=False,
284290
)
291+
# set postfix to object_id if not presigned url, otherwise set to file_name
292+
if not self._download_request.presigned_url:
293+
postfix = self._download_request.object_id
294+
else:
295+
postfix = self._download_request.presigned_url.file_name
285296
self._progress_bar = get_or_create_download_progress_bar(
286297
file_size=file_size,
287-
postfix=self._download_request.object_id,
298+
postfix=postfix,
288299
synapse_client=self._syn,
289300
)
290301
self._prep_file()

synapseclient/core/download/download_functions.py

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from synapseclient.core.download import (
3030
SYNAPSE_DEFAULT_DOWNLOAD_PART_SIZE,
3131
DownloadRequest,
32+
PresignedUrlInfo,
3233
PresignedUrlProvider,
3334
_pre_signed_url_expiration_time,
3435
download_file,
@@ -569,13 +570,14 @@ def download_fn(
569570

570571

571572
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],
574575
object_type: str,
575576
destination: str,
576577
*,
577578
expected_md5: str = None,
578579
synapse_client: Optional["Synapse"] = None,
580+
presigned_url: Optional[PresignedUrlInfo] = None,
579581
) -> str:
580582
"""
581583
Download a file from the given URL using multiple threads.
@@ -603,17 +605,25 @@ async def download_from_url_multi_threaded(
603605

604606
client = Synapse.get_client(synapse_client=synapse_client)
605607
destination = os.path.abspath(destination)
606-
temp_destination = utils.temp_download_filename(
607-
destination=destination, file_handle_id=file_handle_id
608-
)
609608

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+
)
617627

618628
await download_file(client=client, download_request=request)
619629

@@ -643,6 +653,7 @@ def download_from_url(
643653
file_handle_id: Optional[str] = None,
644654
expected_md5: Optional[str] = None,
645655
progress_bar: Optional[tqdm] = None,
656+
url_is_presigned: Optional[bool] = False,
646657
*,
647658
synapse_client: Optional["Synapse"] = None,
648659
) -> Union[str, None]:
@@ -661,6 +672,8 @@ def download_from_url(
661672
handle id which allows resuming partial downloads of the same file from previous
662673
sessions
663674
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.
664677
synapse_client: If not passed in and caching was not disabled by
665678
`Synapse.allow_client_caching(False)` this will use the last created
666679
instance from the Synapse class constructor.
@@ -768,13 +781,21 @@ def _ftp_report_hook(
768781
url
769782
)
770783
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
778799
response = with_retry(
779800
lambda url=url, range_header=range_header, auth=auth: client._requests_session.get(
780801
url=url,
@@ -801,24 +822,29 @@ def _ftp_report_hook(
801822
url
802823
)
803824
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+
)
822848
else:
823849
raise
824850
elif err.response.status_code == 404:

0 commit comments

Comments
 (0)