Coverage for webapp / endpoints / models.py: 94%
137 statements
« prev ^ index » next coverage.py v7.13.1, created at 2025-12-29 22:06 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2025-12-29 22:06 +0000
1# Packages
2import flask
3from flask import make_response
4from canonicalwebteam.exceptions import (
5 StoreApiResponseErrorList,
6 StoreApiResourceNotFound,
7)
8from canonicalwebteam.store_api.publishergw import PublisherGW
10# Local
11from webapp.decorators import login_required, exchange_required
12from webapp.helpers import api_publisher_session, get_brand_id
15publisher_gateway = PublisherGW("snap", api_publisher_session)
17models = flask.Blueprint(
18 "models",
19 __name__,
20)
23@models.route("/api/store/<store_id>/models")
24@login_required
25@exchange_required
26def get_models(store_id: str):
27 """
28 Retrieves models associated with a given store ID.
30 Args:
31 store_id (int): The ID of the store for which to retrieve models.
33 Returns:
34 dict: A dictionary containing the response message, success status,
35 and data.
36 """
38 res = {}
39 try:
40 models = publisher_gateway.get_store_models(flask.session, store_id)
41 res["success"] = True
42 res["data"] = models
43 response = make_response(res, 200)
44 response.cache_control.max_age = "3600"
45 except StoreApiResponseErrorList as error_list:
46 error_messages = [
47 f"{error.get('message', 'An error occurred')}"
48 for error in error_list.errors
49 ]
50 if "unauthorized" in error_messages:
51 res["message"] = "Store not found"
52 else:
53 res["message"] = " ".join(error_messages)
54 res["success"] = False
55 response = make_response(res, 500)
57 return response
60@models.route("/api/store/<store_id>/models/<model_name>/policies")
61@login_required
62@exchange_required
63def get_policies(store_id: str, model_name: str):
64 """
65 Get the policies for a given store model.
67 Args:
68 store_id (str): The ID of the store.
69 model_name (str): The name of the model.
71 Returns:
72 dict: A dictionary containing the response message and success
73 """
74 brand_id = get_brand_id(flask.session, store_id)
75 res = {}
77 try:
78 policies = publisher_gateway.get_store_model_policies(
79 flask.session, brand_id, model_name
80 )
81 res["success"] = True
82 res["data"] = policies
83 response = make_response(res, 200)
84 response.cache_control.max_age = "3600"
85 return response
86 except StoreApiResponseErrorList as error_list:
87 res["success"] = False
88 res["message"] = " ".join(
89 [
90 f"{error.get('message', 'An error occurred')}"
91 for error in error_list.errors
92 ]
93 )
94 except Exception:
95 res["success"] = False
96 res["message"] = "An error occurred"
98 return make_response(res, 500)
101@models.route(
102 "/api/store/<store_id>/models/<model_name>/policies", methods=["POST"]
103)
104@login_required
105@exchange_required
106def create_policy(store_id: str, model_name: str):
107 """
108 Creat policy for a store model.
110 Args:
111 store_id (str): The ID of the store.
112 model_name (str): The name of the model.
114 Returns:
115 dict: A dictionary containing the response message and success
116 """
117 signing_key = flask.request.form.get("signing_key")
118 res = {}
119 try:
120 signing_keys_data = publisher_gateway.get_store_signing_keys(
121 flask.session, store_id
122 )
123 signing_keys = [key["sha3-384"] for key in signing_keys_data]
125 if not signing_key:
126 res["message"] = "Signing key required"
127 res["success"] = False
128 return make_response(res, 500)
130 if signing_key in signing_keys:
131 publisher_gateway.create_store_model_policy(
132 flask.session, store_id, model_name, signing_key
133 )
134 res["success"] = True
135 else:
136 res["message"] = "Invalid signing key"
137 res["success"] = False
138 except StoreApiResponseErrorList as error_list:
139 res["success"] = False
140 res["message"] = error_list.errors[0]["message"]
142 if res["success"]:
143 return make_response(res, 200)
144 return make_response(res, 500)
147@models.route(
148 "/api/store/<store_id>/models/<model_name>/policies/<revision>",
149 methods=["DELETE"],
150)
151@login_required
152@exchange_required
153def delete_policy(store_id: str, model_name: str, revision: str):
154 res = {}
155 try:
156 response = publisher_gateway.delete_store_model_policy(
157 flask.session, store_id, model_name, revision
158 )
159 if response.status_code == 204:
160 res = {"success": True}
161 return make_response(res, 200)
162 elif response.status_code == 404:
163 res = {"success": False, "message": "Policy not found"}
164 return make_response(res, 404)
165 except StoreApiResponseErrorList as error_list:
166 res["success"] = False
167 res["message"] = error_list.errors[0]["message"]
168 return make_response(res, 500)
171@models.route("/api/store/<store_id>/models", methods=["POST"])
172@login_required
173@exchange_required
174def create_models(store_id: str):
175 """
176 Create a model for a given store.
178 Args:
179 store_id (str): The ID of the store.
181 Returns:
182 dict: A dictionary containing the response message and success
183 status.
184 """
186 # TO DO: Addn validation that name does not exist already
188 res = {}
190 try:
191 name = flask.request.form.get("name")
192 api_key = flask.request.form.get("api_key", "")
194 if len(name) > 128:
195 res["message"] = "Name is too long. Limit 128 characters"
196 res["success"] = False
197 return make_response(res, 500)
199 if api_key and len(api_key) != 50 and not api_key.isalpha():
200 res["message"] = "Invalid API key"
201 res["success"] = False
202 return make_response(res, 500)
204 publisher_gateway.create_store_model(
205 flask.session, store_id, name, api_key
206 )
208 res["success"] = True
209 return make_response(res, 201)
210 except StoreApiResponseErrorList as error_list:
211 res["success"] = False
212 messages = [
213 f"{error.get('message', 'An error occurred')}"
214 for error in error_list.errors
215 ]
216 res["message"] = (" ").join(messages)
218 except Exception:
219 res["success"] = False
220 res["message"] = "An error occurred"
222 return make_response(res, 500)
225@models.route("/api/store/<store_id>/models/<model_name>", methods=["PATCH"])
226@login_required
227@exchange_required
228def update_model(store_id: str, model_name: str):
229 """
230 Update a model for a given store.
232 Args:
233 store_id (str): The ID of the store.
234 model_name (str): The name of the model.
236 Returns:
237 dict: A dictionary containing the response message and success
238 status.
239 """
240 res = {}
242 try:
243 api_key = flask.request.form.get("api_key", "")
245 if len(api_key) != 50 and not api_key.isalpha():
246 res["message"] = "Invalid API key"
247 res["success"] = False
248 return make_response(res, 500)
250 publisher_gateway.update_store_model(
251 flask.session, store_id, model_name, api_key
252 )
253 res["success"] = True
255 except StoreApiResponseErrorList as error_list:
256 res["success"] = False
257 res["message"] = error_list.errors[0]["message"]
259 except StoreApiResourceNotFound:
260 res["success"] = False
261 res["message"] = "Model not found"
262 if res["success"]:
263 return make_response(res, 200)
264 return make_response(res, 500)