How do I return a JSON array with Bottle?
Solution 1
Bottle's JSON plugin expects only dicts to be returned - not arrays. There are vulnerabilities associated with returning JSON arrays - see for example this post about JSON hijacking.
If you really need to do this, it can be done, e.g.
@route('/array')
def returnarray():
from bottle import response
from json import dumps
rv = [{ "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" }]
response.content_type = 'application/json'
return dumps(rv)
Solution 2
According to Bottle's 0.12 documentation:
As mentioned above, Python dictionaries (or subclasses thereof) are automatically transformed into JSON strings and returned to the browser with the Content-Type header set to application/json. This makes it easy to implement json-based APIs. Data formats other than json are supported too. See the tutorial-output-filter to learn more.
Which means you don't need to import json
nor setting the content_type attribute of the response.
Thus, the code gets hugely reduced:
@route('/array')
def returnarray():
rv = [{ "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" }]
return dict(data=rv)
And the JSON document returned by the Web server would look like:
{"data": [{"id": 1, "name": "Test Item 1"}, {"id": 2, "name": "Test Item 2"}]}
![Mark Bell](https://i.stack.imgur.com/1ashu.jpg?s=256&g=1)
Comments
-
Mark Bell over 4 years
I'm writing an API using Bottle, which so far has been fantastic. However, I've run up against a small hurdle when trying to return a JSON array. Here's my test app code:
from bottle import route, run @route('/single') def returnsingle(): return { "id": 1, "name": "Test Item 1" } @route('/containsarray') def returncontainsarray(): return { "items": [{ "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" }] } @route('/array') def returnarray(): return [{ "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" }] run(host='localhost', port=8080, debug=True, reloader=True)
When I run this and request each route, I get the JSON responses I'd expect from the first two routes:
/single
{ id: 1, name: "Test Item 1" }
/containsarray
{ "items": [ { "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" } ] }
So, I had expected returning a list of dictionaries to create the following JSON response:
[ { "id": 1, "name": "Test Object 1" }, { "id": 2, "name": "Test Object 2" } ]
But requesting the
/array
route just results in an error. What am I doing wrong, and how can I return a JSON array in this manner? -
Mark Bell almost 12 yearsThanks, that's an interesting article. Good to know I can still do this if I'm careful, though!
-
crunkchitis over 11 yearsThanks a million for this one.
-
Dacav over 10 yearsJavascript, why on the earth would you do that? Thanks man, here your +1
-
Tejas Tank about 7 yearsMost correct way of code bottle json response. thanks.