@@ -15,18 +15,18 @@ class StaxClient:
15
15
_schema = dict ()
16
16
_initialized = False
17
17
18
- def __init__ (self , classname , lambda_client = None ):
18
+ def __init__ (self , classname , lambda_client = None , force = False ):
19
19
# Stax feature, eg 'quotas', 'workloads'
20
- self .classname = classname
21
-
22
- if not self ._initialized :
20
+ if force or not self ._operation_map :
21
+ _operation_map = dict ()
23
22
self ._map_paths_to_operations ()
24
23
StaxContract .set_schema (self ._schema )
25
- if not self ._operation_map .get (self .classname ):
26
- raise ValidationException (
27
- f"No such class: { self .classname } . Please use one of { list (self ._operation_map )} "
28
- )
29
- self ._initialized = True
24
+
25
+ if not self ._operation_map .get (classname ):
26
+ raise ValidationException (
27
+ f"No such class: { classname } . Please use one of { list (self ._operation_map )} "
28
+ )
29
+ self .classname = classname
30
30
31
31
if lambda_client :
32
32
self .lambda_client = lambda_client
@@ -35,6 +35,7 @@ def __init__(self, classname, lambda_client=None):
35
35
else :
36
36
Config .auth_class = ApiTokenAuth
37
37
self ._admin = False
38
+ self ._initialized = True
38
39
39
40
@classmethod
40
41
def _load_schema (cls ):
@@ -53,14 +54,10 @@ def _map_paths_to_operations(cls):
53
54
cls ._load_schema ()
54
55
for path_name , path in cls ._schema ["paths" ].items ():
55
56
parameters = []
56
- base_path = ""
57
- path_parts = path_name .split ("/" )
58
57
59
- for part in path_parts :
58
+ for part in path_name . split ( "/" ) :
60
59
if "{" in part :
61
60
parameters .append (part .replace ("{" , "" ).replace ("}" , "" ))
62
- else :
63
- base_path = f"{ base_path } /{ part } "
64
61
65
62
for method_type , method in path .items ():
66
63
method = path [method_type ]
@@ -69,19 +66,20 @@ def _map_paths_to_operations(cls):
69
66
if len (operation ) != 2 :
70
67
continue
71
68
69
+ parameter_path = {
70
+ "path" : path_name ,
71
+ "method" : method_type ,
72
+ "parameters" : parameters ,
73
+ }
74
+
72
75
api_class = operation [0 ]
73
76
method_name = operation [1 ]
74
-
75
77
if not cls ._operation_map .get (api_class ):
76
78
cls ._operation_map [api_class ] = dict ()
77
79
if not cls ._operation_map .get (api_class , {}).get (method_name ):
78
- cls ._operation_map [api_class ][method_name ] = dict ()
79
- cls ._operation_map [api_class ][method_name ]["path" ] = base_path
80
- cls ._operation_map [api_class ][method_name ]["method" ] = method_type
81
- cls ._operation_map [api_class ][method_name ]["parameters" ] = []
82
- cls ._operation_map [api_class ][method_name ]["parameters" ].append (
83
- parameters
84
- )
80
+ cls ._operation_map [api_class ][method_name ] = []
81
+
82
+ cls ._operation_map [api_class ][method_name ].append (parameter_path )
85
83
86
84
def __getattr__ (self , name ):
87
85
self .name = name
@@ -94,33 +92,40 @@ def stax_wrapper(*args, **kwargs):
94
92
f"No such operation: { self .name } for { self .classname } . Please use one of { list (self ._operation_map [self .classname ])} "
95
93
)
96
94
payload = {** kwargs }
97
- parameters = ""
98
- # All parameters starting with the most dependant
99
- operation_parameters = self ._operation_map [self .classname ][self .name ]. get (
100
- "parameters" , []
95
+
96
+ sorted_parameter_paths = sorted (
97
+ self ._operation_map [self .classname ][self .name ],
98
+ key = lambda x : len ( x [ "parameters" ]),
101
99
)
100
+ # All parameters starting with the most dependant
101
+ operation_parameters = [
102
+ parameter_path ["parameters" ]
103
+ for parameter_path in sorted_parameter_paths
104
+ ]
102
105
# Sort the operation map parameters
103
- sorted_operation_parameters = sorted (
104
- operation_parameters , key = len , reverse = True
105
- )
106
-
106
+ parameter_index = - 1
107
107
# Check if the any of the parameter schemas match parameters provided
108
- for parameter_list in sorted_operation_parameters :
108
+ for index in range ( 0 , len ( operation_parameters )) :
109
109
# Get any parameters from the keyword args and remove them from the payload
110
- if set (parameter_list ).issubset (payload .keys ()):
111
- for parameter in parameter_list :
112
- parameters = f"{ parameters } /{ payload .pop (parameter , None )} "
113
- if parameters .count ("/" ) < len (sorted_operation_parameters [- 1 ]):
110
+ if set (operation_parameters [index ]).issubset (payload .keys ()):
111
+ parameter_index = index
112
+ if parameter_index == - 1 :
114
113
raise ValidationException (
115
- f"Missing one or more parameters: { sorted_operation_parameters [- 1 ]} "
114
+ f"Missing one or more parameters: { operation_parameters [- 1 ]} "
116
115
)
117
-
118
- if method ["method" ].lower () in ["put" , "post" ]:
116
+ paramter_path = sorted_parameter_paths [parameter_index ]
117
+ split_path = paramter_path ["path" ].split ("/" )
118
+ path = ""
119
+ for part in split_path :
120
+ if "{" in part :
121
+ parameter = part .replace ("{" , "" ).replace ("}" , "" )
122
+ path = f"{ path } /{ payload .pop (parameter )} "
123
+ else :
124
+ path = f"{ path } /{ part } "
125
+ if paramter_path ["method" ].lower () in ["put" , "post" ]:
119
126
# We only validate the payload for POST/PUT routes
120
127
StaxContract .validate (payload , method_name )
121
- ret = getattr (Api , method ["method" ])(
122
- f'{ method ["path" ]} { parameters } ' , payload
123
- )
128
+ ret = getattr (Api , paramter_path ["method" ])(path , payload )
124
129
return ret
125
130
126
131
return stax_wrapper
0 commit comments