从Flask视图返回JSON响应

我有一个功能,分析一个CSV文件与熊猫和产生一个词典的摘要信息。我想从Flask视图返回结果作为响应。如何返回JSON响应?

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

将关键字参数传递给flask.jsonify,它们将作为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
}

如果你已经有一个字典,你可以直接把它作为jsonify(d)传递。

从Flask 1.1.0开始,一个视图可以直接返回一个Python字典,Flask会自动调用jsonify

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

如果你的Flask版本低于1.1.0,或者返回一个不同的json序列化对象,请导入并使用jsonify

from flask import jsonify


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

如果您想分析用户上传的文件,Flask 快速入门显示了如何从用户获取文件并访问它们。从request.files获取文件并将其传递给摘要函数。

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

request.files'data'键替换为HTML表单中输入的文件名。

jsonify序列化传递给JSON的数据。如果您想自己序列化数据,可以像jsonify那样使用status=200mimetype='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

我使用装饰器返回jsonfiy的结果。我认为当一个视图有多个返回时可读性更好。这不支持返回像content, status这样的元组,但我用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'

在Flask 0.11之前,jsonfiy不允许直接返回数组。相反,将列表作为关键字参数传递。

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

如果出于某种原因不想使用jsonify,可以手动执行它的操作。调用flask.json.dumps创建JSON数据,然后返回内容类型为application/json的响应。

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与内置的json模块不同。它将使用更快的simplejson模块(如果可用),并支持与Flask应用程序的各种集成。

要返回JSON响应并设置状态码,您可以使用make_response:

from flask import jsonify, make_response


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

灵感来自这个评论在Flask问题跟踪器。

当使用Flask的基于类的视图时,答案是一样的。

from flask import Flask, request, jsonify
from flask.views import MethodView


app = Flask(__name__)


class Summary(MethodView):
def get(self):
d = make_summary()
return jsonify(d)


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

从1.1.0版本开始,如果视图返回dict,它将被转换为JSON响应. Flask。

@app.route("/users", methods=['GET'])
def get_user():
return {
"user": "John Doe",
}

如果是字典,flask可以直接返回(版本1.0.2)

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

在Flask 1.1中,如果你返回一个字典,它会自动转换成JSON。因此,如果make_summary()返回一个字典,则可以

from flask import Flask


app = Flask(__name__)


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

这就要求包含状态码被关闭为这个的副本。因此,要回答这个问题,可以通过返回形式为(dict, int)的元组来包含状态代码。dict被转换为JSON, int将是HTTP状态码。如果没有任何输入,Status默认为200。所以在上面的例子中,代码是200。在下面的示例中,它被更改为201。

from flask import Flask


app = Flask(__name__)


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

您可以使用检查状态码

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

1.1瓶。x支持在不调用jsonify的情况下返回JSON字典。如果你想返回dict以外的东西,你仍然需要调用jsonify

@app.route("/")
def index():
return {
"api_stuff": "values",
}

等于

@app.route("/")
def index():
return jsonify({
"api_stuff": "values",
})

查看添加了https://github.com/pallets/flask/pull/3111的拉请求

我喜欢这样:

    @app.route("/summary")
def summary():
responseBody = { "message": "bla bla bla", "summary": make_summary() }
return make_response(jsonify(responseBody), 200)

要序列化一个对象,使用jsonify from flask模块来jsonify对象,默认情况下字典会被序列化。另外,如果你在处理文件,你总是可以使用make_response