Passed
Push — master ( dae811...ce5c8c )
by Mingyu
01:30
created

build.app.decorators.validation   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 58
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 42
dl 0
loc 58
rs 10
c 0
b 0
f 0
wmc 9

2 Functions

Rating   Name   Duplication   Size   Complexity  
B validate() 0 37 6
A _validate() 0 9 3
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: dict, model: Type[BaseModel]) -> Optional[BaseModel]:
11
    try:
12
        instance = model(**payload)
13
    except ValidationError:
14
        raise
15
    except:
16
        instance = None
17
18
    return instance
19
20
21
def validate(
22
    *,
23
    path_params: Type[BaseModel] = None,
24
    query_params: Type[BaseModel] = None,
25
    json: Type[BaseModel] = None,
26
    json_force_load: bool = False,
27
):
28
    def decorator(fn):
29
        @wraps(fn)
30
        def wrapper(*args, **kwargs):
31
            if path_params:
32
                payload = kwargs
33
                instance = _validate(payload, path_params)
34
                context_property.request_path_params = instance
35
36
            if query_params:
37
                payload = request.args
38
                instance = _validate(payload, query_params)
39
                context_property.request_query_params = instance
40
41
            if json:
42
                if json_force_load:
43
                    payload = request.get_json(force=True)
44
                else:
45
                    payload = request.json
46
47
                if hasattr(payload, "to_dict"):
48
                    payload = payload.to_dict()
49
50
                instance = _validate(payload, json)
51
                context_property.request_json = instance
52
53
            return fn(*args, **kwargs)
54
55
        return wrapper
56
57
    return decorator
58