build.app.decorators.validation._validate()   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nop 2
dl 0
loc 12
rs 9.9
c 0
b 0
f 0
1
from functools import wraps
2
from typing import Type, Optional
3
4
from flask import request
5
from pydantic import BaseModel, ValidationError
6
7
from app.context import context_property
8
9
10
def _validate(payload: Optional[dict], model: Type[BaseModel]) -> Optional[BaseModel]:
11
    if payload is None:
12
        payload = {}
13
14
    try:
15
        instance = model(**payload)
16
    except ValidationError:
17
        raise
18
    except:
19
        instance = None
20
21
    return instance
22
23
24
def validate(
25
    *,
26
    path_params: Type[BaseModel] = None,
27
    query_params: Type[BaseModel] = None,
28
    json: Type[BaseModel] = None,
29
    json_force_load: bool = False,
30
):
31
    def decorator(fn):
32
        @wraps(fn)
33
        def wrapper(*args, **kwargs):
34
            if path_params:
35
                payload = kwargs
36
                instance = _validate(payload, path_params)
37
                context_property.request_path_params = instance
38
39
            if query_params:
40
                payload = request.args
41
                instance = _validate(payload, query_params)
42
                context_property.request_query_params = instance
43
44
            if json:
45
                if json_force_load:
46
                    payload = request.get_json(force=True)
47
                else:
48
                    payload = request.json
49
50
                if hasattr(payload, "to_dict"):
51
                    payload = payload.to_dict()
52
53
                instance = _validate(payload, json)
54
                context_property.request_json = instance
55
56
            return fn(*args, **kwargs)
57
58
        return wrapper
59
60
    return decorator
61