I am writing a wrapper for a Rest API I interact with day to day. When you make a request for something which has many results, it paginates them. I was trying to write a function to elegantly de-paginate data and ran into something unexpected -- if I try to re-use this function in the same application or IPython session, it will stack the results of the second request on top of the results of the first request. Here is the code:
class RestAPIWrapper(object):
def __init__(self, url=url, acct=acct, token=token):
self.url = url
self._session = requests.Session()
self._session.mount('https://', HTTPAdapter(max_retries=5))
self._session.headers.update({'Accept': 'application/json', 'Content-Type': 'application/json'})
self._session.auth = (acct, token)
def search_api_broken(self, query, page=1, results=[]):
r = self._session.get('{0}/search.json?page={1}&query={2}'.format(self.url, page, query))
response = r.json()
results.extend(response['results'])
#returns a dictionary that has these keys: ['results', 'next_page', 'previous_page']
if response['next_page'] is not None:
results = self.search_api_broken(query, page=page+1, results=results)
return results
def search_api_works(self, query, page=1, results=[]):
if page == 1:
results = []
r = self._session.get('{0}/search.json?page={1}&query={2}&sort_by={3}&sort_order={4}'.format(self.base_url, page, quote(query), sort_by, sort_order))
response = r.json()
results.extend(response['results'])
#returns a dictionary that has these keys: ['results', 'next_page', 'previous_page']
if response['next_page'] is not None:
results = self.search_api_wroks(query, page=page+1, results=results)
return results
In other words, if I call the method like this:
my_api_wrapper = RestAPIWrapper()
#query should return 320 results, #query2 should return 140 results
data = my_api_wrapper.search_api_broken(query)
len(data)
#outputs 320
more_data = my_api_wrapper.search_api_broken(query2)
len(more_data)
#outputs 460
The output on the second method includes the first. Why does it do this since I put results = []
in the function definition? I'm not specifying it when I call the method, so it should default to an empty list, right?