5
5
import json
6
6
import logging
7
7
import mimetypes
8
+ import time
8
9
import uuid
9
10
import warnings
10
11
from difflib import get_close_matches
@@ -139,7 +140,12 @@ class ChatGoogleGenerativeAIError(GoogleGenerativeAIError):
139
140
"""
140
141
141
142
142
- def _create_retry_decorator () -> Callable [[Any ], Any ]:
143
+ def _create_retry_decorator (
144
+ max_retries : int = 6 ,
145
+ wait_exponential_multiplier : float = 2.0 ,
146
+ wait_exponential_min : float = 1.0 ,
147
+ wait_exponential_max : float = 60.0 ,
148
+ ) -> Callable [[Any ], Any ]:
143
149
"""
144
150
Creates and returns a preconfigured tenacity retry decorator.
145
151
@@ -151,15 +157,14 @@ def _create_retry_decorator() -> Callable[[Any], Any]:
151
157
Callable[[Any], Any]: A retry decorator configured for handling specific
152
158
Google API exceptions.
153
159
"""
154
- multiplier = 2
155
- min_seconds = 1
156
- max_seconds = 60
157
- max_retries = 2
158
-
159
160
return retry (
160
161
reraise = True ,
161
162
stop = stop_after_attempt (max_retries ),
162
- wait = wait_exponential (multiplier = multiplier , min = min_seconds , max = max_seconds ),
163
+ wait = wait_exponential (
164
+ multiplier = wait_exponential_multiplier ,
165
+ min = wait_exponential_min ,
166
+ max = wait_exponential_max ,
167
+ ),
163
168
retry = (
164
169
retry_if_exception_type (google .api_core .exceptions .ResourceExhausted )
165
170
| retry_if_exception_type (google .api_core .exceptions .ServiceUnavailable )
@@ -184,13 +189,17 @@ def _chat_with_retry(generation_method: Callable, **kwargs: Any) -> Any:
184
189
Returns:
185
190
Any: The result from the chat generation method.
186
191
"""
187
- retry_decorator = _create_retry_decorator ()
192
+ retry_decorator = _create_retry_decorator (
193
+ max_retries = kwargs .get ("max_retries" , 6 ),
194
+ wait_exponential_multiplier = kwargs .get ("wait_exponential_multiplier" , 2.0 ),
195
+ wait_exponential_min = kwargs .get ("wait_exponential_min" , 1.0 ),
196
+ wait_exponential_max = kwargs .get ("wait_exponential_max" , 60.0 ),
197
+ )
188
198
189
199
@retry_decorator
190
200
def _chat_with_retry (** kwargs : Any ) -> Any :
191
201
try :
192
202
return generation_method (** kwargs )
193
- # Do not retry for these errors.
194
203
except google .api_core .exceptions .FailedPrecondition as exc :
195
204
if "location is not supported" in exc .message :
196
205
error_msg = (
@@ -204,6 +213,13 @@ def _chat_with_retry(**kwargs: Any) -> Any:
204
213
raise ChatGoogleGenerativeAIError (
205
214
f"Invalid argument provided to Gemini: { e } "
206
215
) from e
216
+ except google .api_core .exceptions .ResourceExhausted as e :
217
+ # Handle quota-exceeded error with recommended retry delay
218
+ if hasattr (e , "retry_after" ) and e .retry_after < kwargs .get (
219
+ "wait_exponential_max" , 60.0
220
+ ):
221
+ time .sleep (e .retry_after )
222
+ raise e
207
223
except Exception as e :
208
224
raise e
209
225
0 commit comments