我有一个烧瓶应用程序,调用期望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装饰器实现验证检查?
只需在装饰器中使用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
一个迟到的答案,但你可能正在寻找像棉花糖(烧瓶棉花糖)或烤蜜饯的东西。