@@ -42,19 +42,6 @@ def sanitize_sensitive_data(data):
4242 return data
4343
4444
45- def _handle_json_response (response , method : str ):
46- """Parse JSON response and handle parsing errors."""
47- try :
48- data = response .json ()
49- logger .debug ("%s Data: %s" , method , data )
50- return response
51- except (json .JSONDecodeError , ValueError ) as json_ex :
52- error_msg = f"Server returned invalid JSON response. Status: { response .status_code } "
53- logger .error ("Response text: %s" , response .text [:500 ])
54- error_msg += f". Response preview: { response .text [:200 ]} "
55- raise ApiError (error_msg ) from json_ex
56-
57-
5845def _handle_http_error (ex : requests .exceptions .HTTPError ):
5946 """Extract error message from HTTP error response."""
6047 try :
@@ -66,6 +53,12 @@ def _handle_http_error(ex: requests.exceptions.HTTPError):
6653 return failure
6754
6855
56+ def _error_response (message : str ) -> None :
57+ """Display error to user and raise ApiError."""
58+ st .error (f"API Error: { message } " )
59+ raise ApiError (message )
60+
61+
6962def send_request (
7063 method : str ,
7164 endpoint : str ,
@@ -75,68 +68,65 @@ def send_request(
7568 retries : int = 3 ,
7669 backoff_factor : float = 2.0 ,
7770) -> dict :
78- """Send API requests with retry logic."""
71+ """Send API requests with retry logic. Returns JSON response or error dict."""
72+ method_map = {"GET" : requests .get , "POST" : requests .post , "PATCH" : requests .patch , "DELETE" : requests .delete }
73+ if method not in method_map :
74+ return _error_response (f"Unsupported HTTP method: { method } " )
75+
7976 url = urljoin (f"{ state .server ['url' ]} :{ state .server ['port' ]} /" , endpoint )
8077 payload = payload or {}
81- token = state .server ["key" ]
82- headers = {"Authorization" : f"Bearer { token } " }
83- # Send client in header if it exists
78+ headers = {"Authorization" : f"Bearer { state .server ['key' ]} " }
8479 if getattr (state , "client_settings" , {}).get ("client" ):
8580 headers ["Client" ] = state .client_settings ["client" ]
8681
87- method_map = {"GET" : requests .get , "POST" : requests .post , "PATCH" : requests .patch , "DELETE" : requests .delete }
88-
89- if method not in method_map :
90- raise ApiError (f"Unsupported HTTP method: { method } " )
91-
92- args = {
82+ args = {k : v for k , v in {
9383 "url" : url ,
9484 "headers" : headers ,
9585 "timeout" : timeout ,
9686 "params" : params ,
9787 "files" : payload .get ("files" ) if method == "POST" else None ,
9888 "json" : payload .get ("json" ) if method in ["POST" , "PATCH" ] else None ,
99- }
100- args = {k : v for k , v in args .items () if v is not None }
101- # Avoid logging out binary data in files
89+ }.items () if v is not None }
90+
10291 log_args = sanitize_sensitive_data (args .copy ())
10392 try :
10493 if log_args .get ("files" ):
10594 log_args ["files" ] = [(field_name , (f [0 ], "<binary_data>" , f [2 ])) for field_name , f in log_args ["files" ]]
10695 except (ValueError , IndexError ):
10796 pass
10897 logger .info ("%s Request: %s" , method , log_args )
98+
99+ result = None
109100 for attempt in range (retries + 1 ):
110101 try :
111102 response = method_map [method ](** args )
112103 logger .info ("%s Response: %s" , method , response )
113104 response .raise_for_status ()
114- return _handle_json_response (response , method )
105+ result = response .json ()
106+ logger .debug ("%s Data: %s" , method , result )
107+ break
115108
116109 except requests .exceptions .HTTPError as ex :
117110 logger .error ("HTTP Error: %s" , ex )
118- raise ApiError (_handle_http_error (ex )) from ex
111+ _error_response (_handle_http_error (ex ))
119112
120113 except requests .exceptions .ConnectionError as ex :
121114 logger .error ("Attempt %d: Connection Error: %s" , attempt + 1 , ex )
122115 if attempt < retries :
123- sleep_time = backoff_factor * (2 ** attempt )
124- logger .info ("Retrying in %.1f seconds..." , sleep_time )
125- time .sleep (sleep_time )
116+ time .sleep (backoff_factor * (2 ** attempt ))
126117 continue
127- raise ApiError (f"Connection failed after { retries + 1 } attempts: { str ( ex ) } " ) from ex
118+ _error_response (f"Connection failed after { retries + 1 } attempts" )
128119
129- except requests .exceptions .RequestException as ex :
130- logger .error ("Request Error: %s" , ex )
131- raise ApiError (f"Request failed: { str (ex )} " ) from ex
120+ except ( requests .exceptions .RequestException , json . JSONDecodeError , ValueError ) as ex :
121+ logger .error ("Request/JSON Error: %s" , ex )
122+ _error_response (f"Request failed: { str (ex )} " )
132123
133- raise ApiError ("An unexpected error occurred." )
124+ return result if result is not None else _error_response ("An unexpected error occurred." )
134125
135126
136- def get (endpoint : str , params : Optional [dict ] = None , retries : int = 3 , backoff_factor : float = 2.0 ) -> json :
127+ def get (endpoint : str , params : Optional [dict ] = None , retries : int = 3 , backoff_factor : float = 2.0 ) -> dict :
137128 """GET Requests"""
138- response = send_request ("GET" , endpoint , params = params , retries = retries , backoff_factor = backoff_factor )
139- return response .json ()
129+ return send_request ("GET" , endpoint , params = params , retries = retries , backoff_factor = backoff_factor )
140130
141131
142132def post (
@@ -146,9 +136,9 @@ def post(
146136 timeout : int = 60 ,
147137 retries : int = 5 ,
148138 backoff_factor : float = 1.5 ,
149- ) -> json :
139+ ) -> dict :
150140 """POST Requests"""
151- response = send_request (
141+ return send_request (
152142 "POST" ,
153143 endpoint ,
154144 params = params ,
@@ -157,7 +147,6 @@ def post(
157147 retries = retries ,
158148 backoff_factor = backoff_factor ,
159149 )
160- return response .json ()
161150
162151
163152def patch (
@@ -168,9 +157,9 @@ def patch(
168157 retries : int = 5 ,
169158 backoff_factor : float = 1.5 ,
170159 toast = True ,
171- ) -> None :
160+ ) -> dict :
172161 """PATCH Requests"""
173- response = send_request (
162+ result = send_request (
174163 "PATCH" ,
175164 endpoint ,
176165 params = params ,
@@ -182,13 +171,13 @@ def patch(
182171 if toast :
183172 st .toast ("Update Successful." , icon = "✅" )
184173 time .sleep (1 )
185- return response . json ()
174+ return result
186175
187176
188- def delete (endpoint : str , timeout : int = 60 , retries : int = 5 , backoff_factor : float = 1.5 , toast = True ) -> None :
177+ def delete (endpoint : str , timeout : int = 60 , retries : int = 5 , backoff_factor : float = 1.5 , toast = True ) -> dict :
189178 """DELETE Requests"""
190- response = send_request ("DELETE" , endpoint , timeout = timeout , retries = retries , backoff_factor = backoff_factor )
191- success = response .json ()["message" ]
179+ result = send_request ("DELETE" , endpoint , timeout = timeout , retries = retries , backoff_factor = backoff_factor )
192180 if toast :
193- st .toast (success , icon = "✅" )
181+ st .toast (result . get ( "message" , "Deleted." ) , icon = "✅" )
194182 time .sleep (1 )
183+ return result
0 commit comments