web-dev-qa-db-fra.com

Comment renvoyer un tableau JSON avec Bottle?

J'écris une API en utilisant Bottle , ce qui jusqu'à présent a été fantastique. Cependant, je me suis heurté à un petit obstacle lors de la tentative de retour d'un tableau JSON. Voici mon code d'application de test:

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)

Lorsque j'exécute cela et demande chaque route, j'obtiens les réponses JSON que j'attendais des deux premières routes:

/simple

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

/containsarray

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

Donc, je m'attendais à retourner une liste de dictionnaires pour créer la réponse JSON suivante:

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

Mais demander au /array route entraîne simplement une erreur. Qu'est-ce que je fais mal et comment puis-je retourner un tableau JSON de cette manière?

30
Mark Bell

Le plugin JSON de Bottle s'attend à ce que seuls les dicts soient retournés - pas les tableaux. Il existe des vulnérabilités associées au retour de tableaux JSON - voir par exemple ce post sur le détournement JSON .

Si vous avez vraiment besoin de le faire, cela peut être fait, par exemple.

@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)
74
Vinay Sajip

Selon la documentation 0.12 de Bottle:

Comme mentionné ci-dessus, Python (ou leurs sous-classes) sont automatiquement transformés en chaînes JSON et renvoyés au navigateur avec l'en-tête Content-Type défini sur application/json. Cela facilite l'implémentation de json API basées sur. Les formats de données autres que json sont également pris en charge. Consultez le filtre de sortie du didacticiel pour en savoir plus.

Ce qui signifie que vous n'avez pas besoin de import json ni définir l'attribut content_type de la réponse.

Ainsi, le code est considérablement réduit:

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

Et le document JSON retourné par le serveur Web ressemblerait à:

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