33"""
44
55import logging
6+ import os
67import sys
8+ import tempfile
79
810import requests
911
@@ -88,13 +90,14 @@ def _handle_error(operation, exc):
8890 sys .exit (1 )
8991
9092
91- def get (url , params = None ): # type: (str, dict) -> requests.Response
93+ def get (url , params = None , stream = False ):
94+ # type: (str, dict, bool) -> requests.Response
9295 """Make GET request and handle errors."""
9396 LOG .debug ('GET %s' , url )
9497
9598 try :
9699 rsp = requests .get (url , auth = _get_auth (), headers = _get_headers (),
97- params = params )
100+ params = params , stream = stream )
98101 rsp .raise_for_status ()
99102 except requests .exceptions .RequestException as exc :
100103 _handle_error ('fetch' , exc )
@@ -120,6 +123,31 @@ def put(url, data): # type: (str, dict) -> requests.Response
120123 return rsp
121124
122125
126+ def download (url , params = None ): # type: (str, dict) -> None
127+ """Retrieve a specific API resource and save it to a file.
128+
129+ GET /{resource}/{resourceID}/
130+
131+ Arguments:
132+ resource_type (str): The resource endpoint name.
133+ resource_id (int/str): The ID for the specific resource.
134+ params (dict/list): Additional parameters.
135+
136+ Returns:
137+ A path to an output file containing the content.
138+ """
139+ output_fd , output_path = tempfile .mkstemp (suffix = '.patch' )
140+
141+ rsp = get (url , params , stream = True )
142+ with os .fdopen (output_fd , 'w' ) as output_file :
143+ LOG .debug ('Saving to %s' , output_path )
144+ # we use iter_content because patches can be binary
145+ for block in rsp .iter_content (1024 ):
146+ output_file .write (block )
147+
148+ return output_path
149+
150+
123151def index (resource_type , params = None ): # type: (str, dict) -> dict
124152 """List API resources.
125153
@@ -164,7 +192,7 @@ def detail(resource_type, resource_id, params=None):
164192 url = '/' .join ([_get_server (), 'api' , resource_type ,
165193 str (resource_id ), '' ])
166194
167- return get (url , params ).json ()
195+ return get (url , params , stream = False ).json ()
168196
169197
170198def update (resource_type , resource_id , data ):
0 commit comments