@@ -149,7 +149,9 @@ def build(serviceName,
149
149
developerKey = None ,
150
150
model = None ,
151
151
requestBuilder = HttpRequest ,
152
- credentials = None ):
152
+ credentials = None ,
153
+ cache_discovery = True ,
154
+ cache = None ):
153
155
"""Construct a Resource for interacting with an API.
154
156
155
157
Construct a Resource object for interacting with an API. The serviceName and
@@ -171,6 +173,9 @@ def build(serviceName,
171
173
request.
172
174
credentials: oauth2client.Credentials, credentials to be used for
173
175
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.
174
179
175
180
Returns:
176
181
A Resource object with methods for interacting with the service.
@@ -185,22 +190,53 @@ def build(serviceName,
185
190
186
191
requested_url = uritemplate .expand (discoveryServiceUrl , params )
187
192
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
188
225
# REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment
189
226
# variable that contains the network address of the client sending the
190
227
# request. If it exists then add that to the request for the discovery
191
228
# document to avoid exceeding the quota on discovery requests.
192
229
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 )
196
232
197
- resp , content = http .request (requested_url )
233
+ resp , content = http .request (actual_url )
198
234
199
235
if resp .status == 404 :
200
236
raise UnknownApiNameOrVersion ("name: %s version: %s" % (serviceName ,
201
- version ))
237
+ version ))
202
238
if resp .status >= 400 :
203
- raise HttpError (resp , content , uri = requested_url )
239
+ raise HttpError (resp , content , uri = actual_url )
204
240
205
241
try :
206
242
content = content .decode ('utf-8' )
@@ -212,10 +248,9 @@ def build(serviceName,
212
248
except ValueError as e :
213
249
logger .error ('Failed to parse as JSON: ' + content )
214
250
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
219
254
220
255
221
256
@positional (1 )
0 commit comments