| import asyncio
|
| import functools
|
| import inspect
|
| from collections.abc import Callable
|
|
|
| from ..exceptions import APIError
|
|
|
| DELAY_FACTOR = 5
|
|
|
|
|
| def running(retry: int = 0) -> Callable:
|
| """
|
| Decorator to check if GeminiClient is running before making a request.
|
| Supports both regular async functions and async generators.
|
|
|
| Parameters
|
| ----------
|
| retry: `int`, optional
|
| Max number of retries when `gemini_webapi.APIError` is raised.
|
| """
|
|
|
| def decorator(func):
|
| if inspect.isasyncgenfunction(func):
|
|
|
| @functools.wraps(func)
|
| async def wrapper(client, *args, current_retry=None, **kwargs):
|
| if current_retry is None:
|
| current_retry = retry
|
|
|
| try:
|
| if not client._running:
|
| await client.init(
|
| timeout=client.timeout,
|
| auto_close=client.auto_close,
|
| close_delay=client.close_delay,
|
| auto_refresh=client.auto_refresh,
|
| refresh_interval=client.refresh_interval,
|
| verbose=client.verbose,
|
| watchdog_timeout=client.watchdog_timeout,
|
| )
|
|
|
| if not client._running:
|
| raise APIError(
|
| f"Invalid function call: GeminiClient.{func.__name__}. Client initialization failed."
|
| )
|
|
|
| async for item in func(client, *args, **kwargs):
|
| yield item
|
| except APIError:
|
| if current_retry > 0:
|
| delay = (retry - current_retry + 1) * DELAY_FACTOR
|
| await asyncio.sleep(delay)
|
| async for item in wrapper(
|
| client, *args, current_retry=current_retry - 1, **kwargs
|
| ):
|
| yield item
|
| else:
|
| raise
|
|
|
| return wrapper
|
| else:
|
|
|
| @functools.wraps(func)
|
| async def wrapper(client, *args, current_retry=None, **kwargs):
|
| if current_retry is None:
|
| current_retry = retry
|
|
|
| try:
|
| if not client._running:
|
| await client.init(
|
| timeout=client.timeout,
|
| auto_close=client.auto_close,
|
| close_delay=client.close_delay,
|
| auto_refresh=client.auto_refresh,
|
| refresh_interval=client.refresh_interval,
|
| verbose=client.verbose,
|
| watchdog_timeout=client.watchdog_timeout,
|
| )
|
|
|
| if not client._running:
|
| raise APIError(
|
| f"Invalid function call: GeminiClient.{func.__name__}. Client initialization failed."
|
| )
|
|
|
| return await func(client, *args, **kwargs)
|
| except APIError:
|
| if current_retry > 0:
|
| delay = (retry - current_retry + 1) * DELAY_FACTOR
|
| await asyncio.sleep(delay)
|
|
|
| return await wrapper(
|
| client, *args, current_retry=current_retry - 1, **kwargs
|
| )
|
|
|
| raise
|
|
|
| return wrapper
|
|
|
| return decorator
|
|
|