Passed
Push — master ( dc71c6...0c27db )
by Mingyu
01:32
created

build.app.decorators.validation   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 50
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 35
dl 0
loc 50
rs 10
c 0
b 0
f 0
wmc 6

1 Function

Rating   Name   Duplication   Size   Complexity  
B validate_with_pydantic() 0 34 6
1
from enum import Enum
2
from functools import wraps
3
from typing import Type
4
5
from flask import request
6
from pydantic import BaseModel, ValidationError
7
8
from app.context import context_property
9
10
11
class PayloadLocation(Enum):
12
    ARGS = "args"
13
    JSON = "json"
14
15
16
def validate_with_pydantic(
17
    *,
18
    payload_location: PayloadLocation,
19
    model: Type[BaseModel],
20
    json_force_load: bool = False,
21
):
22
    def decorator(fn):
23
        @wraps(fn)
24
        def wrapper(*args, **kwargs):
25
            if payload_location == PayloadLocation.JSON:
26
                if json_force_load:
27
                    payload = request.get_json(force=True)
28
                else:
29
                    payload = request.json
30
            else:
31
                payload = request.args
32
33
                if hasattr(payload, "to_dict"):
34
                    payload = payload.to_dict()
35
36
            try:
37
                instance = model(**payload)
38
            except ValidationError:
39
                raise
40
            except:
41
                instance = None
42
43
            context_property.request_payload = instance
44
45
            return fn(*args, **kwargs)
46
47
        return wrapper
48
49
    return decorator
50