Retornar resposta JSON da visualização Flask

464

Eu tenho uma função que analisa um arquivo CSV com o Pandas e produz um ditado com informações resumidas. Desejo retornar os resultados como resposta de uma exibição do Flask. Como faço para retornar uma resposta JSON?

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

Respostas:

753

Passe os dados de resumo para a jsonifyfunção, que retorna uma resposta JSON.

from flask import jsonify

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

No Flask 0.11, você pode transmitir qualquer tipo de serialização JSON, não apenas dict, como o objeto de nível superior.

codegeek
fonte
4
A partir do Flask 1.1.0 , agora você pode retornar diretamente um dict python, e ele será automaticamente jsonificado pelo Flask.
Adrien Ball
203

jsonifyserializa os dados que você os passa para JSON. Se você deseja serializar os dados por conta própria, faça o que jsonifyé construindo uma resposta com 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
scls
fonte
129

Passe argumentos de palavra-chave para flask.jsonifye eles serão exibidos como um 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
}

Se você já tem um ditado, pode passá-lo diretamente como jsonify(d).

zengr
fonte
1
Conforme as notas de versão 1.1.0 , o Flask permite retornar um dicionário a partir de uma função de visualização. Semelhante a como retornar uma string produzirá uma resposta de texto / html, retornar um dict chamará jsonify para produzir uma resposta de application / json,
CodeMantle
34

Se você não quiser usar jsonifypor algum motivo, pode fazer o que faz manualmente. Ligue flask.json.dumpspara criar dados JSON e, em seguida, retorne uma resposta com o application/jsontipo de conteúdo.

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é diferente do jsonmódulo embutido . Ele usará o simplejsonmódulo mais rápido , se disponível, e permite várias integrações com o aplicativo Flask.

Anthony Awuley
fonte
17

Se você deseja analisar um arquivo carregado pelo usuário, o Início rápido do Flask mostra como obter arquivos dos usuários e acessá-los. Obtenha o arquivo request.filese passe-o para a função de resumo.

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

Substitua a 'data'chave por request.filespelo nome da entrada do arquivo em seu formulário HTML.

teechap
fonte
13

Para retornar uma resposta JSON e definir um código de status, você pode usar make_response:

from flask import jsonify, make_response

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

Inspiração retirada deste comentário no rastreador de problemas do Flask.

rublo
fonte
10

Eu uso um decorador para retornar o resultado de jsonfiy. Eu acho que é mais legível quando uma visão tem vários retornos. Isso não oferece suporte ao retorno de uma tupla content, status, mas lida com o retorno de status de erro 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
fonte
4

Antes do Flask 0.11, jsonfiynão era permitido retornar uma matriz diretamente. Em vez disso, passe a lista como um argumento de palavra-chave.

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

No Flask 1.1, se você retornar um dicionário, ele será automaticamente convertido em JSON. Então, se make_summary()retornar um dicionário, você pode

from flask import Flask

app = Flask(__name__)

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

O SO que pergunta sobre a inclusão do código de status foi fechado como duplicado para este. Portanto, para também responder a essa pergunta, você pode incluir o código de status retornando uma tupla do formulário (dict, int). O dicté convertido para JSON e intserá o Código de Status HTTP. Sem nenhuma entrada, o Status é o padrão 200. Portanto, no exemplo acima, o código seria 200. No exemplo abaixo, ele é alterado para 201.

from flask import Flask

app = Flask(__name__)

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

Você pode verificar o código de status usando

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

se for um dict, o balão pode devolvê-lo diretamente (Versão 1.0.2)

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

"" " Usando a vista de base da 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)
Manish Sharma
fonte