Flask:Decorator来验证JSON和JSON Schema [英] Flask: Decorator to verify JSON and JSON Schema

查看:370
本文介绍了Flask:Decorator来验证JSON和JSON Schema的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个烧瓶应用程序与期待JSON有效载荷的调用。在处理每个调用之前,我有一个2步的错误检查过程:

$ ul
  • 断言有效载荷是有效的JSON

  • 断言JSON有效载荷符合特定模式

    $ b 以下列方式实现: p>

      @ app.route('/ activate',methods = ['POST'])
    def activate():
    request_id =请求.__散列__()

    #断言有效载荷是有效的JSON
    尝试:
    input = request.json
    除了BadRequest,e :
    msg =有效载荷必须是有效的json
    返回jsonify({error:msg}),400
    $ b $ JSON模式验证
    try:
    validate(request.json,app.config ['activate_schema'])
    除了ValidationError,e:
    返回jsonify({error:e.message}),400

    由于这段代码在很多调用中都是重复的,我想知道如果我可以优雅地移动它o $ decorator,formof中的一些东西:

    $ $ $ $ $ $ $ @ $ @ $ @ $ @ $ @ $ @ @ @ ])
    @ app.route('/ activate',methods = ['POST'])
    def activate():
    ....
    请求参数是隐含的:我可以在函数,但它不是一个参数。因此,我不确定如何在装饰器中使用它。



    如何使用Python装饰器实现验证检查?

    解决方案请在装饰器中使用请求 context global。它可以在任何请求期间使用。

      from functools import wrapps 
    from flask import
    current_app,
    jsonify,
    request,


    $ b def validate_json(f):
    @wraps(f)
    def包装(* args,** kw):
    尝试:
    request.json
    除了BadRequest,e:
    msg =有效负载必须是有效的json
    return jsonify({error:msg}),400
    返回f(* args,** kw)
    返回包装


    def validate_schema(schema_name):
    def decorator(f):
    @wrap(f)
    def wrapper(* args,** kw):
    try:
    验证(request.json,current_app.config [schema_name])
    除了ValidationError,e:
    返回jsonify({error:e.message}),400
    return f(* args ,** kw)
    返回包装
    返回装饰器

    在应用 @route 装饰器之前,在之前应用这些装饰器你想注册包装函数,而不是路由的原始函数:

      @ app.route('/ activate', ():
    input = request.json


    I have a flask application with calls expecting JSON payload. Before each call is processed, I have a 2-step error checking process:

    • Assert that the payload is a valid JSON
    • Assert that the JSON payload complies with a specific schema

    Which is implemented in the following fashion:

    @app.route('/activate', methods=['POST'])
    def activate():
        request_id = request.__hash__()
    
        # Assert that the payload is a valid JSON
        try:
            input = request.json
        except BadRequest, e:
            msg = "payload must be a valid json"
            return jsonify({"error": msg}), 400
    
        # JSON Schema Validation
        try:
            validate(request.json, app.config['activate_schema'])
        except ValidationError, e:
            return jsonify({"error": e.message}), 400
    

    Since this code is duplicated over many calls, I wonder If I can elegantly move it to a decorator, something in the formof:

    @validate_json
    @validate_schema(schema=app.config['activate_schema'])
    @app.route('/activate', methods=['POST'])
    def activate():
        ....
    

    The problem is that the request argument is implicit: I can refer to it within the function, but it is not a parameter to it. Therefore, I am not sure how to use it within the decorator.

    How can I implement the validation checks using Python decorators?

    解决方案

    Just use the request context global in your decorator. It is available during any request.

    from functools import wraps
    from flask import (
        current_app,
        jsonify,
        request,
    )
    
    
    def validate_json(f):
        @wraps(f)
        def wrapper(*args, **kw):
            try:
                request.json
            except BadRequest, e:
                msg = "payload must be a valid json"
                return jsonify({"error": msg}), 400
            return f(*args, **kw)
        return wrapper
    
    
    def validate_schema(schema_name):
        def decorator(f):
            @wraps(f)
            def wrapper(*args, **kw):
                try:
                    validate(request.json, current_app.config[schema_name])
                except ValidationError, e:
                    return jsonify({"error": e.message}), 400
                return f(*args, **kw)
            return wrapper
        return decorator
    

    Apply these decorators before applying the @route decorator; you want to register the wrapped function, not the original function for the route:

    @app.route('/activate', methods=['POST'])
    @validate_json
    @validate_schema('activate_schema')
    def activate():
        input = request.json
    

    这篇关于Flask:Decorator来验证JSON和JSON Schema的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
  • 登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆