我正在使用Python Flask开发JSON API。 我想要的是始终返回JSON,并显示一条错误消息,指出发生了错误。
该API也只接受POST正文中的JSON数据,但如果无法将数据作为JSON读取,则Flask默认返回HTML错误400。
最好,我也不想强迫用户发送Content-Type
标头,如果raw
或text
内容类型,尝试解析身体为JSON。
简而言之,我需要一种方法来验证POST正文是JSON,并自己处理错误。
我已经阅读过关于添加装饰器到request
来做到这一点,但没有全面的例子。
你有三个选择:
Request.on_json_loading_failed
method设置为引发具有JSON有效负载的BadRequest
exception子类的东西。请参阅Werkzeug例外文档中的Custom Errors,了解如何创建一个。try: except
调用周围放置一个request.get_json()
,捕获BadRequest
异常并使用JSON有效负载引发新的异常。就个人而言,我可能会选择第二种选择:
from werkzeug.exceptions import BadRequest
from flask import json, Request, _request_ctx_stack
class JSONBadRequest(BadRequest):
def get_body(self, environ=None):
"""Get the JSON body."""
return json.dumps({
'code': self.code,
'name': self.name,
'description': self.description,
})
def get_headers(self, environ=None):
"""Get a list of headers."""
return [('Content-Type', 'application/json')]
def on_json_loading_failed(self):
ctx = _request_ctx_stack.top
if ctx is not None and ctx.app.config.get('DEBUG', False):
raise JSONBadRequest('Failed to decode JSON object: {0}'.format(e))
raise JSONBadRequest()
Request.on_json_loading_failed = on_json_loading_failed
现在,每次request.get_json()
失败时,它都会调用您的自定义on_json_loading_failed
方法,并使用JSON有效负载而不是HTML有效负载引发异常。
组合选项force=True
和silent=True
使得request.get_json
的结果是None
如果数据不可解析,那么简单的if
允许您检查解析。
from flask import Flask
from flask import request
@app.route('/foo', methods=['POST'])
def function(function = None):
print "Data: ", request.get_json(force = True, silent = True);
if request.get_json() is not None:
return "Is JSON";
else:
return "Nope";
if __name__ == "__main__":
app.run()
对lapinkoira和Martijn Pieters的信用。
您可以尝试使用python json库解码JSON对象。主要思想是采用普通请求体并尝试转换为JSON.E.g:
import json
...
# somewhere in view
def view():
try:
json.loads(request.get_data())
except ValueError:
# not a JSON! return error
return {'error': '...'}
# do plain stuff