Skip to content

Commit 8db338d

Browse files
authored
Merge pull request #49 from stax-labs/refactor/networking-fixes
refactor(sdk)
2 parents 94ec5a2 + dace640 commit 8db338d

File tree

2 files changed

+47
-42
lines changed

2 files changed

+47
-42
lines changed

staxapp/openapi.py

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -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

tests/test_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def testLoadOldSchema(self):
4949
"""
5050
self.Config = Config
5151
self.Config.load_live_schema = False
52-
client = StaxClient("accounts")
52+
client = StaxClient("accounts", force=True)
5353
self.assertTrue(client._initialized)
5454

5555
@responses.activate

0 commit comments

Comments
 (0)