Devolver la respuesta JSON desde la vista Flask

464

Tengo una función que analiza un archivo CSV con Pandas y produce un dict con información de resumen. Quiero devolver los resultados como respuesta desde una vista de Flask. ¿Cómo devuelvo una respuesta JSON?

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

Respuestas:

753

Pase los datos de resumen a la jsonifyfunción, que devuelve una respuesta JSON.

from flask import jsonify

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

A partir de Flask 0.11, puede pasar cualquier tipo serializable JSON, no solo dict, como el objeto de nivel superior.

codegeek
fuente
44
A partir de Flask 1.1.0 , ahora puede devolver directamente un dict python, y Flask lo jsonificará automáticamente.
Adrien Ball
203

jsonifyserializa los datos que le pasa a JSON. Si desea serializar los datos usted mismo, haga lo que jsonifyhace creando una respuesta con status=200y 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
fuente
129

Pase argumentos de palabras clave flask.jsonifyy se generarán como un objeto 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 ya tiene un dict, puede pasarlo directamente como jsonify(d).

zengr
fuente
1
Según las notas de la versión 1.1.0 , Flask permite devolver un diccionario desde una función de vista. Similar a cómo devolver una cadena producirá una respuesta text / html, devolver un dict llamará a jsonify para producir una respuesta application / json,
CodeMantle
34

Si no quiere usarlo jsonifypor alguna razón, puede hacer lo que hace manualmente. Llame flask.json.dumpspara crear datos JSON, luego devuelva una respuesta con el application/jsontipo de contenido.

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.jsones distinto del jsonmódulo incorporado . Utilizará el simplejsonmódulo más rápido si está disponible, y permite diversas integraciones con su aplicación Flask.

Anthony Awuley
fuente
17

Si desea analizar un archivo cargado por el usuario, el inicio rápido de Flask muestra cómo obtener archivos de los usuarios y acceder a ellos. Obtenga el archivo request.filesy páselo a la función de resumen.

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

Reemplace la 'data'clave para request.filescon el nombre de la entrada del archivo en su formulario HTML.

teechap
fuente
13

Para devolver una respuesta JSON y establecer un código de estado, puede usar make_response:

from flask import jsonify, make_response

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

Inspiración tomada de este comentario en el rastreador de problemas de Flask.

rublo
fuente
10

Yo uso un decorador para devolver el resultado de jsonfiy. Creo que es más legible cuando una vista tiene múltiples retornos. Esto no admite la devolución de una tupla como content, status, pero en su lugar manejo los estados de error de devolución 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
fuente
4

Antes de Flask 0.11, jsonfiyno permitiría devolver una matriz directamente. En su lugar, pase la lista como argumento de palabra clave.

@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
fuente
2

En Flask 1.1, si devuelve un diccionario y se convertirá automáticamente en JSON. Entonces, si make_summary()devuelve un diccionario, puede

from flask import Flask

app = Flask(__name__)

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

El SO que pregunta sobre la inclusión del código de estado se cerró como un duplicado de este. Entonces, para responder también a esa pregunta, puede incluir el código de estado devolviendo una tupla del formulario (dict, int). El dictse convierte a JSON y intserá el código de estado HTTP. Sin ninguna entrada, el Estado es el 200 predeterminado. Por lo tanto, en el ejemplo anterior, el código sería 200. En el ejemplo a continuación, se cambia a 201.

from flask import Flask

app = Flask(__name__)

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

Puede verificar el código de estado usando

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

si es un dict, el matraz puede devolverlo directamente (Versión 1.0.2)

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

"" " Uso de la vista base de clase de matraz " ""

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
fuente