I'm trying to use the tenacity module to avoid frequent requesting errors (APIError
s) from gspread. I understand the common examples of tenacity use decorators, but I want to use tenacity's Retrying()
function so I can have it retry gspread's spreadsheet cell updating method sheet.update_acell()
instead.
For some reason, using a retry with the sheet.update_acell()
doesn't actually 'give' the arguments to the function (or something). A contrived multiple argument example works perfectly however.
My code (except for imports and google API credential stuff):
# gspread authorization
gs_client = gspread.authorize(creds)
workbook = gs_client.open_by_key(sheet_key)
sheet = workbook.sheet1
ret = tenacity.Retrying(stop=tenacity.stop_after_attempt(30),
wait=tenacity.wait_exponential(multiplier=0.5, max=60))
# contrived example
def retry_example(arg0, arg1):
print(arg0, arg1)
ret.call(retry_example,'foo','bar') #works perfectly
# gspread example
ret.call(sheet.update_acell(),'A1',1) #doesn't work, the arguments aren't found
Output:
foo bar
Traceback (most recent call last):
File "c:/Users/.../tenacitytest.py", line 28, in <module>
ret.call(sheet.update_acell(),'A1',1)
TypeError: update_acell() missing 2 required positional arguments: 'label' and 'value'
Running the gspread stuff without tenacity works as it should, so I'm sure that I'm calling update_acell()
correctly.
I feel like this may have to do with the fact that gspread's update_acell()
is a method, unlike example_func()
?
Any help would be appreciated.
You should not use the parenthesis in the Retrying call. You should pass parameters like below
Hope this will work ;)
ret.call(sheet.update_acell,'A1',1)
Example:
from tenacity import Retrying, stop_after_attempt
def foo(arg1, arg2):
print('Arguments are: {} {}'.format(arg1, arg2))
raise Exception('Throwing Exception')
def bar(max_attempts=3):
retryer = Retrying(stop=stop_after_attempt(max_attempts), reraise=True)
retryer(foo, 'my arg1', 'my arg2')
Let's try the Error Scenario:
>>> from tenacity import Retrying, stop_after_attempt
>>>
>>> def foo(arg1, arg2):
... print('Arguments are: {} {}'.format(arg1, arg2))
... raise Exception('Throwing Exception')
...
>>> def bar(max_attempts=3):
... retryer = Retrying(stop=stop_after_attempt(max_attempts), reraise=True)
... retryer(foo(), 'my arg1', 'my arg2')
...
>>> bar()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in bar
TypeError: foo() missing 2 required positional arguments: 'arg1' and 'arg2'
>>>