Flask:用于验证 JSON 和 JSON Schema 的装饰器 [英] Flask: Decorator to verify JSON and JSON Schema

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

问题描述

我有一个 Flask 应用程序,其调用需要 JSON 有效负载.在处理每个调用之前,我有一个 2 步错误检查过程:

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

  • 断言负载是有效的 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

由于此代码在多次调用中重复,我想知道我是否可以将其优雅地移动到装饰器中,形式为:

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():
    ....

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

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.

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

推荐答案

只需在装饰器中使用全局 request 上下文即可.它在任何请求期间可用.

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

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

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:用于验证 JSON 和 JSON Schema 的装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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