Some methods don't specify a schema for their response, which means that

they are returning non-JSON such as CSV, images, etc. In that case
we return the bytes on the wire instead of trying to parse the response
as JSON.

Reviewed in http://codereview.appspot.com/5448123/
This commit is contained in:
Joe Gregorio
2011-12-07 09:48:22 -05:00
parent bd512b559a
commit e08a166fcb
4 changed files with 76 additions and 3 deletions

View File

@@ -52,6 +52,7 @@ from http import HttpRequest
from http import MediaUpload
from http import MediaFileUpload
from model import JsonModel
from model import RawModel
URITEMPLATE = re.compile('{[^}]*}')
VARNAME = re.compile('[a-zA-Z0-9_-]+')
@@ -437,8 +438,13 @@ def createResource(http, baseUrl, model, requestBuilder,
if self._developerKey:
actual_query_params['key'] = self._developerKey
model = self._model
# If there is no schema for the response then presume a binary blob.
if 'response' not in methodDesc:
model = RawModel()
headers = {}
headers, params, query, body = self._model.request(headers,
headers, params, query, body = model.request(headers,
actual_path_params, actual_query_params, body_value)
expanded_url = uritemplate.expand(pathUrl, params)
@@ -541,7 +547,7 @@ def createResource(http, baseUrl, model, requestBuilder,
logging.info('URL being requested: %s' % url)
return self._requestBuilder(self._http,
self._model.response,
model.response,
url,
method=httpMethod,
body=body,

View File

@@ -161,7 +161,8 @@ class BaseModel(Model):
Returns:
The query parameters properly encoded into an HTTP URI query string.
"""
params.update({'alt': self.alt_param})
if self.alt_param is not None:
params.update({'alt': self.alt_param})
astuples = []
for key, value in params.iteritems():
if type(value) == type([]):
@@ -269,6 +270,25 @@ class JsonModel(BaseModel):
return {}
class RawModel(JsonModel):
"""Model class for requests that don't return JSON.
Serializes and de-serializes between JSON and the Python
object representation of HTTP request, and returns the raw bytes
of the response body.
"""
accept = '*/*'
content_type = 'application/json'
alt_param = None
def deserialize(self, content):
return content
@property
def no_content_response(self):
return ''
class ProtocolBufferModel(BaseModel):
"""Model class for protocol buffers.

View File

@@ -289,6 +289,33 @@
"$ref": "Animal"
}
},
"getmedia": {
"path": "animals/{name}",
"id": "zoo.animals.get",
"httpMethod": "GET",
"description": "Get animals",
"parameters": {
"name": {
"location": "path",
"required": true,
"description": "Name of the animal to load",
"type": "string"
},
"projection": {
"location": "query",
"type": "string",
"enum": [
"full"
],
"enumDescriptions": [
"Include everything"
]
}
},
"parameterOrder": [
"name"
]
},
"insert": {
"path": "animals",
"id": "zoo.animals.insert",

View File

@@ -187,6 +187,26 @@ class Discovery(unittest.TestCase):
self.assertEqual(q['trace'], ['html'])
self.assertEqual(q['fields'], ['description'])
def test_model_added_query_parameters(self):
http = HttpMock(datafile('zoo.json'), {'status': '200'})
zoo = build('zoo', 'v1', http)
request = zoo.animals().get(name='Lion')
parsed = urlparse.urlparse(request.uri)
q = parse_qs(parsed[4])
self.assertEqual(q['alt'], ['json'])
self.assertEqual(request.headers['accept'], 'application/json')
def test_fallback_to_raw_model(self):
http = HttpMock(datafile('zoo.json'), {'status': '200'})
zoo = build('zoo', 'v1', http)
request = zoo.animals().getmedia(name='Lion')
parsed = urlparse.urlparse(request.uri)
q = parse_qs(parsed[4])
self.assertTrue('alt' not in q)
self.assertEqual(request.headers['accept'], '*/*')
def test_patch(self):
http = HttpMock(datafile('zoo.json'), {'status': '200'})
zoo = build('zoo', 'v1', http)