@@ -168,7 +168,7 @@ def _download_file_from_url(response, path_to_file, chunk_multiplier=1, desc=Non
168168def download_file_from_url (url , path_to_file , if_exists = 'replace' , max_retries = 5 ,
169169 requests_session_args = None , verbose = False , print_wrap_limit = None ,
170170 chunk_multiplier = 1 , desc = None , bar_format = None , colour = None ,
171- validate = True , ** kwargs ):
171+ validate = True , stream_download = False , ** kwargs ):
172172 # noinspection PyShadowingNames
173173 """
174174 Downloads a file from a valid URL.
@@ -212,6 +212,11 @@ def download_file_from_url(url, path_to_file, if_exists='replace', max_retries=5
212212 :param validate: Whether to validate if the downloaded file size matches the expected content
213213 length; defaults to ``True``.
214214 :type validate: bool
215+ :param stream_download: When `stream_download=True`, use streaming download
216+ (memory-efficient, perferred for large files);
217+ When `stream_download=False`, not streaming (simpler/faster for small files);
218+ defaults to ``False``.
219+ :type stream_download: bool
215220 :param kwargs: [Optional] Additional parameters passed to the method `tqdm.tqdm()`_.
216221
217222 .. _`tqdm.tqdm()`: https://tqdm.github.io/docs/tqdm/
@@ -272,8 +277,10 @@ def download_file_from_url(url, path_to_file, if_exists='replace', max_retries=5
272277
273278 os .makedirs (os .path .dirname (path_to_file_ ), exist_ok = True ) # Ensure the directory exists
274279
275- # Streaming, so we can iterate over the response
276- with session .get (url = url , stream = True , headers = fake_headers ) as response :
280+ # If streaming, we can iterate over the response
281+ stream_download_ = verbose or stream_download
282+
283+ with session .get (url = url , stream = stream_download_ , headers = fake_headers ) as response :
277284 if response .status_code != 200 :
278285 print (f"Failed to retrieve file. HTTP Status Code: { response .status_code } ." )
279286 return None
@@ -292,8 +299,17 @@ def download_file_from_url(url, path_to_file, if_exists='replace', max_retries=5
292299 )
293300
294301 else :
295- with open (path_to_file_ , mode = 'wb' ) as f : # Open the file in binary write mode
296- shutil .copyfileobj (fsrc = response .raw , fdst = f ) # type: ignore
302+ if stream_download_ :
303+ encoding = response .headers .get ('Content-Encoding' , '' )
304+ if 'gzip' in encoding or 'deflate' in encoding :
305+ response .raw .decode_content = True
306+
307+ with open (path_to_file_ , mode = 'wb' ) as f : # Open the file in binary write mode
308+ shutil .copyfileobj (fsrc = response .raw , fdst = f ) # type: ignore
309+
310+ else :
311+ with open (path_to_file_ , mode = 'wb' ) as f :
312+ f .write (response .content )
297313
298314 # Validate download if necessary
299315 if validate and os .stat (path_to_file ).st_size == 0 :
0 commit comments