Skip to content

Instantly share code, notes, and snippets.

@bboe
Last active June 7, 2021 06:26
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bboe/1860715 to your computer and use it in GitHub Desktop.
Save bboe/1860715 to your computer and use it in GitHub Desktop.
Python Reddit API Comment Loop Test
#!/usr/bin/env python3
import logging
import sys
import time
import praw
def configure_logging():
logger = logging.getLogger("praw")
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())
def main():
configure_logging()
reddit = praw.Reddit("SITENAME", user_agent="PRAW loop test")
reddit.config.ratelimit_seconds = 0xFFFF
last = time.time()
subreddit = reddit.subreddit("test")
for i, submission in enumerate(subreddit.new()):
submission.reply(f"Test comment: {i}")
now = time.time()
print(f"{now - last:.2f} {i:2d} {submission.title}")
last = now
if __name__ == "__main__":
sys.exit(main())
@Coriou
Copy link

Coriou commented Aug 16, 2015

4 years, still good. Only thing is now "Reddit" is "Praw".

@sticks-stuff
Copy link

sticks-stuff commented Oct 10, 2020

Since this shows up as one of the first results on google, I figured I'd post my updated version in Python3 here

def handle_ratelimit(func, *args, **kwargs):
	while True:
		try:
			func(*args, **kwargs)
			break
		except praw.exceptions.RedditAPIException as exception:
			totalLength = str(exception.items[0].message).split('you are doing that too much. try again in ', 1)[1]
			minutesToSleep = totalLength[0].partition("minutes.")[0]
			secondsToSleep = int(minutesToSleep) * 60
			print("Sleeping for " + str(secondsToSleep) + " seconds")
			time.sleep(secondsToSleep)

@jcallin
Copy link

jcallin commented Jun 6, 2021

Ok I just noticed this as of June 2021 but they have changed the message in their error message so that the above code will no longer work. My guess is they do this every so often to deter old bots that are no longer updated from using this method of retry. The new message reads like so:

"Looks like you've been doing that a lot. Take a break for 37 seconds before trying again."

And the above code can be modified like so to make it work

def handle_ratelimit(func, *args, **kwargs):
	while True:
		try:
			func(*args, **kwargs)
			break
		except praw.exceptions.RedditAPIException as exception:
			totalLength = str(exception.items[0].message).split('Looks like you've been doing that a lot. Take a break for ', 1)[1]
			minutesToSleep = totalLength[0].partition("minutes.")[0]
			secondsToSleep = int(minutesToSleep) * 60
			print("Sleeping for " + str(secondsToSleep) + " seconds")
			time.sleep(secondsToSleep)

My personal solution to this uses regex and looks like

def sleep_for_seconds(text):
    find_seconds = r'(\d+) seconds?'
    find_minutes = r'(\d+) minutes?'

    time_seconds = re.search(find_seconds, text)
    time_minutes = re.search(find_minutes, text)

    if time_seconds is not None:
        sleep_time = time_seconds.group(1)
        return float(sleep_time)
    elif time_minutes is not None:
        sleep_time = time_minutes.group(1)
        return float(sleep_time) * 60
    else:
        return float(0)

@bboe
Copy link
Author

bboe commented Jun 7, 2021

Thanks everyone for the updates. I updated the gist to work with Python 3.6+ and PRAW 7.0+ where PRAW has built-in support for retries based upon the configuration value ratelimit_seconds.

https://praw.readthedocs.io/en/latest/getting_started/configuration/options.html#miscellaneous-configuration-options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment