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?

Author: Martijn Pieters, 2014-06-16

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
 28
Author: Martijn Pieters,
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