1010from vonage_http_client .auth import Auth
1111from vonage_http_client .errors import (
1212 AuthenticationError ,
13+ FileStreamingError ,
1314 ForbiddenError ,
1415 HttpRequestError ,
1516 InvalidHttpClientOptionsError ,
@@ -250,6 +251,34 @@ def make_request(
250251 with self ._session .request (** request_params ) as response :
251252 return self ._parse_response (response )
252253
254+ def download_file_stream (self , url : str , file_path : str ) -> bytes :
255+ """Download a file from a URL and save it to a local file. This method streams the
256+ file to disk.
257+
258+ Args:
259+ url (str): The URL of the file to download.
260+ file_path (str): The local path to save the file to.
261+
262+ Returns:
263+ bytes: The content of the file.
264+ """
265+ headers = {
266+ 'User-Agent' : self .user_agent ,
267+ 'Authorization' : self .auth .create_jwt_auth_string (),
268+ }
269+
270+ logger .debug (
271+ f'Downloading file by streaming from { url } to local location: { file_path } , with headers: { self ._headers } '
272+ )
273+ try :
274+ with self ._session .get (url , headers = headers , stream = True ) as response :
275+ with open (file_path , 'wb' ) as f :
276+ for chunk in response .iter_content (chunk_size = 4096 ):
277+ f .write (chunk )
278+ except Exception as e :
279+ logger .error (f'Error downloading file from { url } : { e } ' )
280+ raise FileStreamingError (f'Error downloading file from { url } : { e } ' ) from e
281+
253282 def append_to_user_agent (self , string : str ):
254283 """Append a string to the User-Agent header.
255284
@@ -267,6 +296,8 @@ def _parse_response(self, response: Response) -> Union[dict, None]:
267296 try :
268297 return response .json ()
269298 except JSONDecodeError :
299+ if hasattr (response .headers , 'Content-Type' ):
300+ return response .content
270301 return None
271302 if response .status_code >= 400 :
272303 content_type = response .headers ['Content-Type' ].split (';' , 1 )[0 ]
0 commit comments