Make body optional for requests with no parameters (#446)
diff --git a/googleapiclient/discovery.py b/googleapiclient/discovery.py
index 163f3c9..7762d84 100644
--- a/googleapiclient/discovery.py
+++ b/googleapiclient/discovery.py
@@ -448,7 +448,7 @@
}
-def _fix_up_parameters(method_desc, root_desc, http_method):
+def _fix_up_parameters(method_desc, root_desc, http_method, schema):
"""Updates parameters of an API method with values specific to this library.
Specifically, adds whatever global parameters are specified by the API to the
@@ -466,6 +466,7 @@
root_desc: Dictionary; the entire original deserialized discovery document.
http_method: String; the HTTP method used to call the API method described
in method_desc.
+ schema: Object, mapping of schema names to schema descriptions.
Returns:
The updated Dictionary stored in the 'parameters' key of the method
@@ -486,6 +487,9 @@
if http_method in HTTP_PAYLOAD_METHODS and 'request' in method_desc:
body = BODY_PARAMETER_DEFAULT_VALUE.copy()
body.update(method_desc['request'])
+ # Make body optional for requests with no parameters.
+ if not _methodProperties(method_desc, schema, 'request'):
+ body['required'] = False
parameters['body'] = body
return parameters
@@ -536,7 +540,7 @@
return accept, max_size, media_path_url
-def _fix_up_method_description(method_desc, root_desc):
+def _fix_up_method_description(method_desc, root_desc, schema):
"""Updates a method description in a discovery document.
SIDE EFFECTS: Changes the parameters dictionary in the method description with
@@ -547,6 +551,7 @@
from the dictionary of methods stored in the 'methods' key in the
deserialized discovery document.
root_desc: Dictionary; the entire original deserialized discovery document.
+ schema: Object, mapping of schema names to schema descriptions.
Returns:
Tuple (path_url, http_method, method_id, accept, max_size, media_path_url)
@@ -571,7 +576,7 @@
http_method = method_desc['httpMethod']
method_id = method_desc['id']
- parameters = _fix_up_parameters(method_desc, root_desc, http_method)
+ parameters = _fix_up_parameters(method_desc, root_desc, http_method, schema)
# Order is important. `_fix_up_media_upload` needs `method_desc` to have a
# 'parameters' key and needs to know if there is a 'body' parameter because it
# also sets a 'media_body' parameter.
@@ -699,7 +704,7 @@
"""
methodName = fix_method_name(methodName)
(pathUrl, httpMethod, methodId, accept,
- maxSize, mediaPathUrl) = _fix_up_method_description(methodDesc, rootDesc)
+ maxSize, mediaPathUrl) = _fix_up_method_description(methodDesc, rootDesc, schema)
parameters = ResourceMethodParameters(methodDesc)
diff --git a/tests/test_discovery.py b/tests/test_discovery.py
index 01c67ef..941cfb0 100644
--- a/tests/test_discovery.py
+++ b/tests/test_discovery.py
@@ -75,6 +75,7 @@
from googleapiclient.http import MediaUploadProgress
from googleapiclient.http import tunnel_patch
from googleapiclient.model import JsonModel
+from googleapiclient.schema import Schemas
from oauth2client import GOOGLE_TOKEN_URI
from oauth2client.client import OAuth2Credentials, GoogleCredentials
@@ -122,18 +123,21 @@
self.zoo_get_method_desc = self.zoo_root_desc['methods']['query']
self.zoo_animals_resource = self.zoo_root_desc['resources']['animals']
self.zoo_insert_method_desc = self.zoo_animals_resource['methods']['insert']
+ self.zoo_schema = Schemas(self.zoo_root_desc)
def test_key2param(self):
self.assertEqual('max_results', key2param('max-results'))
self.assertEqual('x007_bond', key2param('007-bond'))
- def _base_fix_up_parameters_test(self, method_desc, http_method, root_desc):
+ def _base_fix_up_parameters_test(
+ self, method_desc, http_method, root_desc, schema):
self.assertEqual(method_desc['httpMethod'], http_method)
method_desc_copy = copy.deepcopy(method_desc)
self.assertEqual(method_desc, method_desc_copy)
- parameters = _fix_up_parameters(method_desc_copy, root_desc, http_method)
+ parameters = _fix_up_parameters(method_desc_copy, root_desc, http_method,
+ schema)
self.assertNotEqual(method_desc, method_desc_copy)
@@ -147,14 +151,14 @@
return parameters
def test_fix_up_parameters_get(self):
- parameters = self._base_fix_up_parameters_test(self.zoo_get_method_desc,
- 'GET', self.zoo_root_desc)
+ parameters = self._base_fix_up_parameters_test(
+ self.zoo_get_method_desc, 'GET', self.zoo_root_desc, self.zoo_schema)
# Since http_method is 'GET'
self.assertFalse('body' in parameters)
def test_fix_up_parameters_insert(self):
- parameters = self._base_fix_up_parameters_test(self.zoo_insert_method_desc,
- 'POST', self.zoo_root_desc)
+ parameters = self._base_fix_up_parameters_test(
+ self.zoo_insert_method_desc, 'POST', self.zoo_root_desc, self.zoo_schema)
body = {
'description': 'The request body.',
'type': 'object',
@@ -165,35 +169,58 @@
def test_fix_up_parameters_check_body(self):
dummy_root_desc = {}
+ dummy_schema = {
+ 'Request': {
+ 'properties': {
+ "description": "Required. Dummy parameter.",
+ "type": "string"
+ }
+ }
+ }
no_payload_http_method = 'DELETE'
with_payload_http_method = 'PUT'
invalid_method_desc = {'response': 'Who cares'}
- valid_method_desc = {'request': {'key1': 'value1', 'key2': 'value2'}}
+ valid_method_desc = {
+ 'request': {
+ 'key1': 'value1',
+ 'key2': 'value2',
+ '$ref': 'Request'
+ }
+ }
parameters = _fix_up_parameters(invalid_method_desc, dummy_root_desc,
- no_payload_http_method)
+ no_payload_http_method, dummy_schema)
self.assertFalse('body' in parameters)
parameters = _fix_up_parameters(valid_method_desc, dummy_root_desc,
- no_payload_http_method)
+ no_payload_http_method, dummy_schema)
self.assertFalse('body' in parameters)
parameters = _fix_up_parameters(invalid_method_desc, dummy_root_desc,
- with_payload_http_method)
+ with_payload_http_method, dummy_schema)
self.assertFalse('body' in parameters)
parameters = _fix_up_parameters(valid_method_desc, dummy_root_desc,
- with_payload_http_method)
+ with_payload_http_method, dummy_schema)
body = {
'description': 'The request body.',
'type': 'object',
'required': True,
+ '$ref': 'Request',
'key1': 'value1',
'key2': 'value2',
}
self.assertEqual(parameters['body'], body)
+ def test_fix_up_parameters_optional_body(self):
+ # Request with no parameters
+ dummy_schema = {'Request': {'properties': {}}}
+ method_desc = {'request': {'$ref': 'Request'}}
+
+ parameters = _fix_up_parameters(method_desc, {}, 'POST', dummy_schema)
+ self.assertFalse(parameters['body']['required'])
+
def _base_fix_up_method_description_test(
self, method_desc, initial_parameters, final_parameters,
final_accept, final_max_size, final_media_path_url):
@@ -260,7 +287,7 @@
def test_fix_up_method_description_get(self):
result = _fix_up_method_description(self.zoo_get_method_desc,
- self.zoo_root_desc)
+ self.zoo_root_desc, self.zoo_schema)
path_url = 'query'
http_method = 'GET'
method_id = 'bigquery.query'
@@ -272,7 +299,7 @@
def test_fix_up_method_description_insert(self):
result = _fix_up_method_description(self.zoo_insert_method_desc,
- self.zoo_root_desc)
+ self.zoo_root_desc, self.zoo_schema)
path_url = 'animals'
http_method = 'POST'
method_id = 'zoo.animals.insert'