Flask:Decorator验证JSON和JSON Schema

问题描述 投票:14回答:2

我有一个烧瓶应用程序,调用期望JSON有效负载。在处理每个调用之前,我有一个两步错误检查过程:

  • 断言有效负载是有效的JSON
  • 断言JSON有效内容符合特定模式

以下列方式实现:

@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

由于此代码在许多调用中都是重复的,我想知道如果我可以优雅地将它移动到装饰器,那么形式为:

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

问题是request参数是隐式的:我可以在函数中引用它,但它不是它的参数。因此,我不知道如何在装饰器中使用它。

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

python flask decorator jsonschema python-decorators
2个回答
31
投票

只需在装饰器中使用request context global。它可在任何请求期间使用。

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

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

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

0
投票

一个迟到的答案,但你可能正在寻找像棉花糖(烧瓶棉花糖)或烤蜜饯的东西。

© www.soinside.com 2019 - 2024. All rights reserved.