Migrating to Async PRAW

With the conversion to async, there are few critical changes that had to be made. This page outlines a few those changes.

Network Requests

Async PRAW utilizes aiohttp to make network requests to Reddit’s API. Since aiohttp can only be used in an asynchronous environment, all network requests need to be awaited. Due to this, most Async PRAW methods need to be awaited as well. You can tell if a method needs awaited by looking at the docs. For example, me() has the word await before me(use_cache: bool = True) in the header for that method since that method makes a network request.

Lazy Loading

In PRAW, the majority of objects are lazily loaded and are not fetched until an attribute is accessed. With Async PRAW, objects can be fetched on initialization and some now do this by default. For example:

  • PRAW:

    # network request is not made and object is lazily loaded
    submission = reddit.submission("id")
    
    # network request is made and object is fully fetched
    print(submission.score)
    
  • Async PRAW:

    # network request made and object is fully loaded
    submission = await reddit.submission("id")
    
    # network request is not made as object is already fully fetched
    print(submission.score)
    

Now, lazy loading is not gone completely and can still be done. For example, if you only want to remove a post, you don’t need the object fully fetched to do that.

  • PRAW:

    # object is not fetched and is only removed
    reddit.submission("id").mod.remove()
    
  • Async PRAW:

    # network request is not made and object is lazily loaded
    submission = await reddit.submission("id", fetch=False)
    
    # object is not fetched and is only removed
    await submission.mod.remove()
    

The following objects are still lazily loaded by default:

You can pass fetch=True in their respective helper method to fully load it.

Inversely, the following objects are now fully fetched when initialized:

You can pass fetch=False in their respective helper method if you want to lazily load it.

In addition, there will be a load() method provided for manually fetching/refreshing objects that subclass RedditBase. If you need to later on access an attribute you need to call the .load() method first:

# object is lazily loaded and no requests are made
submission = await reddit.submission("id", fetch=False)
...
# network request is made and item is fully fetched
await submission.load()

# network request is not made as object is already fully fetched
print(submission.score)

Getting items by Indices

In PRAW you could get specific Emoji, LiveUpdate, RemovalReason, Rule, and WikiPage, objects by using string indices. This will no longer work and has been converted to a .get_<item name>(item) method. Also, they are not lazily loaded by default anymore.

  • PRAW:

    # lazily creates a WikiPage instance
    page = subreddit.wiki["page"]
    
    # network request is made and item is fully fetched
    print(page.content_md)
    
  • Async PRAW:

    # network request made and object is fully loaded
    page = await subreddit.wiki.get_page("page")
    
    # network request is not made as WikiPage is already fully fetched``
    print(page.content_md)
    
    # using slices
    rule = await subreddit.mod.rules.get_rule(slice(-3, None))  # to get the last 3 rules