Renvoyer la réponse JSON de la vue Flask

464

J'ai une fonction qui analyse un fichier CSV avec Pandas et produit un dict avec des informations résumées. Je souhaite renvoyer les résultats sous forme de réponse à partir d'une vue Flask. Comment renvoyer une réponse JSON?

@app.route("/summary")
def summary():
    d = make_summary()
    # send it back as json
Code Ninja
la source

Réponses:

753

Passez les données récapitulatives à la jsonifyfonction, qui renvoie une réponse JSON.

from flask import jsonify

@app.route('/summary')
def summary():
    d = make_summary()
    return jsonify(d)

Depuis Flask 0.11, vous pouvez passer n'importe quel type sérialisable JSON, pas seulement dict, comme objet de niveau supérieur.

codegeek
la source
4
Depuis Flask 1.1.0 , vous pouvez maintenant retourner directement un dict python, et il sera automatiquement jsonifié par Flask.
Adrien Ball
204

jsonifysérialise les données que vous transmettez à JSON. Si vous souhaitez sérialiser les données vous-même, faites ce qui se jsonifypasse en créant une réponse avec status=200et mimetype='application/json'.

from flask import json

@app.route('/summary')
def summary():
    data = make_summary()
    response = app.response_class(
        response=json.dumps(data),
        status=200,
        mimetype='application/json'
    )
    return response
scls
la source
129

Transmettez les arguments des mots clés à flask.jsonifyet ils seront affichés en tant qu'objet JSON.

@app.route('/_get_current_user')
def get_current_user():
    return jsonify(
        username=g.user.username,
        email=g.user.email,
        id=g.user.id
    )
{
    "username": "admin",
    "email": "admin@localhost",
    "id": 42
}

Si vous avez déjà un dict, vous pouvez le passer directement en tant que jsonify(d).

Zengr
la source
1
Conformément aux notes de version 1.1.0 , Flask permet de renvoyer un dictionnaire à partir d'une fonction d'affichage. Similaire à la façon dont le retour d'une chaîne produira une réponse text / html, le retour d'un dict appellera jsonify pour produire une réponse application / json,
CodeMantle
34

Si vous ne souhaitez pas l'utiliser jsonifypour une raison quelconque, vous pouvez faire ce qu'il fait manuellement. Appelez flask.json.dumpspour créer des données JSON, puis renvoyez une réponse avec le application/jsontype de contenu.

from flask import json

@app.route('/summary')
def summary():
    data = make_summary()
    response = app.response_class(
        response=json.dumps(data),
        mimetype='application/json'
    )
    return response

flask.jsonest distinct du jsonmodule intégré. Il utilisera le simplejsonmodule le plus rapide s'il est disponible et permet diverses intégrations avec votre application Flask.

Anthony Awuley
la source
17

Si vous souhaitez analyser un fichier téléchargé par l'utilisateur, le démarrage rapide de Flask montre comment obtenir des fichiers des utilisateurs et y accéder. Obtenez le fichier request.fileset passez-le à la fonction de résumé.

from flask import request, jsonify
from werkzeug import secure_filename

@app.route('/summary', methods=['GET', 'POST'])
def summary():
    if request.method == 'POST':
        csv = request.files['data']
        return jsonify(
            summary=make_summary(csv),
            csv_name=secure_filename(csv.filename)
        )

    return render_template('submit_data.html')

Remplacez la 'data'clé pour request.filespar le nom du fichier entré dans votre formulaire HTML.

teechap
la source
13

Pour renvoyer une réponse JSON et définir un code d'état, vous pouvez utiliser make_response:

from flask import jsonify, make_response

@app.route('/summary')
def summary():
    d = make_summary()
    return make_response(jsonify(d), 200)

Inspiration tirée de ce commentaire dans le suivi des problèmes de Flask.

rouble
la source
10

J'utilise un décorateur pour retourner le résultat de jsonfiy. Je pense que c'est plus lisible quand une vue a plusieurs retours. Cela ne prend pas en charge le retour d'un tuple comme content, status, mais je gère à la place le retour des états d'erreur app.errorhandler.

import functools
from flask import jsonify

def return_json(f):
    @functools.wraps(f)
    def inner(**kwargs):
        return jsonify(f(**kwargs))

    return inner

@app.route('/test/<arg>')
@return_json
def test(arg):
    if arg == 'list':
        return [1, 2, 3]
    elif arg == 'dict':
        return {'a': 1, 'b': 2}
    elif arg == 'bool':
        return True
    return 'none of them'
iman
la source
4

Avant Flask 0.11, jsonfiyne permettait pas de retourner directement un tableau. Au lieu de cela, passez la liste en tant qu'argument de mot clé.

@app.route('/get_records')
def get_records():
    results = [
        {
          "rec_create_date": "12 Jun 2016",
          "rec_dietary_info": "nothing",
          "rec_dob": "01 Apr 1988",
          "rec_first_name": "New",
          "rec_last_name": "Guy",
        },
        {
          "rec_create_date": "1 Apr 2016",
          "rec_dietary_info": "Nut allergy",
          "rec_dob": "01 Feb 1988",
          "rec_first_name": "Old",
          "rec_last_name": "Guy",
        },
    ]
    return jsonify(results=list)
mania_device
la source
2

Dans Flask 1.1, si vous renvoyez un dictionnaire, il sera automatiquement converti en JSON. Donc, si make_summary()renvoie un dictionnaire, vous pouvez

from flask import Flask

app = Flask(__name__)

@app.route('/summary')
def summary():
    d = make_summary()
    return d

L' OS qui demande d'inclure le code de statut a été fermé en double à celui-ci. Donc, pour répondre également à cette question, vous pouvez inclure le code d'état en renvoyant un tuple du formulaire (dict, int). Le dictest converti en JSON et intsera le code d'état HTTP. Sans aucune entrée, le statut est le 200 par défaut. Ainsi, dans l'exemple ci-dessus, le code serait 200. Dans l'exemple ci-dessous, il est remplacé par 201.

from flask import Flask

app = Flask(__name__)

@app.route('/summary')
def summary():
    d = make_summary()
    return d, 201  # 200 is the default

Vous pouvez vérifier le code d'état à l'aide de

curl --request GET "http://127.0.0.1:5000/summary" -w "\ncode: %{http_code}\n\n"
Steven C. Howell
la source
0

si c'est un dict, flask peut le retourner directement (Version 1.0.2)

def summary():
    d = make_summary()
    return d, 200
c8999c 3f964f64
la source
0

"" " Utilisation de Flask Class-base View " ""

from flask import Flask, request, jsonify

from flask.views import MethodView

app = Flask(**__name__**)

app.add_url_rule('/summary/', view_func=Summary.as_view('summary'))

class Summary(MethodView):

    def __init__(self):
        self.response = dict()

    def get(self):
        self.response['summary'] = make_summary()  # make_summary is a method to calculate the summary.
        return jsonify(self.response)
Manish Sharma
la source