确保POST数据有效JSON

时间:2016-09-12 13:04:36

标签: python json flask

我正在使用Python Flask开发JSON API 我想要的是始终返回JSON,并显示一条错误消息,指出发生的任何错误。

该API也只接受POST正文中的JSON数据,但是如果它无法将数据读取为JSON,则Flask默认返回HTML错误400。

最好,我也不想强迫用户发送Content-Type标头,如果是rawtext内容类型,请尝试将主体解析为JSON。

简而言之,我需要一种方法来验证POST主体是否为JSON,并自行处理错误。

我已经阅读了有关添加装饰器到request来做到这一点,但没有全面的例子。

3 个答案:

答案 0 :(得分:8)

您有三种选择:

就个人而言,我可能会选择第二种选择:

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有效内容引发异常。

答案 1 :(得分:1)

结合选项force=Truesilent=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的信用。

答案 2 :(得分:0)

您可以尝试使用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