Kyle Carow
Kyle Carow

Reputation: 194

Python3 retrying with tenacity (w/out decorators) gives error claiming "missing arguments" when using gspread

I'm trying to use the tenacity module to avoid frequent requesting errors (APIErrors) 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.

Upvotes: 1

Views: 2609

Answers (1)

Parvathirajan Natarajan
Parvathirajan Natarajan

Reputation: 1305

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'
>>>   

Upvotes: 2

Related Questions