Skip to content

Commit 0c0c897

Browse files
MaerigJon Wayne Parrott
authored andcommitted
Make body optional for requests with no parameters (googleapis#446)
1 parent fff3ae5 commit 0c0c897

File tree

2 files changed

+49
-17
lines changed

2 files changed

+49
-17
lines changed

googleapiclient/discovery.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ def _media_path_url_from_info(root_desc, path_url):
448448
}
449449

450450

451-
def _fix_up_parameters(method_desc, root_desc, http_method):
451+
def _fix_up_parameters(method_desc, root_desc, http_method, schema):
452452
"""Updates parameters of an API method with values specific to this library.
453453
454454
Specifically, adds whatever global parameters are specified by the API to the
@@ -466,6 +466,7 @@ def _fix_up_parameters(method_desc, root_desc, http_method):
466466
root_desc: Dictionary; the entire original deserialized discovery document.
467467
http_method: String; the HTTP method used to call the API method described
468468
in method_desc.
469+
schema: Object, mapping of schema names to schema descriptions.
469470
470471
Returns:
471472
The updated Dictionary stored in the 'parameters' key of the method
@@ -486,6 +487,9 @@ def _fix_up_parameters(method_desc, root_desc, http_method):
486487
if http_method in HTTP_PAYLOAD_METHODS and 'request' in method_desc:
487488
body = BODY_PARAMETER_DEFAULT_VALUE.copy()
488489
body.update(method_desc['request'])
490+
# Make body optional for requests with no parameters.
491+
if not _methodProperties(method_desc, schema, 'request'):
492+
body['required'] = False
489493
parameters['body'] = body
490494

491495
return parameters
@@ -536,7 +540,7 @@ def _fix_up_media_upload(method_desc, root_desc, path_url, parameters):
536540
return accept, max_size, media_path_url
537541

538542

539-
def _fix_up_method_description(method_desc, root_desc):
543+
def _fix_up_method_description(method_desc, root_desc, schema):
540544
"""Updates a method description in a discovery document.
541545
542546
SIDE EFFECTS: Changes the parameters dictionary in the method description with
@@ -547,6 +551,7 @@ def _fix_up_method_description(method_desc, root_desc):
547551
from the dictionary of methods stored in the 'methods' key in the
548552
deserialized discovery document.
549553
root_desc: Dictionary; the entire original deserialized discovery document.
554+
schema: Object, mapping of schema names to schema descriptions.
550555
551556
Returns:
552557
Tuple (path_url, http_method, method_id, accept, max_size, media_path_url)
@@ -571,7 +576,7 @@ def _fix_up_method_description(method_desc, root_desc):
571576
http_method = method_desc['httpMethod']
572577
method_id = method_desc['id']
573578

574-
parameters = _fix_up_parameters(method_desc, root_desc, http_method)
579+
parameters = _fix_up_parameters(method_desc, root_desc, http_method, schema)
575580
# Order is important. `_fix_up_media_upload` needs `method_desc` to have a
576581
# 'parameters' key and needs to know if there is a 'body' parameter because it
577582
# also sets a 'media_body' parameter.
@@ -699,7 +704,7 @@ def createMethod(methodName, methodDesc, rootDesc, schema):
699704
"""
700705
methodName = fix_method_name(methodName)
701706
(pathUrl, httpMethod, methodId, accept,
702-
maxSize, mediaPathUrl) = _fix_up_method_description(methodDesc, rootDesc)
707+
maxSize, mediaPathUrl) = _fix_up_method_description(methodDesc, rootDesc, schema)
703708

704709
parameters = ResourceMethodParameters(methodDesc)
705710

tests/test_discovery.py

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
from googleapiclient.http import MediaUploadProgress
7676
from googleapiclient.http import tunnel_patch
7777
from googleapiclient.model import JsonModel
78+
from googleapiclient.schema import Schemas
7879
from oauth2client import GOOGLE_TOKEN_URI
7980
from oauth2client.client import OAuth2Credentials, GoogleCredentials
8081

@@ -122,18 +123,21 @@ def setUp(self):
122123
self.zoo_get_method_desc = self.zoo_root_desc['methods']['query']
123124
self.zoo_animals_resource = self.zoo_root_desc['resources']['animals']
124125
self.zoo_insert_method_desc = self.zoo_animals_resource['methods']['insert']
126+
self.zoo_schema = Schemas(self.zoo_root_desc)
125127

126128
def test_key2param(self):
127129
self.assertEqual('max_results', key2param('max-results'))
128130
self.assertEqual('x007_bond', key2param('007-bond'))
129131

130-
def _base_fix_up_parameters_test(self, method_desc, http_method, root_desc):
132+
def _base_fix_up_parameters_test(
133+
self, method_desc, http_method, root_desc, schema):
131134
self.assertEqual(method_desc['httpMethod'], http_method)
132135

133136
method_desc_copy = copy.deepcopy(method_desc)
134137
self.assertEqual(method_desc, method_desc_copy)
135138

136-
parameters = _fix_up_parameters(method_desc_copy, root_desc, http_method)
139+
parameters = _fix_up_parameters(method_desc_copy, root_desc, http_method,
140+
schema)
137141

138142
self.assertNotEqual(method_desc, method_desc_copy)
139143

@@ -147,14 +151,14 @@ def _base_fix_up_parameters_test(self, method_desc, http_method, root_desc):
147151
return parameters
148152

149153
def test_fix_up_parameters_get(self):
150-
parameters = self._base_fix_up_parameters_test(self.zoo_get_method_desc,
151-
'GET', self.zoo_root_desc)
154+
parameters = self._base_fix_up_parameters_test(
155+
self.zoo_get_method_desc, 'GET', self.zoo_root_desc, self.zoo_schema)
152156
# Since http_method is 'GET'
153157
self.assertFalse('body' in parameters)
154158

155159
def test_fix_up_parameters_insert(self):
156-
parameters = self._base_fix_up_parameters_test(self.zoo_insert_method_desc,
157-
'POST', self.zoo_root_desc)
160+
parameters = self._base_fix_up_parameters_test(
161+
self.zoo_insert_method_desc, 'POST', self.zoo_root_desc, self.zoo_schema)
158162
body = {
159163
'description': 'The request body.',
160164
'type': 'object',
@@ -165,35 +169,58 @@ def test_fix_up_parameters_insert(self):
165169

166170
def test_fix_up_parameters_check_body(self):
167171
dummy_root_desc = {}
172+
dummy_schema = {
173+
'Request': {
174+
'properties': {
175+
"description": "Required. Dummy parameter.",
176+
"type": "string"
177+
}
178+
}
179+
}
168180
no_payload_http_method = 'DELETE'
169181
with_payload_http_method = 'PUT'
170182

171183
invalid_method_desc = {'response': 'Who cares'}
172-
valid_method_desc = {'request': {'key1': 'value1', 'key2': 'value2'}}
184+
valid_method_desc = {
185+
'request': {
186+
'key1': 'value1',
187+
'key2': 'value2',
188+
'$ref': 'Request'
189+
}
190+
}
173191

174192
parameters = _fix_up_parameters(invalid_method_desc, dummy_root_desc,
175-
no_payload_http_method)
193+
no_payload_http_method, dummy_schema)
176194
self.assertFalse('body' in parameters)
177195

178196
parameters = _fix_up_parameters(valid_method_desc, dummy_root_desc,
179-
no_payload_http_method)
197+
no_payload_http_method, dummy_schema)
180198
self.assertFalse('body' in parameters)
181199

182200
parameters = _fix_up_parameters(invalid_method_desc, dummy_root_desc,
183-
with_payload_http_method)
201+
with_payload_http_method, dummy_schema)
184202
self.assertFalse('body' in parameters)
185203

186204
parameters = _fix_up_parameters(valid_method_desc, dummy_root_desc,
187-
with_payload_http_method)
205+
with_payload_http_method, dummy_schema)
188206
body = {
189207
'description': 'The request body.',
190208
'type': 'object',
191209
'required': True,
210+
'$ref': 'Request',
192211
'key1': 'value1',
193212
'key2': 'value2',
194213
}
195214
self.assertEqual(parameters['body'], body)
196215

216+
def test_fix_up_parameters_optional_body(self):
217+
# Request with no parameters
218+
dummy_schema = {'Request': {'properties': {}}}
219+
method_desc = {'request': {'$ref': 'Request'}}
220+
221+
parameters = _fix_up_parameters(method_desc, {}, 'POST', dummy_schema)
222+
self.assertFalse(parameters['body']['required'])
223+
197224
def _base_fix_up_method_description_test(
198225
self, method_desc, initial_parameters, final_parameters,
199226
final_accept, final_max_size, final_media_path_url):
@@ -260,7 +287,7 @@ def test_fix_up_media_upload_with_initial_valid_full(self):
260287

261288
def test_fix_up_method_description_get(self):
262289
result = _fix_up_method_description(self.zoo_get_method_desc,
263-
self.zoo_root_desc)
290+
self.zoo_root_desc, self.zoo_schema)
264291
path_url = 'query'
265292
http_method = 'GET'
266293
method_id = 'bigquery.query'
@@ -272,7 +299,7 @@ def test_fix_up_method_description_get(self):
272299

273300
def test_fix_up_method_description_insert(self):
274301
result = _fix_up_method_description(self.zoo_insert_method_desc,
275-
self.zoo_root_desc)
302+
self.zoo_root_desc, self.zoo_schema)
276303
path_url = 'animals'
277304
http_method = 'POST'
278305
method_id = 'zoo.animals.insert'

0 commit comments

Comments
 (0)