关于python:从Flask视图返回JSON响应

Return JSON response from Flask view

我有一个功能,用Pandas分析CSV文件,并生成一个包含摘要信息的dict。 我想将结果作为Flask视图的响应返回。 如何返回JSON响应?

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

将摘要数据传递给jsonify函数,该函数返回JSON响应。

1
2
3
4
5
6
from flask import jsonify

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

从Flask 0.11开始,您可以将任何JSON可序列化类型(不仅仅是dict)作为顶级对象传递。


jsonify将传递给JSON的数据序列化。如果您想自己序列化数据,请通过使用status=200mimetype='application/json'构建响应来执行jsonify所做的操作。

1
2
3
4
5
6
7
8
9
10
11
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


将关键字参数传递给flask.jsonify,它们将作为JSON对象输出。

1
2
3
4
5
6
7
@app.route('/_get_current_user')
def get_current_user():
    return jsonify(
        username=g.user.username,
        email=g.user.email,
        id=g.user.id
    )
1
2
3
4
5
{
   "username":"admin",
   "email":"admin@localhost",
   "id": 42
}

如果您已经有一个dict,可以直接将其传递为jsonify(d)


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

1
2
3
4
5
6
7
8
9
10
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应用程序的各种集成。


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

1
2
3
4
5
6
7
8
9
10
11
12
13
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表单中输入文件的名称。


虽然flask.jsonify易于使用,但我更喜欢使用装饰器来返回json。它有助于返回任何json类型,并且在方法中有多个返回时更具可读性。 (请注意,此示例适用于200个响应,我通过引发异常和Flask.errorhandler返回错误)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def return_json(f):
    @functools.wraps(f)
    def inner(*a, **k):
        return json.dumps(f(*a, **k))
    return inner


@app.route('/test/')
@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 'non of them'


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

1
2
3
4
5
6
from flask import jsonify, make_response

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

Flask问题跟踪器中此评论的灵感。


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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)