Как вернуть массив JSON с помощью Bottle?

Я пишу API, используя Bottle, и пока это было фантастически. Однако я столкнулся с небольшим препятствием при попытке вернуть массив JSON. Вот код моего тестового приложения:

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)

Когда я запускаю это и запрашиваю каждый маршрут, я получаю ответы JSON, которые я ожидаю от первых двух маршрутов:

/одноместный

{ id: 1, name: "Test Item 1" }

/containsarray

{ "items": [ { "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" } ] }

Итак, я ожидал вернуть список словарей для создания следующего ответа JSON:

[ { "id": 1, "name": "Test Object 1" }, { "id": 2, "name": "Test Object 2" } ]

Но запрос маршрута /array просто приводит к ошибке. Что я делаю неправильно и как я могу вернуть массив JSON таким образом?


person Mark Bell    schedule 06.09.2012    source источник


Ответы (2)


Плагин Bottle JSON ожидает, что будут возвращены только словари, а не массивы. Существуют уязвимости, связанные с возвратом массивов JSON. См., например, этот пост о захвате JSON. .

Если вам действительно нужно это сделать, это можно сделать, например.

@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)
person Vinay Sajip    schedule 06.09.2012
comment
Спасибо, это интересная статья. Приятно знать, что я все еще могу это сделать, если буду осторожен! - person Mark Bell; 06.09.2012
comment
Миллион благодарностей за это. - person crunkchitis; 08.01.2013
comment
Джаваскрипт, с какой стати ты это делаешь? Спасибо чувак, вот твой +1 - person Dacav; 30.09.2013
comment
Самый правильный способ ответа json на бутылку с кодом. Благодарю. - person Tejas Tank; 30.03.2017

Согласно документации Bottle 0.12:

Как упоминалось выше, словари Python (или их подклассы) автоматически преобразуются в строки JSON и возвращаются в браузер с заголовком Content-Type, установленным в application/json. Это упрощает реализацию API на основе json. Также поддерживаются форматы данных, отличные от json. См. Tutorial-output-filter, чтобы узнать больше.

Это означает, что вам не нужно import json ни устанавливать атрибут content_type ответа.

Таким образом, код значительно сокращается:

@route('/array')
def returnarray():
    rv = [{ "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" }]
    return dict(data=rv)

И документ JSON, возвращаемый веб-сервером, будет выглядеть так:

{"data": [{"id": 1, "name": "Test Item 1"}, {"id": 2, "name": "Test Item 2"}]}
person jose.angel.jimenez    schedule 12.10.2015