@@ -15,18 +15,18 @@ class StaxClient:
1515 _schema = dict ()
1616 _initialized = False
1717
18- def __init__ (self , classname , lambda_client = None ):
18+ def __init__ (self , classname , lambda_client = None , force = False ):
1919 # 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 ()
2322 self ._map_paths_to_operations ()
2423 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
3030
3131 if lambda_client :
3232 self .lambda_client = lambda_client
@@ -35,6 +35,7 @@ def __init__(self, classname, lambda_client=None):
3535 else :
3636 Config .auth_class = ApiTokenAuth
3737 self ._admin = False
38+ self ._initialized = True
3839
3940 @classmethod
4041 def _load_schema (cls ):
@@ -53,14 +54,10 @@ def _map_paths_to_operations(cls):
5354 cls ._load_schema ()
5455 for path_name , path in cls ._schema ["paths" ].items ():
5556 parameters = []
56- base_path = ""
57- path_parts = path_name .split ("/" )
5857
59- for part in path_parts :
58+ for part in path_name . split ( "/" ) :
6059 if "{" in part :
6160 parameters .append (part .replace ("{" , "" ).replace ("}" , "" ))
62- else :
63- base_path = f"{ base_path } /{ part } "
6461
6562 for method_type , method in path .items ():
6663 method = path [method_type ]
@@ -69,19 +66,20 @@ def _map_paths_to_operations(cls):
6966 if len (operation ) != 2 :
7067 continue
7168
69+ parameter_path = {
70+ "path" : path_name ,
71+ "method" : method_type ,
72+ "parameters" : parameters ,
73+ }
74+
7275 api_class = operation [0 ]
7376 method_name = operation [1 ]
74-
7577 if not cls ._operation_map .get (api_class ):
7678 cls ._operation_map [api_class ] = dict ()
7779 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 )
8583
8684 def __getattr__ (self , name ):
8785 self .name = name
@@ -94,33 +92,40 @@ def stax_wrapper(*args, **kwargs):
9492 f"No such operation: { self .name } for { self .classname } . Please use one of { list (self ._operation_map [self .classname ])} "
9593 )
9694 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" ]),
10199 )
100+ # All parameters starting with the most dependant
101+ operation_parameters = [
102+ parameter_path ["parameters" ]
103+ for parameter_path in sorted_parameter_paths
104+ ]
102105 # Sort the operation map parameters
103- sorted_operation_parameters = sorted (
104- operation_parameters , key = len , reverse = True
105- )
106-
106+ parameter_index = - 1
107107 # 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 )) :
109109 # 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 :
114113 raise ValidationException (
115- f"Missing one or more parameters: { sorted_operation_parameters [- 1 ]} "
114+ f"Missing one or more parameters: { operation_parameters [- 1 ]} "
116115 )
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" ]:
119126 # We only validate the payload for POST/PUT routes
120127 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 )
124129 return ret
125130
126131 return stax_wrapper
0 commit comments