Restituisce la risposta JSON dalla vista Flask


464

Ho una funzione che analizza un file CSV con Panda e produce un dict con informazioni di riepilogo. Voglio restituire i risultati come risposta da una vista Flask. Come posso restituire una risposta JSON?

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

Risposte:


753

Passa i dati di riepilogo alla jsonifyfunzione, che restituisce una risposta JSON.

from flask import jsonify

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

A partire da Flask 0.11, puoi passare qualsiasi tipo serializzabile JSON, non solo dict, come oggetto di livello superiore.


4
A partire da Flask 1.1.0 , ora puoi restituire direttamente un dict di Python e verrà automaticamente jsonificato da Flask.
Adrien Ball

203

jsonifyserializza i dati passati a JSON. Se vuoi serializzare i dati da solo, fai cosa jsonifycreando una risposta con status=200e 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

129

Passa gli argomenti delle parole chiave a flask.jsonifye verranno emessi come oggetto 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
}

Se hai già un dict, puoi passarlo direttamente come jsonify(d).


1
Secondo le note di rilascio 1.1.0 , Flask consente di restituire un dizionario da una funzione di visualizzazione. Simile a come restituire una stringa produrrà una risposta text / html, la restituzione di un dict chiamerà jsonify per produrre una risposta application / json,
CodeMantle

34

Se non si desidera utilizzare jsonifyper qualche motivo, è possibile fare ciò che fa manualmente. Chiamare flask.json.dumpsper creare dati JSON, quindi restituire una risposta con il application/jsontipo di contenuto.

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.jsonè distinto dal jsonmodulo integrato. Utilizzerà il simplejsonmodulo più veloce se disponibile e consentirà varie integrazioni con l'app Flask.


17

Se si desidera analizzare un file caricato dall'utente, l'avvio rapido di Flask mostra come ottenere file dagli utenti e accedervi. Ottieni il file request.filese passalo alla funzione di riepilogo.

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')

Sostituisci la 'data'chiave request.filescon il nome dell'input del file nel tuo modulo HTML.


13

Per restituire una risposta JSON e impostare un codice di stato è possibile utilizzare make_response:

from flask import jsonify, make_response

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

Ispirazione tratta da questo commento nel tracker del problema Flask.



10

Uso un decoratore per restituire il risultato di jsonfiy. Penso che sia più leggibile quando una vista ha più ritorni. Questo non supporta la restituzione di una tupla simile content, status, ma gestisco app.errorhandlerinvece gli stati di errore di ritorno .

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'

4

Prima di Flask 0.11, jsonfiynon avrebbe permesso di restituire direttamente un array. Invece, passa l'elenco come argomento di parola chiave.

@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)

2

In Flask 1.1, se si restituisce un dizionario e questo verrà automaticamente convertito in JSON. Quindi, se make_summary()restituisce un dizionario, è possibile

from flask import Flask

app = Flask(__name__)

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

Il SO che chiede di includere il codice di stato è stato chiuso come duplicato a questo. Quindi, per rispondere anche a questa domanda, puoi includere il codice di stato restituendo una tupla del modulo (dict, int). La dictviene convertito in JSON e intsarà il codice di stato HTTP. Senza alcun input, lo stato è il valore predefinito 200. Quindi nell'esempio precedente il codice sarebbe 200. Nell'esempio seguente viene modificato in 201.

from flask import Flask

app = Flask(__name__)

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

Puoi controllare il codice di stato usando

curl --request GET "http://127.0.0.1:5000/summary" -w "\ncode: %{http_code}\n\n"

0

se è un dict, il pallone può restituirlo direttamente (Versione 1.0.2)

def summary():
    d = make_summary()
    return d, 200

0

"" " Uso della vista di classe Flask " ""

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)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.