[+] Implement rate limit

This commit is contained in:
Hykilpikonna
2021-11-21 23:03:10 -05:00
parent 181a89688b
commit 44ef88c420
+22 -1
View File
@@ -2,6 +2,7 @@ import io
import json import json
import math import math
import random import random
import time
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
@@ -157,6 +158,20 @@ def download_users(start_point: str, n: float = math.inf,
if base_dir.endswith('/'): if base_dir.endswith('/'):
base_dir = base_dir[:-1] base_dir = base_dir[:-1]
# Limit request rate
start_time = time.time()
num_requests = 0
# Ensure that the current request rate is under the specified rate limit.
def ensure_rate_limit() -> None:
requests_per_minute = num_requests / (time.time() - start_time) * 60
# We're over the rate limit.
if requests_per_minute < rate_limit:
# Sleep and check again
debug('Rate-limit reached, sleeping')
time.sleep((rate_limit - requests_per_minute) * 60)
ensure_rate_limit()
# Set of all the downloaded users' screen names # Set of all the downloaded users' screen names
downloaded = set() downloaded = set()
@@ -171,11 +186,14 @@ def download_users(start_point: str, n: float = math.inf,
# Loop until there are enough users # Loop until there are enough users
while len(downloaded) < n: while len(downloaded) < n:
ensure_rate_limit()
# Take a screen name from the current list # Take a screen name from the current list
screen_name = current_set.pop() screen_name = current_set.pop()
# Get a list of friends. # Get a list of friends.
friends = api.get_friends(screen_name=screen_name, count=5000) friends = api.get_friends(screen_name=screen_name, count=5000)
num_requests += 1
# Save users # Save users
for user in friends: for user in friends:
@@ -187,6 +205,7 @@ def download_users(start_point: str, n: float = math.inf,
# Add to set # Add to set
downloaded.add(user.screen_name) downloaded.add(user.screen_name)
# debug(f'- Downloaded {user.screen_name}')
# Get users and their popularity that we haven't downloaded # Get users and their popularity that we haven't downloaded
screen_names = [(user.screen_name, user.followers_count) for user in friends screen_names = [(user.screen_name, user.followers_count) for user in friends
@@ -196,7 +215,6 @@ def download_users(start_point: str, n: float = math.inf,
screen_names.sort(key=lambda x: x[1]) screen_names.sort(key=lambda x: x[1])
# Add 3 random users to the next set # Add 3 random users to the next set
samples = set()
if len(screen_names) > 3: if len(screen_names) > 3:
samples = {n[0] for n in random.sample(screen_names, 3)} samples = {n[0] for n in random.sample(screen_names, 3)}
else: else:
@@ -223,6 +241,9 @@ def download_users(start_point: str, n: float = math.inf,
current_set: current_set, next_set: next_set} current_set: current_set, next_set: next_set}
f.write(json.dumps(meta)) f.write(json.dumps(meta))
debug(f'Finished saving friends of {screen_name}')
debug(f'============= Total {len(downloaded)} saved =============')
def convert_to_generic(username: str, tweet: Tweet) -> Posting: def convert_to_generic(username: str, tweet: Tweet) -> Posting:
""" """