def fetch_profiles(client, screen_names, storage): """ Fetch twitter profile information for screen_names and add them to storage Can request 100 profiles per request and 180 profiles per 15mins, hence the swapping of request sizes for 100, 80 """ lookup_uri = client.twitter_uri('users', 'lookup') rate_limit = 180 while screen_names: if rate_limit > 100: size_limit, rate_limit = 100, rate_limit - 100 else: size_limit = rate_limit clump = screen_names[:size_limit] response = client.get(lookup_uri, params={'screen_name': ",".join(clump)}) if ok(response): del screen_names[:size_limit] for profile in response.json: storage.store_profile(profile) logger.debug("fetched {} profiles, {} left".format(len(clump), len(screen_names))) elif not_found(response): # none of the screen names were valid del screen_names[:size_limit] elif rate_limited(response): # rate limiting, need to sleep client.wait_for(lookup_uri) rate_limit = 180 else: raise UnexpectedError(response.status_code, response.text) client.enhance_my_calm()
def fetch_cursored_collection(client, screen_name, resource_uri, storage_func): """ Fetch each page of friends/followers collections for a screen name adding the resulting list by calling storage_func(screen_name, result) """ cursor = -1 result = [] while cursor != 0: response = client.get(resource_uri, params={'screen_name': screen_name, 'cursor': cursor}) client.enhance_my_calm() if ok(response): logger.debug('fetched {} ids from {}'.format( len(response.json['ids']), resource_uri)) result.extend(response.json['ids']) cursor = response.json['next_cursor'] if cursor == 0: break logger.debug('next cursor {}'.format(cursor)) elif not_found(response): return elif rate_limited(response): client.wait_for(resource_uri) else: raise UnexpectedError(response.status_code, response.text) storage_func(screen_name, result)