feat(api-client): implement session management for AdvowareAPI and EspoCRMAPI
This commit is contained in:
@@ -73,6 +73,17 @@ class AdvowareAPI:
|
||||
|
||||
self.logger.info("AdvowareAPI initialized")
|
||||
|
||||
self._session: Optional[aiohttp.ClientSession] = None
|
||||
|
||||
async def _get_session(self) -> aiohttp.ClientSession:
|
||||
if self._session is None or self._session.closed:
|
||||
self._session = aiohttp.ClientSession()
|
||||
return self._session
|
||||
|
||||
async def close(self) -> None:
|
||||
if self._session and not self._session.closed:
|
||||
await self._session.close()
|
||||
|
||||
def _generate_hmac(self, request_time_stamp: str, nonce: Optional[str] = None) -> str:
|
||||
"""Generate HMAC-SHA512 signature for authentication"""
|
||||
if not nonce:
|
||||
@@ -260,7 +271,7 @@ class AdvowareAPI:
|
||||
# Use 'data' parameter if provided, otherwise 'json_data'
|
||||
json_payload = data if data is not None else json_data
|
||||
|
||||
async with aiohttp.ClientSession(timeout=effective_timeout) as session:
|
||||
session = await self._get_session()
|
||||
try:
|
||||
with self.logger.api_call(endpoint, method):
|
||||
async with session.request(
|
||||
@@ -268,7 +279,8 @@ class AdvowareAPI:
|
||||
url,
|
||||
headers=effective_headers,
|
||||
params=params,
|
||||
json=json_payload
|
||||
json=json_payload,
|
||||
timeout=effective_timeout
|
||||
) as response:
|
||||
# Handle 401 - retry with fresh token
|
||||
if response.status == 401:
|
||||
@@ -281,7 +293,8 @@ class AdvowareAPI:
|
||||
url,
|
||||
headers=effective_headers,
|
||||
params=params,
|
||||
json=json_payload
|
||||
json=json_payload,
|
||||
timeout=effective_timeout
|
||||
) as retry_response:
|
||||
if retry_response.status == 401:
|
||||
raise AdvowareAuthError(
|
||||
|
||||
@@ -55,6 +55,8 @@ class EspoCRMAPI:
|
||||
|
||||
self.logger.info(f"EspoCRM API initialized with base URL: {self.api_base_url}")
|
||||
|
||||
self._session: Optional[aiohttp.ClientSession] = None
|
||||
|
||||
# Optional Redis for caching/rate limiting (centralized)
|
||||
self.redis_client = get_redis_client(strict=False)
|
||||
if self.redis_client:
|
||||
@@ -70,6 +72,15 @@ class EspoCRMAPI:
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
async def _get_session(self) -> aiohttp.ClientSession:
|
||||
if self._session is None or self._session.closed:
|
||||
self._session = aiohttp.ClientSession()
|
||||
return self._session
|
||||
|
||||
async def close(self) -> None:
|
||||
if self._session and not self._session.closed:
|
||||
await self._session.close()
|
||||
|
||||
async def api_call(
|
||||
self,
|
||||
endpoint: str,
|
||||
@@ -106,7 +117,7 @@ class EspoCRMAPI:
|
||||
total=timeout_seconds or self.api_timeout_seconds
|
||||
)
|
||||
|
||||
async with aiohttp.ClientSession(timeout=effective_timeout) as session:
|
||||
session = await self._get_session()
|
||||
try:
|
||||
with self.logger.api_call(endpoint, method):
|
||||
async with session.request(
|
||||
@@ -114,7 +125,8 @@ class EspoCRMAPI:
|
||||
url,
|
||||
headers=headers,
|
||||
params=params,
|
||||
json=json_data
|
||||
json=json_data,
|
||||
timeout=effective_timeout
|
||||
) as response:
|
||||
# Handle errors
|
||||
if response.status == 401:
|
||||
@@ -340,9 +352,9 @@ class EspoCRMAPI:
|
||||
|
||||
effective_timeout = aiohttp.ClientTimeout(total=self.api_timeout_seconds)
|
||||
|
||||
async with aiohttp.ClientSession(timeout=effective_timeout) as session:
|
||||
session = await self._get_session()
|
||||
try:
|
||||
async with session.post(url, headers=headers, data=form_data) as response:
|
||||
async with session.post(url, headers=headers, data=form_data, timeout=effective_timeout) as response:
|
||||
self._log(f"Upload response status: {response.status}")
|
||||
|
||||
if response.status == 401:
|
||||
@@ -390,9 +402,9 @@ class EspoCRMAPI:
|
||||
|
||||
effective_timeout = aiohttp.ClientTimeout(total=self.api_timeout_seconds)
|
||||
|
||||
async with aiohttp.ClientSession(timeout=effective_timeout) as session:
|
||||
session = await self._get_session()
|
||||
try:
|
||||
async with session.get(url, headers=headers) as response:
|
||||
async with session.get(url, headers=headers, timeout=effective_timeout) as response:
|
||||
if response.status == 401:
|
||||
raise EspoCRMAuthError("Authentication failed - check API key")
|
||||
elif response.status == 403:
|
||||
|
||||
Reference in New Issue
Block a user