1
- import typing
2
-
1
+ import inspect
3
2
import re
4
-
5
- from .parameter_types import Route , Json , Query , Form , File
6
- from .exceptions import MissingInputError , InvalidParameterTypeError , ValidationError
7
- from flask import request , current_app
8
3
from inspect import signature
4
+
5
+ from flask import request
9
6
from werkzeug .exceptions import BadRequest
10
- import inspect
7
+
8
+ from .exceptions import (InvalidParameterTypeError , MissingInputError ,
9
+ ValidationError )
10
+ from .parameter_types import File , Form , Json , Query , Route
11
11
12
12
fn_list = dict ()
13
+
14
+
13
15
class ValidateParameters :
14
16
@classmethod
15
17
def get_fn_list (cls ):
@@ -22,15 +24,19 @@ def __call__(self, f):
22
24
"""
23
25
Parent flow for validating each required parameter
24
26
"""
25
- fsig = f .__module__ + "." + f .__name__
27
+ fsig = f .__module__ + "." + f .__name__
26
28
argspec = inspect .getfullargspec (f )
27
29
source = inspect .getsource (f )
28
30
index = source .find ("def " )
29
31
decorators = []
30
32
for line in source [:index ].strip ().splitlines ():
31
33
if line .strip ()[0 ] == "@" :
32
34
decorators .append (line )
33
- fdocs = {"argspec" : argspec , "docstring" : f .__doc__ .strip () if f .__doc__ else None , "decorators" : decorators .copy ()}
35
+ fdocs = {
36
+ "argspec" : argspec ,
37
+ "docstring" : f .__doc__ .strip () if f .__doc__ else None ,
38
+ "decorators" : decorators .copy (),
39
+ }
34
40
fn_list [fsig ] = fdocs
35
41
36
42
def nested_func (** kwargs ):
@@ -47,7 +53,7 @@ def nested_func(**kwargs):
47
53
Json : json_input ,
48
54
Query : request .args .to_dict (),
49
55
Form : request .form .to_dict (),
50
- File : request .files .to_dict ()
56
+ File : request .files .to_dict (),
51
57
}
52
58
# Step 2 - Get expected input details as dict
53
59
expected_inputs = signature (f ).parameters
@@ -97,8 +103,7 @@ def validate(self, expected_input, all_request_inputs):
97
103
raise InvalidParameterTypeError (expected_delivery_type )
98
104
99
105
# Validate that user supplied input in expected delivery type (unless specified as Optional)
100
- user_input = all_request_inputs [expected_delivery_type .__class__ ].get (
101
- expected_name )
106
+ user_input = all_request_inputs [expected_delivery_type .__class__ ].get (expected_name )
102
107
if user_input is None :
103
108
# If default is given, set and continue
104
109
if expected_delivery_type .default is not None :
@@ -108,8 +113,7 @@ def validate(self, expected_input, all_request_inputs):
108
113
if hasattr (expected_input_type , "__args__" ) and type (None ) in expected_input_type .__args__ :
109
114
return user_input
110
115
else :
111
- raise MissingInputError (
112
- expected_name , expected_delivery_type .__class__ )
116
+ raise MissingInputError (expected_name , expected_delivery_type .__class__ )
113
117
114
118
# Skip validation if typing.Any is given
115
119
if expected_input_type_str .startswith ("typing.Any" ):
@@ -119,7 +123,6 @@ def validate(self, expected_input, all_request_inputs):
119
123
if expected_input_type_str .startswith ("typing.Optional" ):
120
124
new_type = expected_input_type .__args__ [0 ]
121
125
expected_input_type = new_type
122
- expected_input_type_str_str = str (new_type )
123
126
124
127
# Prepare expected type checks for unions, lists and plain types
125
128
if expected_input_type_str .startswith ("typing.Union" ):
@@ -149,14 +152,12 @@ def validate(self, expected_input, all_request_inputs):
149
152
# Perform automatic type conversion for parameter types (i.e. "true" -> True)
150
153
for count , value in enumerate (user_inputs ):
151
154
try :
152
- user_inputs [count ] = expected_delivery_type .convert (
153
- value , expected_input_types )
155
+ user_inputs [count ] = expected_delivery_type .convert (value , expected_input_types )
154
156
except ValueError as e :
155
157
raise ValidationError (str (e ), expected_name , expected_input_type )
156
158
157
159
# Validate that user type(s) match expected type(s)
158
- validation_success = all (
159
- type (inp ) in expected_input_types for inp in user_inputs )
160
+ validation_success = all (type (inp ) in expected_input_types for inp in user_inputs )
160
161
161
162
# Validate that if lists are required, lists are given
162
163
if expected_input_type_str .startswith ("typing.List" ):
@@ -165,12 +166,13 @@ def validate(self, expected_input, all_request_inputs):
165
166
166
167
# Error if types don't match
167
168
if not validation_success :
168
- if hasattr (original_expected_input_type , "__name__" ) and not original_expected_input_type_str .startswith ("typing." ):
169
+ if hasattr (original_expected_input_type , "__name__" ) and not original_expected_input_type_str .startswith (
170
+ "typing."
171
+ ):
169
172
type_name = original_expected_input_type .__name__
170
173
else :
171
174
type_name = original_expected_input_type_str
172
- raise ValidationError (
173
- f"must be type '{ type_name } '" , expected_name , original_expected_input_type )
175
+ raise ValidationError (f"must be type '{ type_name } '" , expected_name , original_expected_input_type )
174
176
175
177
# Validate parameter-specific requirements are met
176
178
try :
@@ -182,4 +184,3 @@ def validate(self, expected_input, all_request_inputs):
182
184
if len (user_inputs ) == 1 :
183
185
return user_inputs [0 ]
184
186
return user_inputs
185
-
0 commit comments