从 Flask 视图返回 JSON 响应
- 2024-11-22 08:47:00
- admin 原创
- 197
问题描述:
我有一个函数,它使用 Pandas 分析 CSV 文件并生成包含摘要信息的字典。我想将结果作为 Flask 视图的响应返回。如何返回 JSON 响应?
@app.route("/summary")
def summary():
d = make_summary()
# send it back as json
解决方案 1:
视图可以直接返回 Python 字典或列表,Flask 将jsonify
自动调用。
@app.route("/summary")
def summary():
d = make_summary()
return d
对于旧版本的 Flask,或者要返回不同的 JSON 可序列化对象,请导入并使用jsonify
。
from flask import jsonify
@app.route("/summary")
def summary():
d = make_summary()
return jsonify(d)
解决方案 2:
jsonify
将您传递的数据序列化为 JSON。如果您想自己序列化数据,请使用和jsonify
构建响应来执行操作。status=200
`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
解决方案 3:
传递关键字参数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)
。
解决方案 4:
如果出于某种原因您不想使用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 应用进行各种集成。
解决方案 5:
要返回 JSON 响应并设置状态代码,您可以使用make_response
:
from flask import jsonify, make_response
@app.route('/summary')
def summary():
d = make_summary()
return make_response(jsonify(d), 200)
灵感来自于Flask 问题跟踪器中的这条评论。
解决方案 6:
从 Flask 1.1.0 版本开始,如果视图返回一个字典,它将被转换成 JSON 响应。
@app.route("/users", methods=['GET'])
def get_user():
return {
"user": "John Doe",
}
解决方案 7:
如果你想分析用户上传的文件,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')
'data'
将键替换request.files
为 HTML 表单中输入的文件名。
解决方案 8:
Flask 1.1.x 支持无需调用 即可返回 JSON 字典jsonify
。如果要返回字典以外的内容,仍需要调用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
解决方案 9:
我使用装饰器返回 的结果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'
解决方案 10:
在 Flask 1.1 中,如果你返回一个字典,它将自动转换为 JSON。所以如果make_summary()
返回一个字典,你可以
from flask import Flask
app = Flask(__name__)
@app.route('/summary')
def summary():
d = make_summary()
return d
询问是否包含状态代码的 SO已关闭,因为它与此 SO 重复。因此,要回答该问题,您可以通过返回以下形式的元组来包含状态代码(dict, int)
。dict
转换为 JSON,int
将成为 HTTP 状态代码。没有任何输入,状态是默认的 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 "
code: %{http_code}
"
解决方案 11:
在 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)
解决方案 12:
使用 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'))
解决方案 13:
如果它是一个字典,flask 可以直接返回它(版本 1.0.2)
def summary():
d = make_summary()
return d, 200
解决方案 14:
要序列化对象,请使用jsonify
fromflask
模块对对象进行 json 化,默认情况下字典会被序列化。此外,如果您正在处理文件,则始终可以使用make_response
。
解决方案 15:
我喜欢这种方式:
@app.route("/summary")
def summary():
responseBody = { "message": "bla bla bla", "summary": make_summary() }
return make_response(jsonify(responseBody), 200)