@@ -149,7 +149,9 @@ def build(serviceName,
149149 developerKey = None ,
150150 model = None ,
151151 requestBuilder = HttpRequest ,
152- credentials = None ):
152+ credentials = None ,
153+ cache_discovery = True ,
154+ cache = None ):
153155 """Construct a Resource for interacting with an API.
154156
155157 Construct a Resource object for interacting with an API. The serviceName and
@@ -171,6 +173,9 @@ def build(serviceName,
171173 request.
172174 credentials: oauth2client.Credentials, credentials to be used for
173175 authentication.
176+ cache_discovery: Boolean, whether or not to cache the discovery doc.
177+ cache: googleapiclient.discovery_cache.base.CacheBase, an optional
178+ cache object for the discovery documents.
174179
175180 Returns:
176181 A Resource object with methods for interacting with the service.
@@ -185,22 +190,53 @@ def build(serviceName,
185190
186191 requested_url = uritemplate .expand (discoveryServiceUrl , params )
187192
193+ content = _retrieve_discovery_doc (requested_url , http , cache_discovery , cache )
194+
195+ return build_from_document (content , base = discoveryServiceUrl , http = http ,
196+ developerKey = developerKey , model = model , requestBuilder = requestBuilder ,
197+ credentials = credentials )
198+
199+
200+ def _retrieve_discovery_doc (url , http , cache_discovery , cache = None ):
201+ """Retrieves the discovery_doc from cache or the internet.
202+
203+ Args:
204+ url: string, the URL of the discovery document.
205+ http: httplib2.Http, An instance of httplib2.Http or something that acts
206+ like it through which HTTP requests will be made.
207+ cache_discovery: Boolean, whether or not to cache the discovery doc.
208+ cache: googleapiclient.discovery_cache.base.Cache, an optional cache
209+ object for the discovery documents.
210+
211+ Returns:
212+ A unicode string representation of the discovery document.
213+ """
214+ if cache_discovery :
215+ from . import discovery_cache
216+ from .discovery_cache import base
217+ if cache is None :
218+ cache = discovery_cache .autodetect ()
219+ if cache :
220+ content = cache .get (url )
221+ if content :
222+ return content
223+
224+ actual_url = url
188225 # REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment
189226 # variable that contains the network address of the client sending the
190227 # request. If it exists then add that to the request for the discovery
191228 # document to avoid exceeding the quota on discovery requests.
192229 if 'REMOTE_ADDR' in os .environ :
193- requested_url = _add_query_parameter (requested_url , 'userIp' ,
194- os .environ ['REMOTE_ADDR' ])
195- logger .info ('URL being requested: GET %s' % requested_url )
230+ actual_url = _add_query_parameter (url , 'userIp' , os .environ ['REMOTE_ADDR' ])
231+ logger .info ('URL being requested: GET %s' , actual_url )
196232
197- resp , content = http .request (requested_url )
233+ resp , content = http .request (actual_url )
198234
199235 if resp .status == 404 :
200236 raise UnknownApiNameOrVersion ("name: %s version: %s" % (serviceName ,
201- version ))
237+ version ))
202238 if resp .status >= 400 :
203- raise HttpError (resp , content , uri = requested_url )
239+ raise HttpError (resp , content , uri = actual_url )
204240
205241 try :
206242 content = content .decode ('utf-8' )
@@ -212,10 +248,9 @@ def build(serviceName,
212248 except ValueError as e :
213249 logger .error ('Failed to parse as JSON: ' + content )
214250 raise InvalidJsonError ()
215-
216- return build_from_document (content , base = discoveryServiceUrl , http = http ,
217- developerKey = developerKey , model = model , requestBuilder = requestBuilder ,
218- credentials = credentials )
251+ if cache_discovery and cache :
252+ cache .set (url , content )
253+ return content
219254
220255
221256@positional (1 )
0 commit comments