Kolba: dekorator do weryfikacji schematu JSON i JSON
Mam aplikację flask z wywołaniami oczekującymi JSON payload. Zanim każde wywołanie zostanie przetworzone, mam 2-etapowy proces sprawdzania błędów:
- twierdzenie, że ładunek jest prawidłowym JSON
- Upewnij się, że ładunek JSON jest zgodny ze specyficznym schematem
Który jest realizowany w następujący sposób:
@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
Ponieważ ten kod jest powielany przez wiele wywołań, zastanawiam się, czy mogę elegancko przenieść go do dekoratora, coś w formie:
@validate_json
@validate_schema(schema=app.config['activate_schema'])
@app.route('/activate', methods=['POST'])
def activate():
....
The problem polega na tym, że argument request
jest niejawny: mogę się do niego odwoływać w ramach funkcji, ale nie jest to jej parametr. Dlatego nie jestem pewien, jak go użyć w dekoratorze.
Jak zaimplementować sprawdzanie poprawności przy użyciu dekoratorów Pythona?
1 answers
Po prostu użyj request
kontekstu globalnego w dekoratorze. Jest on dostępny podczas każdego żądania.
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
Zastosuj dekoratory przed Zastosuj dekorator @route
; chcesz zarejestrować funkcję zawiniętą, a nie oryginalną dla trasy:
@app.route('/activate', methods=['POST'])
@validate_json
@validate_schema('activate_schema')
def activate():
input = request.json
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-16 08:13:09