- 1# Copyright (C) 2012 Google Inc.
+ 1# Copyright (C) 2014 Google Inc. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License.
@@ -103,7 +103,7 @@
http=None,
developerKey=None,
model=None,
- requestBuilder=HttpRequest)
+ requestBuilder=HttpRequest,
+ credentials=None)
Create a Resource for interacting with an API.
build_from_document<
model: Model class instance that serializes and de-serializes requests and
responses.
requestBuilder: Takes an http request and packages it up to be executed.
+ credentials: object, credentials to be used for authentication.
Returns:
A Resource object with methods for interacting with the service.
@@ -1074,7 +1081,7 @@
STACK_QUERY_PARAMETER_DEFAULT_VALUE
- Generated by Epydoc 3.0.1 on Thu Apr 24 15:46:09 2014
+ Generated by Epydoc 3.0.1 on Thu Aug 14 10:37:41 2014
- 1# Copyright (C) 2010 Google Inc.
+ 1# Copyright (C) 2014 Google Inc. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License.
@@ -85,994 +85,1030 @@
107"""Fix method names to avoid reserved word conflicts.108
-109 Returns:
-110 The name with a '_' prefixed if the name is a reserved word.
-111 """
-112ifkeyword.iskeyword(name)ornameinRESERVED_WORDS:
-113returnname+'_'
-114else:
-115returnname
-
119"""Converts key names into parameter names.
-120
-121 For example, converting "max-results" -> "max_results"
-122
-123 Args:
-124 key: string, the method key name.
+109 Args:
+110 name: string, method name.
+111
+112 Returns:
+113 The name with a '_' prefixed if the name is a reserved word.
+114 """
+115ifkeyword.iskeyword(name)ornameinRESERVED_WORDS:
+116returnname+'_'
+117else:
+118returnname
+
122"""Converts key names into parameter names.
+123
+124 For example, converting "max-results" -> "max_results"125
-126 Returns:
-127 A safe method name based on the key name.
-128 """
-129result=[]
-130key=list(key)
-131ifnotkey[0].isalpha():
-132result.append('x')
-133forcinkey:
-134ifc.isalnum():
-135result.append(c)
-136else:
-137result.append('_')
-138
-139return''.join(result)
-
150"""Construct a Resource for interacting with an API.
-151
-152 Construct a Resource object for interacting with an API. The serviceName and
-153 version are the names from the Discovery service.
-154
-155 Args:
-156 serviceName: string, name of the service.
-157 version: string, the version of the service.
-158 http: httplib2.Http, An instance of httplib2.Http or something that acts
-159 like it that HTTP requests will be made through.
-160 discoveryServiceUrl: string, a URI Template that points to the location of
-161 the discovery service. It should have two parameters {api} and
-162 {apiVersion} that when filled in produce an absolute URI to the discovery
-163 document for that service.
-164 developerKey: string, key obtained from
-165 https://code.google.com/apis/console.
-166 model: googleapiclient.Model, converts to and from the wire format.
-167 requestBuilder: googleapiclient.http.HttpRequest, encapsulator for an HTTP
-168 request.
-169
-170 Returns:
-171 A Resource object with methods for interacting with the service.
-172 """
-173params={
-174'api':serviceName,
-175'apiVersion':version
-176}
-177
-178ifhttpisNone:
-179http=httplib2.Http()
-180
-181requested_url=uritemplate.expand(discoveryServiceUrl,params)
-182
-183# REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment
-184# variable that contains the network address of the client sending the
-185# request. If it exists then add that to the request for the discovery
-186# document to avoid exceeding the quota on discovery requests.
-187if'REMOTE_ADDR'inos.environ:
-188requested_url=_add_query_parameter(requested_url,'userIp',
-189os.environ['REMOTE_ADDR'])
-190logger.info('URL being requested: %s'%requested_url)
-191
-192resp,content=http.126 Args:
+127 key: string, the method key name.
+128
+129 Returns:
+130 A safe method name based on the key name.
+131 """
+132result=[]
+133key=list(key)
+134ifnotkey[0].isalpha():
+135result.append('x')
+136forcinkey:
+137ifc.isalnum():
+138result.append(c)
+139else:
+140result.append('_')
+141
+142return''.join(result)
+
154"""Construct a Resource for interacting with an API.
+155
+156 Construct a Resource object for interacting with an API. The serviceName and
+157 version are the names from the Discovery service.
+158
+159 Args:
+160 serviceName: string, name of the service.
+161 version: string, the version of the service.
+162 http: httplib2.Http, An instance of httplib2.Http or something that acts
+163 like it that HTTP requests will be made through.
+164 discoveryServiceUrl: string, a URI Template that points to the location of
+165 the discovery service. It should have two parameters {api} and
+166 {apiVersion} that when filled in produce an absolute URI to the discovery
+167 document for that service.
+168 developerKey: string, key obtained from
+169 https://code.google.com/apis/console.
+170 model: googleapiclient.Model, converts to and from the wire format.
+171 requestBuilder: googleapiclient.http.HttpRequest, encapsulator for an HTTP
+172 request.
+173 credentials: oauth2client.Credentials, credentials to be used for
+174 authentication.
+175
+176 Returns:
+177 A Resource object with methods for interacting with the service.
+178 """
+179params={
+180'api':serviceName,
+181'apiVersion':version
+182}
+183
+184ifhttpisNone:
+185http=httplib2.Http()
+186
+187requested_url=uritemplate.expand(discoveryServiceUrl,params)
+188
+189# REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment
+190# variable that contains the network address of the client sending the
+191# request. If it exists then add that to the request for the discovery
+192# document to avoid exceeding the quota on discovery requests.
+193if'REMOTE_ADDR'inos.environ:
+194requested_url=_add_query_parameter(requested_url,'userIp',
+195os.environ['REMOTE_ADDR'])
+196logger.info('URL being requested: GET %s'%requested_url)
+197
+198resp,content=http.request(requested_url)
-193
-194ifresp.status==404:
-195raiseUnknownApiNameOrVersion("name: %s version: %s"%(serviceName,
-196version))
-197ifresp.status>=400:
-198raiseHttpError(resp,content,uri=requested_url)199
-200try:
-201service=simplejson.loads(content)
-202exceptValueError,e:
-203logger.error('Failed to parse as JSON: '+content)
-204raiseInvalidJsonError()
+200ifresp.status==404:
+201raiseUnknownApiNameOrVersion("name: %s version: %s"%(serviceName,
+202version))
+203ifresp.status>=400:
+204raiseHttpError(resp,content,uri=requested_url)205
-206returnbuild_from_document(content,base=discoveryServiceUrl,http=http,
-207developerKey=developerKey,model=model,requestBuilder=requestBuilder)
-
219"""Create a Resource for interacting with an API.
-220
-221 Same as `build()`, but constructs the Resource object from a discovery
-222 document that is it given, as opposed to retrieving one over HTTP.
-223
-224 Args:
-225 service: string or object, the JSON discovery document describing the API.
-226 The value passed in may either be the JSON string or the deserialized
-227 JSON.
-228 base: string, base URI for all HTTP requests, usually the discovery URI.
-229 This parameter is no longer used as rootUrl and servicePath are included
-230 within the discovery document. (deprecated)
-231 future: string, discovery document with future capabilities (deprecated).
-232 http: httplib2.Http, An instance of httplib2.Http or something that acts
-233 like it that HTTP requests will be made through.
-234 developerKey: string, Key for controlling API usage, generated
-235 from the API Console.
-236 model: Model class instance that serializes and de-serializes requests and
-237 responses.
-238 requestBuilder: Takes an http request and packages it up to be executed.
-239
-240 Returns:
-241 A Resource object with methods for interacting with the service.
-242 """
-243
-244# future is no longer used.
-245future={}
-246
-247ifisinstance(service,basestring):
-248service=simplejson.loads(service)
-249base=urlparse.urljoin(service['rootUrl'],service['servicePath'])
-250schema=Schemas(service)
-251
-252ifmodelisNone:
-253features=service.get('features',[])
-254model=JsonModel('dataWrapper'infeatures)
-255returnResource(http=http,baseUrl=base,model=model,
-256developerKey=developerKey,requestBuilder=requestBuilder,
-257resourceDesc=service,rootDesc=service,schema=schema)
-
261"""Convert value to a string based on JSON Schema type.
-262
-263 See http://tools.ietf.org/html/draft-zyp-json-schema-03 for more details on
-264 JSON Schema.
-265
-266 Args:
-267 value: any, the value to convert
-268 schema_type: string, the type that value should be interpreted as
-269
-270 Returns:
-271 A string representation of 'value' based on the schema_type.
-272 """
-273ifschema_type=='string':
-274iftype(value)==type('')ortype(value)==type(u''):
-275returnvalue
-276else:
-277returnstr(value)
-278elifschema_type=='integer':
-279returnstr(int(value))
-280elifschema_type=='number':
-281returnstr(float(value))
-282elifschema_type=='boolean':
-283returnstr(bool(value)).lower()
-284else:
-285iftype(value)==type('')ortype(value)==type(u''):
-286returnvalue
-287else:
-288returnstr(value)
+206try:
+207service=simplejson.loads(content)
+208exceptValueError,e:
+209logger.error('Failed to parse as JSON: '+content)
+210raiseInvalidJsonError()
+211
+212returnbuild_from_document(content,base=discoveryServiceUrl,http=http,
+213developerKey=developerKey,model=model,requestBuilder=requestBuilder,
+214credentials=credentials)
+
227"""Create a Resource for interacting with an API.
+228
+229 Same as `build()`, but constructs the Resource object from a discovery
+230 document that is it given, as opposed to retrieving one over HTTP.
+231
+232 Args:
+233 service: string or object, the JSON discovery document describing the API.
+234 The value passed in may either be the JSON string or the deserialized
+235 JSON.
+236 base: string, base URI for all HTTP requests, usually the discovery URI.
+237 This parameter is no longer used as rootUrl and servicePath are included
+238 within the discovery document. (deprecated)
+239 future: string, discovery document with future capabilities (deprecated).
+240 http: httplib2.Http, An instance of httplib2.Http or something that acts
+241 like it that HTTP requests will be made through.
+242 developerKey: string, Key for controlling API usage, generated
+243 from the API Console.
+244 model: Model class instance that serializes and de-serializes requests and
+245 responses.
+246 requestBuilder: Takes an http request and packages it up to be executed.
+247 credentials: object, credentials to be used for authentication.
+248
+249 Returns:
+250 A Resource object with methods for interacting with the service.
+251 """
+252
+253# future is no longer used.
+254future={}
+255
+256ifisinstance(service,basestring):
+257service=simplejson.loads(service)
+258base=urlparse.urljoin(service['rootUrl'],service['servicePath'])
+259schema=Schemas(service)
+260
+261ifcredentials:
+262# If credentials were passed in, we could have two cases:
+263# 1. the scopes were specified, in which case the given credentials
+264# are used for authorizing the http;
+265# 2. the scopes were not provided (meaning the Application Default
+266# Credentials are to be used). In this case, the Application Default
+267# Credentials are built and used instead of the original credentials.
+268# If there are no scopes found (meaning the given service requires no
+269# authentication), there is no authorization of the http.
+270if(isinstance(credentials,GoogleCredentials)and
+271credentials.create_scoped_required()):
+272scopes=service.get('auth',{}).get('oauth2',{}).get('scopes',{})
+273ifscopes:
+274credentials=credentials.create_scoped(scopes.keys())
+275else:
+276# No need to authorize the http object
+277# if the service does not require authentication.
+278credentials=None
+279
+280ifcredentials:
+281http=credentials.authorize(http)
+282
+283ifmodelisNone:
+284features=service.get('features',[])
+285model=JsonModel('dataWrapper'infeatures)
+286returnResource(http=http,baseUrl=base,model=model,
+287developerKey=developerKey,requestBuilder=requestBuilder,
+288resourceDesc=service,rootDesc=service,schema=schema)
292"""Convert value to a string based on JSON Schema type.293
-294 Args:
-295 maxSize: string, size as a string, such as 2MB or 7GB.
+294 See http://tools.ietf.org/html/draft-zyp-json-schema-03 for more details on
+295 JSON Schema.296
-297 Returns:
-298 The size as an integer value.
-299 """
-300iflen(maxSize)<2:
-301return0L
-302units=maxSize[-2:].upper()
-303bit_shift=_MEDIA_SIZE_BIT_SHIFTS.get(units)
-304ifbit_shiftisnotNone:
-305returnlong(maxSize[:-2])<<bit_shift
-306else:
-307returnlong(maxSize)
-
311"""Creates an absolute media path URL.
-312
-313 Constructed using the API root URI and service path from the discovery
-314 document and the relative path for the API method.
-315
-316 Args:
-317 root_desc: Dictionary; the entire original deserialized discovery document.
-318 path_url: String; the relative URL for the API method. Relative to the API
-319 root, which is specified in the discovery document.
-320
-321 Returns:
-322 String; the absolute URI for media upload for the API method.
-323 """
-324return'%(root)supload/%(service_path)s%(path)s'%{
-325'root':root_desc['rootUrl'],
-326'service_path':root_desc['servicePath'],
-327'path':path_url,
-328}
-
332"""Updates parameters of an API method with values specific to this library.
-333
-334 Specifically, adds whatever global parameters are specified by the API to the
-335 parameters for the individual method. Also adds parameters which don't
-336 appear in the discovery document, but are available to all discovery based
-337 APIs (these are listed in STACK_QUERY_PARAMETERS).
-338
-339 SIDE EFFECTS: This updates the parameters dictionary object in the method
-340 description.
-341
-342 Args:
-343 method_desc: Dictionary with metadata describing an API method. Value comes
-344 from the dictionary of methods stored in the 'methods' key in the
-345 deserialized discovery document.
-346 root_desc: Dictionary; the entire original deserialized discovery document.
-347 http_method: String; the HTTP method used to call the API method described
-348 in method_desc.
-349
-350 Returns:
-351 The updated Dictionary stored in the 'parameters' key of the method
-352 description dictionary.
-353 """
-354parameters=method_desc.setdefault('parameters',{})
-355
-356# Add in the parameters common to all methods.
-357forname,descriptioninroot_desc.get('parameters',{}).iteritems():
-358parameters[name]=description
-359
-360# Add in undocumented query parameters.
-361fornameinSTACK_QUERY_PARAMETERS:
-362parameters[name]=STACK_QUERY_PARAMETER_DEFAULT_VALUE.copy()
-363
-364# Add 'body' (our own reserved word) to parameters if the method supports
-365# a request payload.
-366ifhttp_methodinHTTP_PAYLOAD_METHODSand'request'inmethod_desc:
-367body=BODY_PARAMETER_DEFAULT_VALUE.copy()
-368body.update(method_desc['request'])
-369parameters['body']=body
-370
-371returnparameters
-
375"""Updates parameters of API by adding 'media_body' if supported by method.
-376
-377 SIDE EFFECTS: If the method supports media upload and has a required body,
-378 sets body to be optional (required=False) instead. Also, if there is a
-379 'mediaUpload' in the method description, adds 'media_upload' key to
-380 parameters.
-381
-382 Args:
-383 method_desc: Dictionary with metadata describing an API method. Value comes
-384 from the dictionary of methods stored in the 'methods' key in the
-385 deserialized discovery document.
-386 root_desc: Dictionary; the entire original deserialized discovery document.
-387 path_url: String; the relative URL for the API method. Relative to the API
-388 root, which is specified in the discovery document.
-389 parameters: A dictionary describing method parameters for method described
-390 in method_desc.
-391
-392 Returns:
-393 Triple (accept, max_size, media_path_url) where:
-394 - accept is a list of strings representing what content types are
-395 accepted for media upload. Defaults to empty list if not in the
-396 discovery document.
-397 - max_size is a long representing the max size in bytes allowed for a
-398 media upload. Defaults to 0L if not in the discovery document.
-399 - media_path_url is a String; the absolute URI for media upload for the
-400 API method. Constructed using the API root URI and service path from
-401 the discovery document and the relative path for the API method. If
-402 media upload is not supported, this is None.
-403 """
-404media_upload=method_desc.get('mediaUpload',{})
-405297 Args:
+298 value: any, the value to convert
+299 schema_type: string, the type that value should be interpreted as
+300
+301 Returns:
+302 A string representation of 'value' based on the schema_type.
+303 """
+304ifschema_type=='string':
+305iftype(value)==type('')ortype(value)==type(u''):
+306returnvalue
+307else:
+308returnstr(value)
+309elifschema_type=='integer':
+310returnstr(int(value))
+311elifschema_type=='number':
+312returnstr(float(value))
+313elifschema_type=='boolean':
+314returnstr(bool(value)).lower()
+315else:
+316iftype(value)==type('')ortype(value)==type(u''):
+317returnvalue
+318else:
+319returnstr(value)
+
323"""Convert a string media size, such as 10GB or 3TB into an integer.
+324
+325 Args:
+326 maxSize: string, size as a string, such as 2MB or 7GB.
+327
+328 Returns:
+329 The size as an integer value.
+330 """
+331iflen(maxSize)<2:
+332return0L
+333units=maxSize[-2:].upper()
+334bit_shift=_MEDIA_SIZE_BIT_SHIFTS.get(units)
+335ifbit_shiftisnotNone:
+336returnlong(maxSize[:-2])<<bit_shift
+337else:
+338returnlong(maxSize)
+
342"""Creates an absolute media path URL.
+343
+344 Constructed using the API root URI and service path from the discovery
+345 document and the relative path for the API method.
+346
+347 Args:
+348 root_desc: Dictionary; the entire original deserialized discovery document.
+349 path_url: String; the relative URL for the API method. Relative to the API
+350 root, which is specified in the discovery document.
+351
+352 Returns:
+353 String; the absolute URI for media upload for the API method.
+354 """
+355return'%(root)supload/%(service_path)s%(path)s'%{
+356'root':root_desc['rootUrl'],
+357'service_path':root_desc['servicePath'],
+358'path':path_url,
+359}
+
363"""Updates parameters of an API method with values specific to this library.
+364
+365 Specifically, adds whatever global parameters are specified by the API to the
+366 parameters for the individual method. Also adds parameters which don't
+367 appear in the discovery document, but are available to all discovery based
+368 APIs (these are listed in STACK_QUERY_PARAMETERS).
+369
+370 SIDE EFFECTS: This updates the parameters dictionary object in the method
+371 description.
+372
+373 Args:
+374 method_desc: Dictionary with metadata describing an API method. Value comes
+375 from the dictionary of methods stored in the 'methods' key in the
+376 deserialized discovery document.
+377 root_desc: Dictionary; the entire original deserialized discovery document.
+378 http_method: String; the HTTP method used to call the API method described
+379 in method_desc.
+380
+381 Returns:
+382 The updated Dictionary stored in the 'parameters' key of the method
+383 description dictionary.
+384 """
+385parameters=method_desc.setdefault('parameters',{})
+386
+387# Add in the parameters common to all methods.
+388forname,descriptioninroot_desc.get('parameters',{}).iteritems():
+389parameters[name]=description
+390
+391# Add in undocumented query parameters.
+392fornameinSTACK_QUERY_PARAMETERS:
+393parameters[name]=STACK_QUERY_PARAMETER_DEFAULT_VALUE.copy()
+394
+395# Add 'body' (our own reserved word) to parameters if the method supports
+396# a request payload.
+397ifhttp_methodinHTTP_PAYLOAD_METHODSand'request'inmethod_desc:
+398body=BODY_PARAMETER_DEFAULT_VALUE.copy()
+399body.update(method_desc['request'])
+400parameters['body']=body
+401
+402returnparameters
+
406"""Updates parameters of API by adding 'media_body' if supported by method.
+407
+408 SIDE EFFECTS: If the method supports media upload and has a required body,
+409 sets body to be optional (required=False) instead. Also, if there is a
+410 'mediaUpload' in the method description, adds 'media_upload' key to
+411 parameters.
+412
+413 Args:
+414 method_desc: Dictionary with metadata describing an API method. Value comes
+415 from the dictionary of methods stored in the 'methods' key in the
+416 deserialized discovery document.
+417 root_desc: Dictionary; the entire original deserialized discovery document.
+418 path_url: String; the relative URL for the API method. Relative to the API
+419 root, which is specified in the discovery document.
+420 parameters: A dictionary describing method parameters for method described
+421 in method_desc.
+422
+423 Returns:
+424 Triple (accept, max_size, media_path_url) where:
+425 - accept is a list of strings representing what content types are
+426 accepted for media upload. Defaults to empty list if not in the
+427 discovery document.
+428 - max_size is a long representing the max size in bytes allowed for a
+429 media upload. Defaults to 0L if not in the discovery document.
+430 - media_path_url is a String; the absolute URI for media upload for the
+431 API method. Constructed using the API root URI and service path from
+432 the discovery document and the relative path for the API method. If
+433 media upload is not supported, this is None.
+434 """
+435media_upload=method_desc.get('mediaUpload',{})
+436accept=media_upload.get('accept',[])
-406max_size=_media_size_to_long(media_upload.get('maxSize',''))
-407media_path_url=None
-408
-409ifmedia_upload:
-410media_path_url=_media_path_url_from_info(root_desc,path_url)
-411parameters['media_body']=MEDIA_BODY_PARAMETER_DEFAULT_VALUE.copy()
-412if'body'inparameters:
-413parameters['body']['required']=False
-414
-415returnaccept=media_upload.get('accept',[])
+437max_size=_media_size_to_long(media_upload.get('maxSize',''))
+438media_path_url=None
+439
+440ifmedia_upload:
+441media_path_url=_media_path_url_from_info(root_desc,path_url)
+442parameters['media_body']=MEDIA_BODY_PARAMETER_DEFAULT_VALUE.copy()
+443if'body'inparameters:
+444parameters['body']['required']=False
+445
+446returnaccept,max_size,media_path_url
-
419"""Updates a method description in a discovery document.
-420
-421 SIDE EFFECTS: Changes the parameters dictionary in the method description with
-422 extra parameters which are used locally.
-423
-424 Args:
-425 method_desc: Dictionary with metadata describing an API method. Value comes
-426 from the dictionary of methods stored in the 'methods' key in the
-427 deserialized discovery document.
-428 root_desc: Dictionary; the entire original deserialized discovery document.
-429
-430 Returns:
-431 Tuple (path_url, http_method, method_id, accept, max_size, media_path_url)
-432 where:
-433 - path_url is a String; the relative URL for the API method. Relative to
-434 the API root, which is specified in the discovery document.
-435 - http_method is a String; the HTTP method used to call the API method
-436 described in the method description.
-437 - method_id is a String; the name of the RPC method associated with the
-438 API method, and is in the method description in the 'id' key.
-439 - accept is a list of strings representing what content types are
-440 accepted for media upload. Defaults to empty list if not in the
-441 discovery document.
-442 - max_size is a long representing the max size in bytes allowed for a
-443 media upload. Defaults to 0L if not in the discovery document.
-444 - media_path_url is a String; the absolute URI for media upload for the
-445 API method. Constructed using the API root URI and service path from
-446 the discovery document and the relative path for the API method. If
-447 media upload is not supported, this is None.
-448 """
-449path_url=method_desc['path']
-450http_method=method_desc['httpMethod']
-451method_id=method_desc['id']
-452
-453parameters=_fix_up_parameters(method_desc,root_desc,http_method)
-454# Order is important. `_fix_up_media_upload` needs `method_desc` to have a
-455# 'parameters' key and needs to know if there is a 'body' parameter because it
-456# also sets a 'media_body' parameter.
-457accept,max_size,media_path_url
+
450"""Updates a method description in a discovery document.
+451
+452 SIDE EFFECTS: Changes the parameters dictionary in the method description with
+453 extra parameters which are used locally.
+454
+455 Args:
+456 method_desc: Dictionary with metadata describing an API method. Value comes
+457 from the dictionary of methods stored in the 'methods' key in the
+458 deserialized discovery document.
+459 root_desc: Dictionary; the entire original deserialized discovery document.
+460
+461 Returns:
+462 Tuple (path_url, http_method, method_id, accept, max_size, media_path_url)
+463 where:
+464 - path_url is a String; the relative URL for the API method. Relative to
+465 the API root, which is specified in the discovery document.
+466 - http_method is a String; the HTTP method used to call the API method
+467 described in the method description.
+468 - method_id is a String; the name of the RPC method associated with the
+469 API method, and is in the method description in the 'id' key.
+470 - accept is a list of strings representing what content types are
+471 accepted for media upload. Defaults to empty list if not in the
+472 discovery document.
+473 - max_size is a long representing the max size in bytes allowed for a
+474 media upload. Defaults to 0L if not in the discovery document.
+475 - media_path_url is a String; the absolute URI for media upload for the
+476 API method. Constructed using the API root URI and service path from
+477 the discovery document and the relative path for the API method. If
+478 media upload is not supported, this is None.
+479 """
+480path_url=method_desc['path']
+481http_method=method_desc['httpMethod']
+482method_id=method_desc['id']
+483
+484parameters=_fix_up_parameters(method_desc,root_desc,http_method)
+485# Order is important. `_fix_up_media_upload` needs `method_desc` to have a
+486# 'parameters' key and needs to know if there is a 'body' parameter because it
+487# also sets a 'media_body' parameter.
+488accept,max_size,media_path_url=_fix_up_media_upload(
-458method_desc,root_desc,path_url,parameters)
-459
-460returnpath_url,http_method,method_id,accept,max_size,media_path_url=_fix_up_media_upload(
+489method_desc,root_desc,path_url,parameters)
+490
+491returnpath_url,http_method,method_id,accept,max_size,media_path_url
-
461
-
462
-463# TODO(dhermes): Convert this class to ResourceMethod and make it callable
-464-classResourceMethodParameters(object):
-
465"""Represents the parameters associated with a method.
-466
-467 Attributes:
-468 argmap: Map from method parameter name (string) to query parameter name
-469 (string).
-470 required_params: List of required parameters (represented by parameter
-471 name as string).
-472 repeated_params: List of repeated parameters (represented by parameter
-473 name as string).
-474 pattern_params: Map from method parameter name (string) to regular
-475 expression (as a string). If the pattern is set for a parameter, the
-476 value for that parameter must match the regular expression.
-477 query_params: List of parameters (represented by parameter name as string)
-478 that will be used in the query string.
-479 path_params: Set of parameters (represented by parameter name as string)
-480 that will be used in the base URL path.
-481 param_types: Map from method parameter name (string) to parameter type. Type
-482 can be any valid JSON schema type; valid values are 'any', 'array',
-483 'boolean', 'integer', 'number', 'object', or 'string'. Reference:
-484 http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1
-485 enum_params: Map from method parameter name (string) to list of strings,
-486 where each list of strings is the list of acceptable enum values.
-487 """
-488
-
490"""Constructor for ResourceMethodParameters.
-491
-492 Sets default values and defers to set_parameters to populate.
-493
-494 Args:
-495 method_desc: Dictionary with metadata describing an API method. Value
-496 comes from the dictionary of methods stored in the 'methods' key in
-497 the deserialized discovery document.
-498 """
-499self.argmap={}
-500self.required_params=[]
-501self.repeated_params=[]
-502self.pattern_params={}
-503self.query_params=[]
-504# TODO(dhermes): Change path_params to a list if the extra URITEMPLATE
-505# parsing is gotten rid of.
-506self.path_params=set()
-507self.param_types={}
-508self.enum_params={}
-509
-510self.set_parameters(method_desc)
-
513"""Populates maps and lists based on method description.
-514
-515 Iterates through each parameter for the method and parses the values from
-516 the parameter dictionary.
-517
-518 Args:
-519 method_desc: Dictionary with metadata describing an API method. Value
-520 comes from the dictionary of methods stored in the 'methods' key in
-521 the deserialized discovery document.
-522 """
-523forarg,descinmethod_desc.get('parameters',{}).iteritems():
-524param=key2param(arg)
-525self.argmap[param]=arg
-526
-527ifdesc.get('pattern'):
-528self.pattern_params[param]=desc['pattern']
-529ifdesc.get('enum'):
-530self.enum_params[param]=desc['enum']
-531ifdesc.get('required'):
-532self.required_params.append(param)
-533ifdesc.get('repeated'):
-534self.repeated_params.append(param)
-535ifdesc.get('location')=='query':
-536self.query_params.append(param)
-537ifdesc.get('location')=='path':
-538self.path_params.add(param)
-539self.param_types[param]=desc.get('type','string')
+googleapiclient.model.RawModel.accept" class="py-name" href="#" onclick="return doclink('link-110', 'accept', 'link-100');">accept,max_size,media_path_url
+
492
+
493
+494# TODO(dhermes): Convert this class to ResourceMethod and make it callable
+495-classResourceMethodParameters(object):
+
496"""Represents the parameters associated with a method.
+497
+498 Attributes:
+499 argmap: Map from method parameter name (string) to query parameter name
+500 (string).
+501 required_params: List of required parameters (represented by parameter
+502 name as string).
+503 repeated_params: List of repeated parameters (represented by parameter
+504 name as string).
+505 pattern_params: Map from method parameter name (string) to regular
+506 expression (as a string). If the pattern is set for a parameter, the
+507 value for that parameter must match the regular expression.
+508 query_params: List of parameters (represented by parameter name as string)
+509 that will be used in the query string.
+510 path_params: Set of parameters (represented by parameter name as string)
+511 that will be used in the base URL path.
+512 param_types: Map from method parameter name (string) to parameter type. Type
+513 can be any valid JSON schema type; valid values are 'any', 'array',
+514 'boolean', 'integer', 'number', 'object', or 'string'. Reference:
+515 http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1
+516 enum_params: Map from method parameter name (string) to list of strings,
+517 where each list of strings is the list of acceptable enum values.
+518 """
+519
+
521"""Constructor for ResourceMethodParameters.
+522
+523 Sets default values and defers to set_parameters to populate.
+524
+525 Args:
+526 method_desc: Dictionary with metadata describing an API method. Value
+527 comes from the dictionary of methods stored in the 'methods' key in
+528 the deserialized discovery document.
+529 """
+530self.argmap={}
+531self.required_params=[]
+532self.repeated_params=[]
+533self.pattern_params={}
+534self.query_params=[]
+535# TODO(dhermes): Change path_params to a list if the extra URITEMPLATE
+536# parsing is gotten rid of.
+537self.path_params=set()
+538self.param_types={}
+539self.enum_params={}540
-541# TODO(dhermes): Determine if this is still necessary. Discovery based APIs
-542# should have all path parameters already marked with
-543# 'location: path'.
-544formatchinURITEMPLATE.finditer(method_desc['path']):
-545fornamematchinVARNAME.finditer(match.group(0)):
-546name=key2param(namematch.group(0))
-547self.path_params.add(name)
-548ifnameinself.query_params:
-549self.query_params.remove(name)
-
553"""Creates a method for attaching to a Resource.
-554
-555 Args:
-556 methodName: string, name of the method to use.
-557 methodDesc: object, fragment of deserialized discovery document that
-558 describes the method.
-559 rootDesc: object, the entire deserialized discovery document.
-560 schema: object, mapping of schema names to schema descriptions.
-561 """
-562methodName=fix_method_name(methodName)
-563(pathUrl,httpMethod,methodId,541self.set_parameters(method_desc)
+
544"""Populates maps and lists based on method description.
+545
+546 Iterates through each parameter for the method and parses the values from
+547 the parameter dictionary.
+548
+549 Args:
+550 method_desc: Dictionary with metadata describing an API method. Value
+551 comes from the dictionary of methods stored in the 'methods' key in
+552 the deserialized discovery document.
+553 """
+554forarg,descinmethod_desc.get('parameters',{}).iteritems():
+555param=key2param(arg)
+556self.argmap[param]=arg
+557
+558ifdesc.get('pattern'):
+559self.pattern_params[param]=desc['pattern']
+560ifdesc.get('enum'):
+561self.enum_params[param]=desc['enum']
+562ifdesc.get('required'):
+563self.required_params.append(param)
+564ifdesc.get('repeated'):
+565self.repeated_params.append(param)
+566ifdesc.get('location')=='query':
+567self.query_params.append(param)
+568ifdesc.get('location')=='path':
+569self.path_params.add(param)
+570self.param_types[param]=desc.get('type','string')
+571
+572# TODO(dhermes): Determine if this is still necessary. Discovery based APIs
+573# should have all path parameters already marked with
+574# 'location: path'.
+575formatchinURITEMPLATE.finditer(method_desc['path']):
+576fornamematchinVARNAME.finditer(match.group(0)):
+577name=key2param(namematch.group(0))
+578self.path_params.add(name)
+579ifnameinself.query_params:
+580self.query_params.remove(name)
+
584"""Creates a method for attaching to a Resource.
+585
+586 Args:
+587 methodName: string, name of the method to use.
+588 methodDesc: object, fragment of deserialized discovery document that
+589 describes the method.
+590 rootDesc: object, the entire deserialized discovery document.
+591 schema: object, mapping of schema names to schema descriptions.
+592 """
+593methodName=fix_method_name(methodName)
+594(pathUrl,httpMethod,methodId,accept,
-564maxSize,mediaPathUrl)=_fix_up_method_description(methodDesc,rootDesc)
-565
-566parameters=ResourceMethodParameters(methodDesc)
-567
-568defmethod(self,**kwargs):
-569# Don't bother with doc string, it will be over-written by createMethod.
-570
-571fornameinkwargs.iterkeys():
-572ifnamenotinparameters.argmap:
-573raiseTypeError('Got an unexpected keyword argument "%s"'%name)
-574
-575# Remove args that have a value of None.
-576keys=kwargs.keys()
-577fornameinkeys:
-578ifkwargs[name]isNone:
-579delkwargs[name]
-580
-581fornameinparameters.required_params:
-582ifnamenotinkwargs:
-583raiseTypeError('Missing required parameter "%s"'%name)
-584
-585forname,regexinparameters.pattern_params.iteritems():
-586ifnameinkwargs:
-587ifisinstance(kwargs[name],basestring):
-588pvalues=[kwargs[name]]
-589else:
-590pvalues=kwargs[name]
-591forpvalueinpvalues:
-592ifre.match(regex,pvalue)isNone:
-593raiseTypeError(
-594'Parameter "%s" value "%s" does not match the pattern "%s"'%
-595(name,pvalue,regex))
+googleapiclient.model.RawModel.accept" class="py-name" href="#" onclick="return doclink('link-127', 'accept', 'link-100');">accept,
+595maxSize,mediaPathUrl)=_fix_up_method_description(methodDesc,rootDesc)596
-597forname,enumsinparameters.enum_params.iteritems():
-598ifnameinkwargs:
-599# We need to handle the case of a repeated enum
-600# name differently, since we want to handle both
-601# arg='value' and arg=['value1', 'value2']
-602if(nameinparameters.repeated_paramsand
-603notisinstance(kwargs[name],basestring)):
-604values=kwargs[name]
-605else:
-606values=[kwargs[name]]
-607forvalueinvalues:
-608ifvaluenotinenums:
-609raiseTypeError(
-610'Parameter "%s" value "%s" is not an allowed value in "%s"'%
-611(name,value,str(enums)))
-612
-613actual_query_params={}
-614actual_path_params={}
-615forkey,valueinkwargs.iteritems():
-616to_type=parameters.param_types.get(key,'string')
-617# For repeated parameters we cast each member of the list.
-618ifkeyinparameters.repeated_paramsandtype(value)==type([]):
-619cast_value=[_cast(x,to_type)forxinvalue]
-620else:
-621cast_value=_cast(value,to_type)
-622ifkeyinparameters.query_params:
-623actual_query_params[parameters.argmap[key]]=cast_value
-624ifkeyinparameters.path_params:
-625actual_path_params[parameters.argmap[key]]=cast_value
-626body_value=kwargs.get('body',None)
-627media_filename=kwargs.get('media_body',None)
-628
-629ifself._developerKey:
-630actual_query_params['key']=self._developerKey
-631
-632model=self._model
-633ifmethodName.endswith('_media'):
-634model=MediaModel()
-635elif'response'notinmethodDesc:
-636model=RawModel()
-637
-638headers={}
-639headers,params,query,body=model.597parameters=ResourceMethodParameters(methodDesc)
+598
+599defmethod(self,**kwargs):
+600# Don't bother with doc string, it will be over-written by createMethod.
+601
+602fornameinkwargs.iterkeys():
+603ifnamenotinparameters.argmap:
+604raiseTypeError('Got an unexpected keyword argument "%s"'%name)
+605
+606# Remove args that have a value of None.
+607keys=kwargs.keys()
+608fornameinkeys:
+609ifkwargs[name]isNone:
+610delkwargs[name]
+611
+612fornameinparameters.required_params:
+613ifnamenotinkwargs:
+614raiseTypeError('Missing required parameter "%s"'%name)
+615
+616forname,regexinparameters.pattern_params.iteritems():
+617ifnameinkwargs:
+618ifisinstance(kwargs[name],basestring):
+619pvalues=[kwargs[name]]
+620else:
+621pvalues=kwargs[name]
+622forpvalueinpvalues:
+623ifre.match(regex,pvalue)isNone:
+624raiseTypeError(
+625'Parameter "%s" value "%s" does not match the pattern "%s"'%
+626(name,pvalue,regex))
+627
+628forname,enumsinparameters.enum_params.iteritems():
+629ifnameinkwargs:
+630# We need to handle the case of a repeated enum
+631# name differently, since we want to handle both
+632# arg='value' and arg=['value1', 'value2']
+633if(nameinparameters.repeated_paramsand
+634notisinstance(kwargs[name],basestring)):
+635values=kwargs[name]
+636else:
+637values=[kwargs[name]]
+638forvalueinvalues:
+639ifvaluenotinenums:
+640raiseTypeError(
+641'Parameter "%s" value "%s" is not an allowed value in "%s"'%
+642(name,value,str(enums)))
+643
+644actual_query_params={}
+645actual_path_params={}
+646forkey,valueinkwargs.iteritems():
+647to_type=parameters.param_types.get(key,'string')
+648# For repeated parameters we cast each member of the list.
+649ifkeyinparameters.repeated_paramsandtype(value)==type([]):
+650cast_value=[_cast(x,to_type)forxinvalue]
+651else:
+652cast_value=_cast(value,to_type)
+653ifkeyinparameters.query_params:
+654actual_query_params[parameters.argmap[key]]=cast_value
+655ifkeyinparameters.path_params:
+656actual_path_params[parameters.argmap[key]]=cast_value
+657body_value=kwargs.get('body',None)
+658media_filename=kwargs.get('media_body',None)
+659
+660ifself._developerKey:
+661actual_query_params['key']=self._developerKey
+662
+663model=self._model
+664ifmethodName.endswith('_media'):
+665model=MediaModel()
+666elif'response'notinmethodDesc:
+667model=RawModel()
+668
+669headers={}
+670headers,params,query,body=model.request(headers,
-640actual_path_params,actual_query_params,body_value)
-641
-642expanded_url=uritemplate.expand(pathUrl,params)
-643url=urlparse.urljoin(self._baseUrl,expanded_url+query)
-644
-645resumable=None
-646multipart_boundary=''
-647
-648ifmedia_filename:
-649# Ensure we end up with a valid MediaUpload object.
-650ifisinstance(media_filename,basestring):
-651(media_mime_type,encoding)=mimetypes.guess_type(media_filename)
-652ifmedia_mime_typeisNone:
-653raiseUnknownFileType(media_filename)
-654ifnotmimeparse.best_match([media_mime_type],','.join(request(headers,
+671actual_path_params,actual_query_params,body_value)
+672
+673expanded_url=uritemplate.expand(pathUrl,params)
+674url=urlparse.urljoin(self._baseUrl,expanded_url+query)
+675
+676resumable=None
+677multipart_boundary=''
+678
+679ifmedia_filename:
+680# Ensure we end up with a valid MediaUpload object.
+681ifisinstance(media_filename,basestring):
+682(media_mime_type,encoding)=mimetypes.guess_type(media_filename)
+683ifmedia_mime_typeisNone:
+684raiseUnknownFileType(media_filename)
+685ifnotmimeparse.best_match([media_mime_type],','.join(accept)):
-655raiseUnacceptableMimeTypeError(media_mime_type)
-656media_upload=MediaFileUpload(media_filename,
-657mimetype=media_mime_type)
-658elifisinstance(media_filename,MediaUpload):
-659media_upload=media_filename
-660else:
-661raiseTypeError('media_filename must be str or MediaUpload.')
-662
-663# Check the maxSize
-664ifmaxSize>0andmedia_upload.size()>maxSize:
-665raiseMediaUploadSizeError("Media larger than: %s"%maxSize)
-666
-667# Use the media path uri for media uploads
-668expanded_url=uritemplate.expand(mediaPathUrl,params)
-669url=urlparse.urljoin(self._baseUrl,expanded_url+query)
-670ifmedia_upload.resumable():
-671url=_add_query_parameter(url,'uploadType','resumable')
-672
-673ifmedia_upload.resumable():
-674# This is all we need to do for resumable, if the body exists it gets
-675# sent in the first request, otherwise an empty body is sent.
-676resumable=media_upload
-677else:
-678# A non-resumable upload
-679ifbodyisNone:
-680# This is a simple media upload
-681headers['content-type']=media_upload.mimetype()
-682body=media_upload.getbytes(0,media_upload.size())
-683url=_add_query_parameter(url,'uploadType','media')
-684else:
-685# This is a multipart/related upload.
-686msgRoot=MIMEMultipart('related')
-687# msgRoot should not write out it's own headers
-688setattr(msgRoot,'_write_headers',lambdaself:None)
-689
-690# attach the body as one part
-691msg=MIMENonMultipart(*headers['content-type'].split('/'))
-692msg.set_payload(body)
-693msgRoot.attach(msg)
-694
-695# attach the media as the second part
-696msg=MIMENonMultipart(*media_upload.mimetype().split('/'))
-697msg['Content-Transfer-Encoding']='binary'
-698
-699payload=media_upload.getbytes(0,media_upload.size())
-700msg.set_payload(payload)
-701msgRoot.attach(msg)
-702body=msgRoot.as_string()
+googleapiclient.model.RawModel.accept" class="py-name" href="#" onclick="return doclink('link-147', 'accept', 'link-100');">accept)):
+686raiseUnacceptableMimeTypeError(media_mime_type)
+687media_upload=MediaFileUpload(media_filename,
+688mimetype=media_mime_type)
+689elifisinstance(media_filename,MediaUpload):
+690media_upload=media_filename
+691else:
+692raiseTypeError('media_filename must be str or MediaUpload.')
+693
+694# Check the maxSize
+695ifmaxSize>0andmedia_upload.size()>maxSize:
+696raiseMediaUploadSizeError("Media larger than: %s"%maxSize)
+697
+698# Use the media path uri for media uploads
+699expanded_url=uritemplate.expand(mediaPathUrl,params)
+700url=urlparse.urljoin(self._baseUrl,expanded_url+query)
+701ifmedia_upload.resumable():
+702url=_add_query_parameter(url,'uploadType','resumable')703
-704multipart_boundary=msgRoot.get_boundary()
-705headers['content-type']=('multipart/related; '
-706'boundary="%s"')%multipart_boundary
-707url=_add_query_parameter(url,'uploadType','multipart')
-708
-709logger.info('URL being requested: %s'%url)
-710returnself._requestBuilder(self._http,
-711model.response,
-712url,
-713method=httpMethod,
-714body=body,
-715headers=headers,
-716methodId=methodId,
-717resumable=resumable)
-
718
-719docs=[methodDesc.get('description',DEFAULT_METHOD_DOC),'\n\n']
-720iflen(parameters.argmap)>0:
-721docs.append('Args:\n')
-722
-723# Skip undocumented params and params common to all methods.
-724skip_parameters=rootDesc.get('parameters',{}).keys()
-725skip_parameters.extend(STACK_QUERY_PARAMETERS)
-726
-727all_args=parameters.argmap.keys()
-728args_ordered=[key2param(s)forsinmethodDesc.get('parameterOrder',[])]
+704ifmedia_upload.resumable():
+705# This is all we need to do for resumable, if the body exists it gets
+706# sent in the first request, otherwise an empty body is sent.
+707resumable=media_upload
+708else:
+709# A non-resumable upload
+710ifbodyisNone:
+711# This is a simple media upload
+712headers['content-type']=media_upload.mimetype()
+713body=media_upload.getbytes(0,media_upload.size())
+714url=_add_query_parameter(url,'uploadType','media')
+715else:
+716# This is a multipart/related upload.
+717msgRoot=MIMEMultipart('related')
+718# msgRoot should not write out it's own headers
+719setattr(msgRoot,'_write_headers',lambdaself:None)
+720
+721# attach the body as one part
+722msg=MIMENonMultipart(*headers['content-type'].split('/'))
+723msg.set_payload(body)
+724msgRoot.attach(msg)
+725
+726# attach the media as the second part
+727msg=MIMENonMultipart(*media_upload.mimetype().split('/'))
+728msg['Content-Transfer-Encoding']='binary'729
-730# Move body to the front of the line.
-731if'body'inall_args:
-732args_ordered.append('body')
-733
-734fornameinall_args:
-735ifnamenotinargs_ordered:
-736args_ordered.append(name)
-737
-738forarginargs_ordered:
-739ifarginskip_parameters:
-740continue
-741
-742repeated=''
-743ifarginparameters.repeated_params:
-744repeated=' (repeated)'
-745required=''
-746ifarginparameters.required_params:
-747required=' (required)'
-748paramdesc=methodDesc['parameters'][parameters.argmap[arg]]
-749paramdoc=paramdesc.get('description','A parameter')
-750if'$ref'inparamdesc:
-751docs.append(
-752(' %s: object, %s%s%s\n The object takes the'
-753' form of:\n\n%s\n\n')%(arg,paramdoc,required,repeated,
-754schema.prettyPrintByName(paramdesc['$ref'])))
-755else:
-756paramtype=paramdesc.get('type','string')
-757docs.append(' %s: %s, %s%s%s\n'%(arg,paramtype,paramdoc,required,
-758repeated))
-759enum=paramdesc.get('enum',[])
-760enumDesc=paramdesc.get('enumDescriptions',[])
-761ifenumandenumDesc:
-762docs.append(' Allowed values\n')
-763for(name,desc)inzip(enum,enumDesc):
-764docs.append(' %s - %s\n'%(name,desc))
-765if'response'inmethodDesc:
-766ifmethodName.endswith('_media'):
-767docs.append('\nReturns:\n The media object as a string.\n\n ')
-768else:
-769docs.append('\nReturns:\n An object of the form:\n\n ')
-770docs.append(schema.prettyPrintSchema(methodDesc['response']))
-771
-772setattr(method,'__doc__',''.join(docs))
-773return(methodName,method)
-
777"""Creates any _next methods for attaching to a Resource.
-778
-779 The _next methods allow for easy iteration through list() responses.
-780
-781 Args:
-782 methodName: string, name of the method to use.
-783 """
-784methodName=fix_method_name(methodName)
-785
-786defmethodNext(self,previous_request,previous_response):
-787"""Retrieves the next page of results.
-788
-789Args:
-790 previous_request: The request for the previous page. (required)
-791 previous_response: The response from the request for the previous page. (required)
-792
-793Returns:
-794 A request object that you can call 'execute()' on to request the next
-795 page. Returns None if there are no more items in the collection.
-796 """
-797# Retrieve nextPageToken from previous_response
-798# Use as pageToken in previous_request to create new request.
-799
-800if'nextPageToken'notinprevious_response:
-801returnNone
-802
-803730payload=media_upload.getbytes(0,media_upload.size())
+731msg.set_payload(payload)
+732msgRoot.attach(msg)
+733# encode the body: note that we can't use `as_string`, because
+734# it plays games with `From ` lines.
+735fp=StringIO.StringIO()
+736g=Generator(fp,mangle_from_=False)
+737g.flatten(msgRoot,unixfrom=False)
+738body=fp.getvalue()
+739
+740multipart_boundary=msgRoot.get_boundary()
+741headers['content-type']=('multipart/related; '
+742'boundary="%s"')%multipart_boundary
+743url=_add_query_parameter(url,'uploadType','multipart')
+744
+745logger.info('URL being requested: %s %s'%(httpMethod,url))
+746returnself._requestBuilder(self._http,
+747model.response,
+748url,
+749method=httpMethod,
+750body=body,
+751headers=headers,
+752methodId=methodId,
+753resumable=resumable)
+
754
+755docs=[methodDesc.get('description',DEFAULT_METHOD_DOC),'\n\n']
+756iflen(parameters.argmap)>0:
+757docs.append('Args:\n')
+758
+759# Skip undocumented params and params common to all methods.
+760skip_parameters=rootDesc.get('parameters',{}).keys()
+761skip_parameters.extend(STACK_QUERY_PARAMETERS)
+762
+763all_args=parameters.argmap.keys()
+764args_ordered=[key2param(s)forsinmethodDesc.get('parameterOrder',[])]
+765
+766# Move body to the front of the line.
+767if'body'inall_args:
+768args_ordered.append('body')
+769
+770fornameinall_args:
+771ifnamenotinargs_ordered:
+772args_ordered.append(name)
+773
+774forarginargs_ordered:
+775ifarginskip_parameters:
+776continue
+777
+778repeated=''
+779ifarginparameters.repeated_params:
+780repeated=' (repeated)'
+781required=''
+782ifarginparameters.required_params:
+783required=' (required)'
+784paramdesc=methodDesc['parameters'][parameters.argmap[arg]]
+785paramdoc=paramdesc.get('description','A parameter')
+786if'$ref'inparamdesc:
+787docs.append(
+788(' %s: object, %s%s%s\n The object takes the'
+789' form of:\n\n%s\n\n')%(arg,paramdoc,required,repeated,
+790schema.prettyPrintByName(paramdesc['$ref'])))
+791else:
+792paramtype=paramdesc.get('type','string')
+793docs.append(' %s: %s, %s%s%s\n'%(arg,paramtype,paramdoc,required,
+794repeated))
+795enum=paramdesc.get('enum',[])
+796enumDesc=paramdesc.get('enumDescriptions',[])
+797ifenumandenumDesc:
+798docs.append(' Allowed values\n')
+799for(name,desc)inzip(enum,enumDesc):
+800docs.append(' %s - %s\n'%(name,desc))
+801if'response'inmethodDesc:
+802ifmethodName.endswith('_media'):
+803docs.append('\nReturns:\n The media object as a string.\n\n ')
+804else:
+805docs.append('\nReturns:\n An object of the form:\n\n ')
+806docs.append(schema.prettyPrintSchema(methodDesc['response']))
+807
+808setattr(method,'__doc__',''.join(docs))
+809return(methodName,method)
+
813"""Creates any _next methods for attaching to a Resource.
+814
+815 The _next methods allow for easy iteration through list() responses.
+816
+817 Args:
+818 methodName: string, name of the method to use.
+819 """
+820methodName=fix_method_name(methodName)
+821
+822defmethodNext(self,previous_request,previous_response):
+823"""Retrieves the next page of results.
+824
+825Args:
+826 previous_request: The request for the previous page. (required)
+827 previous_response: The response from the request for the previous page. (required)
+828
+829Returns:
+830 A request object that you can call 'execute()' on to request the next
+831 page. Returns None if there are no more items in the collection.
+832 """
+833# Retrieve nextPageToken from previous_response
+834# Use as pageToken in previous_request to create new request.
+835
+836if'nextPageToken'notinprevious_response:
+837returnNone
+838
+839request=copy.copy(previous_request)
-804
-805pageToken=previous_response['nextPageToken']
-806parsed=list(urlparse.urlparse(request=copy.copy(previous_request)
+840
+841pageToken=previous_response['nextPageToken']
+842parsed=list(urlparse.urlparse(request.uri))
-807q=parse_qsl(parsed[4])
-808
-809# Find and remove old 'pageToken' value from URI
-810newq=[(key,value)for(key,value)inqifkey!='pageToken']
-811newq.append(('pageToken',pageToken))
-812parsed[4]=urllib.urlencode(newq)
-813uri=urlparse.urlunparse(parsed)
-814
-815request.uri))
+843q=parse_qsl(parsed[4])
+844
+845# Find and remove old 'pageToken' value from URI
+846newq=[(key,value)for(key,value)inqifkey!='pageToken']
+847newq.append(('pageToken',pageToken))
+848parsed[4]=urllib.urlencode(newq)
+849uri=urlparse.urlunparse(parsed)
+850
+851request.uri=uri
-816
-817logger.info('URL being requested: %s'%uri)
-818
-819returnrequest.uri=uri
+852
+853logger.info('URL being requested: %s %s'%(methodName,uri))
+854
+855returnrequest
-
829"""Build a Resource from the API description.
-830
-831 Args:
-832 http: httplib2.Http, Object to make http requests with.
-833 baseUrl: string, base URL for the API. All requests are relative to this
-834 URI.
-835 model: googleapiclient.Model, converts to and from the wire format.
-836 requestBuilder: class or callable that instantiates an
-837 googleapiclient.HttpRequest object.
-838 developerKey: string, key obtained from
-839 https://code.google.com/apis/console
-840 resourceDesc: object, section of deserialized discovery document that
-841 describes a resource. Note that the top level discovery document
-842 is considered a resource.
-843 rootDesc: object, the entire deserialized discovery document.
-844 schema: object, mapping of schema names to schema descriptions.
-845 """
-846self._dynamic_attrs=[]
-847
-848self._http=http
-849self._baseUrl=baseUrl
-850self._model=model
-851self._developerKey=developerKey
-852self._requestBuilder=requestBuilder
-853self._resourceDesc=resourceDesc
-854self._rootDesc=rootDesc
-855self._schema=schema
-856
-857self._set_service_methods()
+googleapiclient.model.Model.request" class="py-name" href="#" onclick="return doclink('link-193', 'request', 'link-59');">request
+
860"""Sets an instance attribute and tracks it in a list of dynamic attributes.
-861
-862 Args:
-863 attr_name: string; The name of the attribute to be set
-864 value: The value being set on the object and tracked in the dynamic cache.
-865 """
-866self._dynamic_attrs.append(attr_name)
-867self.__dict__[attr_name]=value
-
870"""Trim the state down to something that can be pickled.
-871
-872 Uses the fact that the instance variable _dynamic_attrs holds attrs that
-873 will be wiped and restored on pickle serialization.
-874 """
-875state_dict=copy.copy(self.__dict__)
-876fordynamic_attrinself._dynamic_attrs:
-877delstate_dict[dynamic_attr]
-878delstate_dict['_dynamic_attrs']
-879returnstate_dict
-
882"""Reconstitute the state of the object from being pickled.
-883
-884 Uses the fact that the instance variable _dynamic_attrs holds attrs that
-885 will be wiped and restored on pickle serialization.
-886 """
-887self.__dict__.update(state)
-888self._dynamic_attrs=[]
-889self._set_service_methods()
-
897# Add basic methods to Resource
-898if'methods'inresourceDesc:
-899formethodName,methodDescinresourceDesc['methods'].iteritems():
-900fixedMethodName,method=createMethod(
-901methodName,methodDesc,rootDesc,schema)
-902self._set_dynamic_attr(fixedMethodName,
-903method.__get__(self,self.__class__))
-904# Add in _media methods. The functionality of the attached method will
-905# change when it sees that the method name ends in _media.
-906ifmethodDesc.get('supportsMediaDownload',False):
-907fixedMethodName,method=createMethod(
-908methodName+'_media',methodDesc,rootDesc,schema)
-909self._set_dynamic_attr(fixedMethodName,
-910method.__get__(self,self.__class__))
-
913# Add in nested resources
-914if'resources'inresourceDesc:
-915
-916defcreateResourceMethod(methodName,methodDesc):
-917"""Create a method on the Resource to access a nested Resource.
-918
-919 Args:
-920 methodName: string, name of the method to use.
-921 methodDesc: object, fragment of deserialized discovery document that
-922 describes the method.
-923 """
-924methodName=fix_method_name(methodName)
-925
-926defmethodResource(self):
-927returnResource(http=self._http,baseUrl=self._baseUrl,
-928model=self._model,developerKey=self._developerKey,
-929requestBuilder=self._requestBuilder,
-930resourceDesc=methodDesc,rootDesc=rootDesc,
-931schema=schema)
-