Реализация таймаута в APIPython

Программы на Python
Ответить
Anonymous
 Реализация таймаута в API

Сообщение Anonymous »

У меня есть функция, которую я использую для выполнения вызовов API в своей базе кода, но я не могу заставить работать часть тайм-аута. Все остальное в порядке, но тайм-аут просто не работает, он просто зацикливается, а затем через некоторое время останавливается. Я предполагаю, что где-то есть ошибка по умолчанию. Любые указания на то, где я напутал с реализацией тайм-аута.
async def services():
global session6

connector = aiohttp.TCPConnector(
limit=50, # Maximum number of simultaneous connections
ttl_dns_cache=300, # DNS cache time-to-live in seconds
force_close=False, # Whether to force close connections on release
enable_cleanup_closed=True, # Whether to enable cleanup of closed connections
keepalive_timeout=20

)

if session6 is None:
logger.debug(' Generating New Session',extra={'traceId': uuid.uuid4(),'resource':resource,'spanId':uuid.uuid4(),'event_timestamp':time.time_ns()})
connector = aiohttp.TCPConnector()
session6 = aiohttp.ClientSession(connector=connector)

return session6

async def api_request(trace_id, url, метод, retry_limit=3, timeout=2, интервал=2, протокол='https', **kwargs):
"" "
Выполните вызов API, используя aiohttp с повторными попытками и указанными параметрами.
:param trace_id: Unique identifier for the trace.
:param url: The API endpoint URL.
:param method: The HTTP method (GET, POST, PUT, DELETE).
:param retry_limit: Number of retry attempts.
:param timeout: Timeout for each API call in seconds.
:param interval: Interval between retries in seconds.
:param protocol: The default Protocol to use if not provided (http or https).
:param kwargs: Additional arguments to pass to the request (e.g., headers, data, json).
:return: A dictionary containing status_code and response_data.
"""
try:

# Ensure the URL starts with http or https
if not url.startswith(('http://', 'https://')):
url = f'{protocol}://' + url

async def fetch(session, url, method, timeout, **kwargs):
try:
if method.upper() == 'GET':
async with session.get(url, timeout=ClientTimeout(total=timeout), **kwargs) as response:
response_data = await response.json()
return {'status_code': response.status, 'response_data': response_data}
elif method.upper() == 'POST':
async with session.post(url, timeout=ClientTimeout(total=timeout), **kwargs) as response:
response_data = await response.json()
return {'status_code': response.status, 'response_data': response_data}
elif method.upper() == 'PUT':
async with session.put(url, timeout=ClientTimeout(total=timeout), **kwargs) as response:
response_data = await response.json()
return {'status_code': response.status, 'response_data': response_data}
elif method.upper() == 'DELETE':
async with session.delete(url, timeout=ClientTimeout(total=timeout), **kwargs) as response:
response_data = await response.json()
return {'status_code': response.status, 'response_data': response_data}
else:
raise ValueError(f"Unsupported HTTP method: {method}")
except aiohttp.ClientError as e:
logger.info(
f'Client error: {e}',
extra={'traceId': trace_id, 'resource':resource,'spanId': trace_id, 'event_timestamp': time.time_ns()}
)
raise
except asyncio.TimeoutError:
logger.error("Request timed out", extra={'traceId': trace_id})
logger.info(
'Request timed out',
extra={'traceId': trace_id, 'resource':resource,'spanId': trace_id, 'event_timestamp': time.time_ns()}
)
raise

for attempt in range(retry_limit):
try:
session = await services()
logger.info(
f'API Request ====> url={url} || method={method} || Retry Attempt={attempt} || Retry Limit={retry_limit} || Timeout={timeout} || Retry Interval={interval} || Request Details={kwargs}',
extra={'traceId': trace_id, 'resource':resource,'spanId': trace_id, 'event_timestamp': time.time_ns()}
)
response = await fetch(session, url, method, timeout, **kwargs)
logger.info(
f'API Response ====> url={url} || method={method} || Retry Attempt={attempt} || Retry Limit={retry_limit} || Timeout={timeout} || Retry Interval={interval} || Response Details={response}',
extra={'traceId': trace_id, 'resource':resource, 'spanId': trace_id, 'event_timestamp': time.time_ns()}
)
return response
except (aiohttp.ClientError, asyncio.TimeoutError) as e:
if attempt < retry_limit - 1:
logger.info(
f'Retrying in {interval} seconds... (Attempt {attempt + 1} of {retry_limit})',
extra={'traceId': trace_id, 'resource':resource, 'spanId': trace_id, 'event_timestamp': time.time_ns()}
)
await asyncio.sleep(interval)
else:
logger.info(
'Exceeded retry limit.',
extra={'traceId': trace_id, 'resource':resource, 'spanId': trace_id, 'event_timestamp': time.time_ns()}
)
raise ApiResponse(f"API Request Limit Exhausted for url={url}", trace_id, 5002 , [{"field": url,
"error_message":kwargs}])

except Exception as e:
print(type(e).__name__, __file__, e.__traceback__.tb_lineno ,e.args)
logger.critical(f'Error during ECS HTTP get request- {type(e).__name__, __file__, e.__traceback__.tb_lineno ,e.args}',extra={'traceId': trace_id,'resource':'resource','spanId':trace_id,'event_timestamp':time.time_ns()})
return {"status_code": 500,"response_data": f"connection_error to {url}","message": str(e)}


Подробнее здесь: https://stackoverflow.com/questions/792 ... ut-in-apis
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»