44
55import json
66import random
7- import urllib .parse
87from abc import ABC , abstractmethod
9- from typing import TYPE_CHECKING , Any , Dict , Optional
8+ from typing import Any , Dict , Optional
109
1110from meraki ._version import __version__
1211from meraki .common import (
3231 USE_ITERATOR_FOR_GET_PAGES ,
3332 WAIT_ON_RATE_LIMIT ,
3433)
34+ import httpx
35+
3536from meraki .exceptions import APIError , APIResponseError
3637from meraki .response_handler import handle_3xx
3738
38- if TYPE_CHECKING :
39- import httpx
40-
4139
4240class SessionBase (ABC ):
4341 """Abstract base class providing config storage, URL resolution, retry loop, and status dispatch.
@@ -118,9 +116,7 @@ def __init__(
118116 self ._parameters ["use_iterator_for_get_pages" ] = self ._use_iterator_for_get_pages
119117
120118 if self ._logger :
121- self ._logger .info (
122- f"Meraki dashboard API session initialized with these parameters: { self ._parameters } "
123- )
119+ self ._logger .info (f"Meraki dashboard API session initialized with these parameters: { self ._parameters } " )
124120
125121 # ------------------------------------------------------------------
126122 # Abstract methods (subclass contract)
@@ -145,9 +141,7 @@ def _transport_kwargs(self, kwargs: Dict[str, Any]) -> Dict[str, Any]:
145141 # Template method: request
146142 # ------------------------------------------------------------------
147143
148- def request (
149- self , metadata : Dict [str , Any ], method : str , url : str , ** kwargs : Any
150- ) -> Optional ["httpx.Response" ]:
144+ def request (self , metadata : Dict [str , Any ], method : str , url : str , ** kwargs : Any ) -> Optional ["httpx.Response" ]:
151145 """Execute an API request with retry loop and status dispatch.
152146
153147 Args:
@@ -185,7 +179,7 @@ def request(
185179 if self ._logger :
186180 self ._logger .info (f"{ method } { abs_url } " )
187181 response = self ._send_request (method , abs_url , ** kwargs )
188- except Exception as e :
182+ except httpx . HTTPError as e :
189183 if self ._logger :
190184 self ._logger .warning (f"{ tag } , { operation } - { e } , retrying in 1 second" )
191185 self ._sleep (1 )
@@ -261,9 +255,7 @@ def _handle_success(
261255 return response
262256 except (json .decoder .JSONDecodeError , ValueError ):
263257 if self ._logger :
264- self ._logger .warning (
265- f"{ tag } , { operation } - JSON decode error, retrying in 1 second"
266- )
258+ self ._logger .warning (f"{ tag } , { operation } - JSON decode error, retrying in 1 second" )
267259 return None
268260
269261 def _handle_redirect (self , response : "httpx.Response" ) -> str :
@@ -298,24 +290,18 @@ def _handle_rate_limit(
298290 )
299291
300292 if self ._logger :
301- self ._logger .warning (
302- f"{ tag } , { operation } - { status } { reason } , retrying in { wait } seconds"
303- )
293+ self ._logger .warning (f"{ tag } , { operation } - { status } { reason } , retrying in { wait } seconds" )
304294 return wait
305295
306- def _handle_server_error (
307- self , response : "httpx.Response" , metadata : Dict [str , Any ]
308- ) -> None :
296+ def _handle_server_error (self , response : "httpx.Response" , metadata : Dict [str , Any ]) -> None :
309297 """Handle 5xx server errors. Logs warning before retry."""
310298 tag = metadata ["tags" ][0 ]
311299 operation = metadata ["operation" ]
312300 reason = response .reason_phrase if hasattr (response , "reason_phrase" ) else ""
313301 status = response .status_code
314302
315303 if self ._logger :
316- self ._logger .warning (
317- f"{ tag } , { operation } - { status } { reason } , retrying in 1 second"
318- )
304+ self ._logger .warning (f"{ tag } , { operation } - { status } { reason } , retrying in 1 second" )
319305
320306 def _handle_client_error (
321307 self ,
@@ -381,9 +367,7 @@ def _retry_with_wait(
381367 status = response .status_code
382368
383369 if self ._logger :
384- self ._logger .warning (
385- f"{ tag } , { operation } - { status } { reason } , retrying in { wait } seconds"
386- )
370+ self ._logger .warning (f"{ tag } , { operation } - { status } { reason } , retrying in { wait } seconds" )
387371 self ._sleep (wait )
388372 retries -= 1
389373 if retries == 0 :
@@ -416,6 +400,5 @@ def _build_headers(self) -> Dict[str, str]:
416400 return {
417401 "Authorization" : "Bearer " + self ._api_key ,
418402 "Content-Type" : "application/json" ,
419- "User-Agent" : f"python-meraki/{ self ._version } "
420- + validate_user_agent (self ._be_geo_id , self ._caller ),
403+ "User-Agent" : f"python-meraki/{ self ._version } " + validate_user_agent (self ._be_geo_id , self ._caller ),
421404 }
0 commit comments