Coverage for model/utils/request.py: 100%
50 statements
« prev ^ index » next coverage.py v7.3.2, created at 2024-11-05 04:22 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2024-11-05 04:22 +0000
1import time
2import json
3from functools import wraps
4from flask import request, current_app
5from mongo import engine
6from mongo.utils import doc_required
7from .response import *
9__all__ = (
10 'Request',
11 'get_ip',
12)
14type_map = {
15 'int': int,
16 'list': list,
17 'str': str,
18 'dict': dict,
19 'bool': bool,
20 'None': type(None)
21}
24class _Request(type):
26 def __getattr__(self, content_type):
28 def get(*keys, vars_dict={}):
30 def data_func(func):
32 @wraps(func)
33 def wrapper(*args, **kwargs):
34 data = getattr(request, content_type)
35 if data == None:
36 # FIXME: This exception doesn't mean the content type is wrong
37 return HTTPError(
38 f'Unaccepted Content-Type {content_type}', 415)
39 try:
40 # Magic
41 # yapf: disable
42 kwargs.update({
43 k: (lambda v: v
44 if t is None or type(v) is t else int(''))(
45 data.get((lambda s, *t: s + ''.join(
46 map(str.capitalize, t))
47 )(*filter(bool, k.split('_')))))
48 for k, t in map(
49 lambda x:
50 (x[0], (x[1:] or None) and type_map.get(x[1].strip())),
51 map(lambda q: q.split(':', 1), keys))
52 })
53 # yapf: enable
54 except ValueError as ve:
55 return HTTPError('Requested Value With Wrong Type',
56 400)
57 kwargs.update(
58 {v: data.get(vars_dict[v])
59 for v in vars_dict})
60 return func(*args, **kwargs)
62 return wrapper
64 return data_func
66 return get
69class Request(metaclass=_Request):
71 @staticmethod
72 def doc(src, des, cls=None, src_none_allowed=False):
73 '''
74 a warpper to `doc_required` for flask route
75 '''
77 def deco(func):
79 @doc_required(src, des, cls, src_none_allowed)
80 def inner_wrapper(*args, **ks):
81 return func(*args, **ks)
83 @wraps(func)
84 def real_wrapper(*args, **ks):
85 try:
86 return inner_wrapper(*args, **ks)
87 # if document not exists in db
88 except engine.DoesNotExist as e:
89 return HTTPError(str(e), 404)
90 # if args missing
91 except TypeError as e:
92 return HTTPError(str(e), 500)
93 except engine.ValidationError as e:
94 current_app.logger.info(
95 f'Validation error [err={e.to_dict()}]')
96 return HTTPError('Invalid parameter', 400)
98 return real_wrapper
100 return deco
103def get_ip() -> str:
104 ip = request.headers.get('X-Forwarded-For', '').split(',')[-1].strip()
105 return ip