PRAW: The Python Reddit API Wrapper

PRAW’s documentation is organized into the following sections:

Documentation Conventions

Unless otherwise mentioned, all examples in this document assume the use of a script application. See Authenticating via OAuth for information on using installed applications and web applications.

Quick Start

In this section, we go over everything you need to know to start building scripts or bots using PRAW, the Python Reddit API Wrapper. It’s fun and easy. Let’s get started.

Prerequisites

Python Knowledge

You need to know at least a little Python to use PRAW. PRAW supports Python 3.7+. If you are stuck on a problem, r/learnpython is a great place to ask for help.

Reddit Knowledge

A basic understanding of how Reddit works is a must. In the event you are not already familiar with Reddit start at Reddit Help.

Reddit Account

A Reddit account is required to access Reddit’s API. Create one at reddit.com.

Client ID & Client Secret

These two values are needed to access Reddit’s API as a script application (see Authenticating via OAuth for other application types). If you don’t already have a client ID and client secret, follow Reddit’s First Steps Guide to create them.

User Agent

A user agent is a unique identifier that helps Reddit determine the source of network requests. To use Reddit’s API, you need a unique and descriptive user agent. The recommended format is <platform>:<app ID>:<version string> (by u/<Reddit username>). For example, android:com.example.myredditapp:v1.2.3 (by u/kemitche). Read more about user agents at Reddit’s API wiki page.

With these prerequisites satisfied, you are ready to learn how to do some of the most common tasks with Reddit’s API.

Common Tasks

Obtain a Reddit Instance

Warning

For the sake of brevity, the following examples pass authentication information via arguments to praw.Reddit(). If you do this, you need to be careful not to reveal this information to the outside world if you share your code. It is recommended to use a praw.ini file in order to keep your authentication information separate from your code.

You need an instance of the Reddit class to do anything with PRAW. There are two distinct states a Reddit instance can be in: read-only, and authorized.

Read-only Reddit Instances

To create a read-only Reddit instance, you need three pieces of information:

  1. Client ID

  2. Client secret

  3. User agent

You may choose to provide these by passing in three keyword arguments when calling the initializer of the Reddit class: client_id, client_secret, user_agent (see Configuring PRAW for other methods of providing this information). For example:

import praw

reddit = praw.Reddit(
    client_id="my client id",
    client_secret="my client secret",
    user_agent="my user agent",
)

Just like that, you now have a read-only Reddit instance.

print(reddit.read_only)
# Output: True

With a read-only instance, you can do something like obtaining 10 “hot” submissions from r/test:

# continued from code above

for submission in reddit.subreddit("test").hot(limit=10):
    print(submission.title)

# Output: 10 submissions

If you want to do more than retrieve public information from Reddit, then you need an authorized Reddit instance.

Note

In the above example we are limiting the results to 10. Without the limit parameter PRAW should yield as many results as it can with a single request. For most endpoints this results in 100 items per request. If you want to retrieve as many as possible pass in limit=None.

Authorized Reddit Instances

In order to create an authorized Reddit instance, two additional pieces of information are required for script applications (see Authenticating via OAuth for other application types):

  1. Your Reddit username, and

  2. Your Reddit password

Again, you may choose to provide these by passing in keyword arguments username and password when you call the Reddit initializer, like the following:

import praw

reddit = praw.Reddit(
    client_id="my client id",
    client_secret="my client secret",
    password="my password",
    user_agent="my user agent",
    username="my username",
)

print(reddit.read_only)
# Output: False

Now you can do whatever your Reddit account is authorized to do. And you can switch back to read-only mode whenever you want:

# continued from code above
reddit.read_only = True

Note

If you are uncomfortable hard-coding your credentials into your program, there are some options available to you. Please see: Configuring PRAW.

Obtain a Subreddit

To obtain a Subreddit instance, pass the subreddit’s name when calling subreddit on your Reddit instance. For example:

# assume you have a praw.Reddit instance bound to variable `reddit`
subreddit = reddit.subreddit("redditdev")

print(subreddit.display_name)
# Output: redditdev
print(subreddit.title)
# Output: reddit development
print(subreddit.description)
# Output: a subreddit for discussion of ...
Obtain Submission Instances from a Subreddit

Now that you have a Subreddit instance, you can iterate through some of its submissions, each bound to an instance of Submission. There are several sorts that you can iterate through:

  • controversial

  • gilded

  • hot

  • new

  • rising

  • top

Each of these methods will immediately return a ListingGenerator, which is to be iterated through. For example, to iterate through the first 10 submissions based on the hot sort for a given subreddit try:

# assume you have a Subreddit instance bound to variable `subreddit`
for submission in subreddit.hot(limit=10):
    print(submission.title)
    # Output: the submission's title
    print(submission.score)
    # Output: the submission's score
    print(submission.id)
    # Output: the submission's ID
    print(submission.url)
    # Output: the URL the submission points to or the submission's URL if it's a self post

Note

The act of calling a method that returns a ListingGenerator does not result in any network requests until you begin to iterate through the ListingGenerator.

You can create Submission instances in other ways too:

# assume you have a praw.Reddit instance bound to variable `reddit`
submission = reddit.submission("39zje0")
print(submission.title)
# Output: reddit will soon only be available ...

# or
submission = reddit.submission(url="https://www.reddit.com/...")
Obtain Redditor Instances

There are several ways to obtain a redditor (a Redditor instance). Two of the most common ones are:

For example:

# assume you have a Submission instance bound to variable `submission`
redditor1 = submission.author
print(redditor1.name)
# Output: name of the redditor

# assume you have a praw.Reddit instance bound to variable `reddit`
redditor2 = reddit.redditor("bboe")
print(redditor2.link_karma)
# Output: u/bboe's karma
Obtain Comment Instances

Submissions have a comments attribute that is a CommentForest instance. That instance is iterable and represents the top-level comments of the submission by the default comment sort (confidence). If you instead want to iterate over all comments as a flattened list you can call the list() method on a CommentForest instance. For example:

# assume you have a praw.Reddit instance bound to variable `reddit`
top_level_comments = list(submission.comments)
all_comments = submission.comments.list()

Note

The comment sort order can be changed by updating the value of comment_sort on the Submission instance prior to accessing comments (see: /api/set_suggested_sort for possible values). For example to have comments sorted by new try something like:

# assume you have a praw.Reddit instance bound to variable `reddit`
submission = reddit.submission("39zje0")
submission.comment_sort = "new"
top_level_comments = list(submission.comments)

As you may be aware there will periodically be MoreComments instances scattered throughout the forest. Replace those MoreComments instances at any time by calling replace_more() on a CommentForest instance. Calling replace_more() access comments, and so must be done after comment_sort is updated. See Extracting comments with PRAW for an example.

Determine Available Attributes of an Object

If you have a PRAW object, e.g., Comment, Message, Redditor, or Submission, and you want to see what attributes are available along with their values, use the built-in vars() function of python. For example:

import pprint

# assume you have a praw.Reddit instance bound to variable `reddit`
submission = reddit.submission("39zje0")
print(submission.title)  # to make it non-lazy
pprint.pprint(vars(submission))

Note the line where we print the title. PRAW uses lazy objects so that network requests to Reddit’s API are only issued when information is needed. Here, before the print line, submission points to a lazy Submission object. When we try to print its title, additional information is needed, thus a network request is made, and the instances ceases to be lazy. Outputting all the attributes of a lazy object will result in fewer attributes than expected.

Installing PRAW

PRAW supports Python 3.7+. The recommended way to install PRAW is via pip.

pip install praw

Note

Depending on your system, you may need to use pip3 to install packages for Python 3.

Warning

Avoid using sudo to install packages. Do you really trust this package?

For instructions on installing Python and pip see “The Hitchhiker’s Guide to Python” Installation Guides.

Updating PRAW

PRAW can be updated by running:

pip install --upgrade praw

Installing Older Versions

Older versions of PRAW can be installed by specifying the version number as part of the installation command:

pip install praw==3.6.0

Installing the Latest Development Version

Is there a feature that was recently merged into PRAW that you cannot wait to take advantage of? If so, you can install PRAW directly from GitHub like so:

pip install --upgrade https://github.com/praw-dev/praw/archive/master.zip

You can also directly clone a copy of the repository using git, like so:

pip install --upgrade git+https://github.com/praw-dev/praw.git

Authenticating via OAuth

PRAW supports all three types of applications that can be registered on Reddit. Those are:

Before you can use any one of these with PRAW, you must first register an application of the appropriate type on Reddit.

If your application does not require a user context, it is read-only.

PRAW supports the flows that each of these applications can use. The following table defines which application types can use which flows:

Application Type

Script

Web

Installed

Default Flow

Password

Code

Alternative Flows

Code

Application-Only (Client Credentials)

Implicit

Application-Only (Client Credentials)

Application-Only (Installed Client)

Warning

For the sake of brevity, the following examples pass authentication information via arguments to Reddit. If you do this, you need to be careful not to reveal this information to the outside world if you share your code. It is recommended to use a praw.ini file in order to keep your authentication information separate from your code.

Password Flow

Password Flow is the simplest type of authentication flow to work with because no callback process is involved in obtaining an access_token.

While password flow applications do not involve a redirect URI, Reddit still requires that you provide one when registering your script application – http://localhost:8080 is a simple one to use.

In order to use a password flow application with PRAW you need four pieces of information:

client_id

The client ID is at least a 14-character string listed just under “personal use script” for the desired developed application

client_secret

The client secret is at least a 27-character string listed adjacent to secret for the application.

password

The password for the Reddit account used to register the application.

username

The username of the Reddit account used to register the application.

With this information authorizing as username using a password flow app is as simple as:

reddit = praw.Reddit(
    client_id="SI8pN3DSbt0zor",
    client_secret="xaxkj7HNh8kwg8e5t4m6KvSrbTI",
    password="1guiwevlfo00esyy",
    user_agent="testscript by u/fakebot3",
    username="fakebot3",
)

To verify that you are authenticated as the correct user run:

print(reddit.user.me())

The output should contain the same name as you entered for username.

Note

If the following exception is raised, double-check your credentials, and ensure that that the username and password you are using are for the same user with which the application is associated:

OAuthException: invalid_grant error processing request
Two-Factor Authentication

A 2FA token can be used by joining it to the password with a colon:

reddit = praw.Reddit(
    client_id="SI8pN3DSbt0zor",
    client_secret="xaxkj7HNh8kwg8e5t4m6KvSrbTI",
    password="1guiwevlfo00esyy:955413",
    user_agent="testscript by u/fakebot3",
    username="fakebot3",
)

However, for such an app there is little benefit to using 2FA. The token must be refreshed after one hour; therefore, the 2FA secret would have to be stored along with the rest of the credentials in order to generate the token, which defeats the point of having an extra credential beyond the password.

If you do choose to use 2FA, you must handle the prawcore.OAuthException that will be raised by API calls after one hour.

Code Flow

A code flow application is useful for two primary purposes:

  • You have an application and want to be able to access Reddit from your users’ accounts.

  • You have a personal-use script application and you either want to

    • limit the access one of your PRAW-based programs has to Reddit

    • avoid the hassle of 2FA (described above)

    • not pass your username and password to PRAW (and thus not keep it in memory)

When registering your application you must provide a valid redirect URI. If you are running a website you will want to enter the appropriate callback URL and configure that endpoint to complete the code flow.

If you aren’t actually running a website, you can follow the Working with Refresh Tokens tutorial to learn how to obtain and use the initial refresh token.

Whether or not you follow the Working with Refresh Tokens tutorial there are two processes involved in obtaining access or refresh tokens.

Obtain the Authorization URL

The first step to completing the code flow is to obtain the authorization URL. You can do that as follows:

reddit = praw.Reddit(
    client_id="SI8pN3DSbt0zor",
    client_secret="xaxkj7HNh8kwg8e5t4m6KvSrbTI",
    redirect_uri="http://localhost:8080",
    user_agent="testscript by u/fakebot3",
)
print(reddit.auth.url(scopes=["identity"], state="...", duration="permanent"))

The above will output an authorization URL for a permanent token (i.e., the resulting authorization will include both a short-lived access_token, and a longer-lived, single use refresh_token) that has only the identity scope. See url() for more information on these parameters.

This URL should be accessed by the account that desires to authorize their Reddit access to your application. On completion of that flow, the user’s browser will be redirected to the specified redirect_uri. After verifying the state and extracting the code you can obtain the refresh token via:

print(reddit.auth.authorize(code))
print(reddit.user.me())

The first line of output is the refresh_token. You can save this for later use (see Using a Saved Refresh Token).

The second line of output reveals the name of the Redditor that completed the code flow. It also indicates that the Reddit instance is now associated with that account.

The code flow can be used with an installed application just as described above with one change: set the value of client_secret to None when initializing Reddit.

Implicit Flow

The implicit flow requires a similar instantiation of the Reddit class as done in Code Flow, however, the token is returned directly as part of the redirect. For the implicit flow call url() like so:

print(reddit.auth.url(scopes=["identity"], state="...", implicit=True))

Then use implicit() to provide the authorization to the Reddit instance.

Read-Only Mode

All application types support a read-only mode. Read-only mode provides access to Reddit like a logged out user would see including the default subreddits in the reddit.front listings.

In the absence of a refresh_token both Code Flow and Implicit Flow applications start in the read-only mode. With such applications read-only mode is disabled when authorize(), or implicit() are successfully called. Password Flow applications start up with read-only mode disabled.

Read-only mode can be toggled via:

# Enable read-only mode
reddit.read_only = True

# Disable read-only mode (must have a valid authorization)
reddit.read_only = False
Application-Only Flows

The following flows are the read-only mode flows for Reddit applications

Application-Only (Client Credentials)

This is the default flow for read-only mode in script and web applications. The idea behind this is that Reddit can trust these applications as coming from a given developer, however the application requires no logged-in user context.

An installed application cannot use this flow, because Reddit requires a client_secret to be given if this flow is being used. In other words, installed applications are not considered confidential clients.

Application-Only (Installed Client)

This is the default flow for read-only mode in installed applications. The idea behind this is that Reddit might not be able to trust these applications as coming from a given developer. This would be able to happen if someone other than the developer can potentially replicate the client information and then pretend to be the application, such as in installed applications where the end user could retrieve the client_id.

Note

No benefit is really gained from this in script or web apps. The one exception is for when a script or web app has multiple end users, this will allow you to give Reddit the information needed in order to distinguish different users of your app from each other (as the supplied device ID should be a unique string per both device (in the case of a web app, server) and user (in the case of a web app, browser session).

Using a Saved Refresh Token

A saved refresh token can be used to immediately obtain an authorized instance of Reddit like so:

reddit = praw.Reddit(
    client_id="SI8pN3DSbt0zor",
    client_secret="xaxkj7HNh8kwg8e5t4m6KvSrbTI",
    refresh_token="WeheY7PwgeCZj4S3QgUcLhKE5S2s4eAYdxM",
    user_agent="testscript by u/fakebot3",
)
print(reddit.auth.scopes())

The output from the above code displays which scopes are available on the Reddit instance.

Note

Observe that redirect_uri does not need to be provided in such cases. It is only needed when url() is used.

Configuring PRAW

Configuration Options

PRAW’s configuration options are broken down into the following categories:

All of these options can be provided in any of the ways mentioned in Configuring PRAW.

Basic Configuration Options
check_for_updates

When true, check for new versions of PRAW. When a newer version of PRAW is available a message is reported via standard error (default: true).

user_agent

(Required) A unique description of your application. The following format is recommended according to Reddit’s API Rules: <platform>:<app ID>:<version string> (by u/<reddit username>).

OAuth Configuration Options
client_id

(Required) The OAuth client ID associated with your registered Reddit application. See Authenticating via OAuth for instructions on registering a Reddit application.

client_secret

The OAuth client secret associated with your registered Reddit application. This option is required for all application types, however, the value must be set to None for installed applications.

redirect_uri

The redirect URI associated with your registered Reddit application. This field is unused for script applications and is only needed for both web applications, and installed applications when the url() method is used.

password

The password of the Reddit account associated with your registered Reddit script application. This field is required for script applications, and PRAW assumes it is working with a script application by its presence.

username

The username of the Reddit account associated with your registered Reddit script application. This field is required for script applications, and PRAW assumes it is working with a script application by its presence.

Reddit Site Configuration Options

PRAW can be configured to work with instances of Reddit which are not hosted at reddit.com. The following options may need to be updated in order to successfully access a third-party Reddit site:

comment_kind

The type prefix for comments on the Reddit instance (default: t1_).

message_kind

The type prefix for messages on the Reddit instance (default: t4_).

oauth_url

The URL used to access the Reddit instance’s API (default: https://oauth.reddit.com).

reddit_url

The URL used to access the Reddit instance. PRAW assumes the endpoints for establishing OAuth authorization are accessible under this URL (default: https://www.reddit.com).

redditor_kind

The type prefix for redditors on the Reddit instance (default: t2_).

short_url

The URL used to generate short links on the Reddit instance (default: https://redd.it).

submission_kind

The type prefix for submissions on the Reddit instance (default: t3_).

subreddit_kind

The type prefix for subreddits on the Reddit instance (default: t5_).

Miscellaneous Configuration Options

These are options that do not belong in another category, but still play a part in PRAW.

check_for_async

When true, check if PRAW is being ran in an asynchronous environment whenever a request is made. If so, a warning will be logged recommending the usage of Async PRAW (default: true).

ratelimit_seconds

Controls the maximum number of seconds PRAW will capture ratelimits returned in JSON data. Because this can be as high as 14 minutes, only ratelimits of up to 5 seconds are captured and waited on by default.

Note

PRAW sleeps for the ratelimit value plus 1 second.

See Ratelimits for more info.

timeout

Controls the amount of time PRAW will wait for a request from Reddit to complete before throwing an exception. By default, PRAW waits 16 seconds before throwing an exception.

warn_comment_sort

When true, log a warning when the comment_sort attribute of a submission is updated after _fetch() has been called (default: true).

Custom Configuration Options

Your application can utilize PRAW’s configuration system in order to provide its own custom settings.

For instance you might want to add an app_debugging: true option to your application’s praw.ini file. To retrieve the value of this custom option from an instance of Reddit you can execute:

reddit.config.custom["app_debugging"]

Note

Custom PRAW configuration environment variables are not supported. You can directly access environment variables via os.getenv.

Configuration options can be provided to PRAW in one of three ways:

praw.ini Files

PRAW comes with a praw.ini file in the package directory, and looks for user defined praw.ini files in a few other locations:

  1. In the current working directory at the time Reddit is initialized.

  2. In the launching user’s config directory. This directory, if available, is detected in order as one of the following:

    1. In the directory specified by the XDG_CONFIG_HOME environment variable on operating systems that define such an environment variable (some modern Linux distributions).

    2. In the directory specified by $HOME/.config if the HOME environment variable is defined (Linux and Mac OS systems).

    3. In the directory specified by the APPDATA environment variable (Windows).

      Note

      To check the values of the environment variables, you can open up a terminal (Terminal/Terminal.app/Command Prompt/Powershell) and echo the variables (replacing <variable> with the name of the variable):

      MacOS/Linux:

      echo "$<variable>"
      

      Windows Command Prompt

      echo "%<variable>%"
      

      Powershell

      Write-Output "$env:<variable>"
      

      You can also view environment variables in Python:

      import os
      
      print(os.environ.get("<variable>", ""))
      
Format of praw.ini

praw.ini uses the INI file format, which can contain multiple groups of settings separated into sections. PRAW refers to each section as a site. The default site, DEFAULT, is provided in the package’s praw.ini file. This site defines the default settings for interaction with Reddit. The contents of the package’s praw.ini file are:

[DEFAULT]
# A boolean to indicate whether or not to check for package updates.
check_for_updates=True

# Object to kind mappings
comment_kind=t1
message_kind=t4
redditor_kind=t2
submission_kind=t3
subreddit_kind=t5
trophy_kind=t6

# The URL prefix for OAuth-related requests.
oauth_url=https://oauth.reddit.com

# The amount of seconds of ratelimit to sleep for upon encountering a specific type of 429 error.
ratelimit_seconds=5

# The URL prefix for regular requests.
reddit_url=https://www.reddit.com

# The URL prefix for short URLs.
short_url=https://redd.it

# The timeout for requests to Reddit in number of seconds
timeout=16

Warning

Avoid modifying the package’s praw.ini file. Prefer instead to override its values in your own praw.ini file. You can even override settings of the DEFAULT site in user defined praw.ini files.

Defining Additional Sites

In addition to the DEFAULT site, additional sites can be configured in user defined praw.ini files. All sites inherit settings from the DEFAULT site and can override whichever settings desired.

Defining additional sites is a convenient way to store OAuth credentials for various accounts, or distinct OAuth applications. For example if you have three separate bots, you might create a site for each:

[bot1]
client_id=revokedpDQy3xZ
client_secret=revokedoqsMk5nHCJTHLrwgvHpr
password=invalidht4wd50gk
username=fakebot1

[bot2]
client_id=revokedcIqbclb
client_secret=revokedCClyu4FjVO77MYlTynfj
password=invalidzpiq8s59j
username=fakebot2

[bot3]
client_id=revokedSbt0zor
client_secret=revokedNh8kwg8e5t4m6KvSrbTI
password=invalidlfo00esyy
username=fakebot3
Choosing a Site

Site selection is done via the site_name parameter to Reddit. For example, to use the settings defined for bot2 as shown above, initialize Reddit like so:

reddit = praw.Reddit("bot2", user_agent="bot2 user agent")

Note

In the above example you can obviate passing user_agent if you add the setting user_agent=... in the [bot2] site definition.

A site can also be selected via a praw_site environment variable. This approach has precedence over the site_name parameter described above.

Using Interpolation

By default PRAW doesn’t apply any interpolation on the config file but this can be changed with the config_interpolation parameter which can be set to “basic” or “extended”.

This can be useful to separate the components of the user_agent into individual variables, for example:

[bot1]
bot_name=MyBot
bot_version=1.2.3
bot_author=MyUser
user_agent=script:%(bot_name)s:v%(bot_version)s (by u/%(bot_author)s)

This uses basic interpolation thus Reddit need to be initialized as follows:

reddit = praw.Reddit("bot1", config_interpolation="basic")

Then the value of reddit.config.user_agent will be "script:MyBot:v1.2.3 (by u/MyUser)".

See Interpolation of values for details.

Warning

The configparser.ConfigParser instance is cached internally at the class level, it is shared across all instances of Reddit and once set it’s not overridden by future invocations.

Keyword Arguments to Reddit

Most of PRAW’s documentation will demonstrate configuring PRAW through the use of keyword arguments when initializing instances of Reddit. All of the Configuration Options can be specified using a keyword argument of the same name.

For example, if we wanted to explicitly pass the information for bot3 defined in the praw.ini custom site example without using the bot3 site, we would initialize Reddit as:

reddit = praw.Reddit(
    client_id="SI8pN3DSbt0zor",
    client_secret="xaxkj7HNh8kwg8e5t4m6KvSrbTI",
    password="1guiwevlfo00esyy",
    user_agent="testscript by u/fakebot3",
    username="fakebot3",
)

PRAW Environment Variables

The second-highest priority configuration options can be passed to a program via environment variables prefixed with praw_.

For example, you can invoke your script as follows:

praw_username=bboe praw_password=not_my_password python my_script.py

The username and password provided via environment variables will override any values contained in a praw.ini file, but not any variables passed in through Reddit.

All Configuration Options can be provided in this manner, except for custom options.

Environment variables have the highest priority, followed by keyword arguments to Reddit, and finally settings in praw.ini files.

Using an HTTP or HTTPS proxy with PRAW

PRAW internally relies upon the requests package to handle HTTP requests. Requests supports use of HTTP_PROXY and HTTPS_PROXY environment variables in order to proxy HTTP and HTTPS requests respectively [ref].

Given that PRAW exclusively communicates with Reddit via HTTPS, only the HTTPS_PROXY option should be required.

For example, if you have a script named prawbot.py, the HTTPS_PROXY environment variable can be provided on the command line like so:

HTTPS_PROXY=http://localhost:3128 ./prawbot.py

Configuring a custom requests Session

PRAW uses requests to handle networking. If your use-case requires custom configuration, it is possible to configure a custom Session instance and then use it with PRAW.

For example, some networks use self-signed SSL certificates when connecting to HTTPS sites. By default, this would raise an exception in requests. To use a self-signed SSL certificate without an exception from requests, first export the certificate as a .pem file. Then configure PRAW like so:

import praw
from requests import Session


session = Session()
session.verify = "/path/to/certfile.pem"
reddit = praw.Reddit(
    client_id="SI8pN3DSbt0zor",
    client_secret="xaxkj7HNh8kwg8e5t4m6KvSrbTI",
    password="1guiwevlfo00esyy",
    requestor_kwargs={"session": session},  # pass the custom Session instance
    user_agent="testscript by u/fakebot3",
    username="fakebot3",
)

The code above creates a custom Session instance and configures it to use a custom certificate, then passes it as a parameter when creating the Reddit instance. Note that the example above uses a Password Flow authentication type, but this method will work for any authentication type.

Running Multiple Instances of PRAW

PRAW, as of version 4, performs rate limiting dynamically based on the HTTP response headers from Reddit. As a result you can safely run a handful of PRAW instances without any additional configuration.

Note

Running more than a dozen or so instances of PRAW concurrently may occasionally result in exceeding Reddit’s rate limits as each instance can only guess how many other instances are running.

If you are authorized on other users’ behalf, each authorization should have its own rate limit, even when running from a single IP address.

Discord Bots and Asynchronous Environments

If you plan on using PRAW in an asynchronous environment, (e.g., discord.py, asyncio) it is strongly recommended to use Async PRAW. It is the official asynchronous version of PRAW and its usage is similar and has the same features as PRAW.

Note

By default, PRAW will check to see if it is in an asynchronous environment every time a network request is made. To disable this check, set the check_for_async configuration option to False. For example:

import praw

reddit = praw.Reddit(..., check_for_async=False)

Multiple Programs

The recommended way to run multiple instances of PRAW is to simply write separate independent Python programs. With this approach one program can monitor a comment stream and reply as needed, and another program can monitor a submission stream, for example.

If these programs need to share data consider using a third-party system such as a database or queuing system.

Multiple Threads

Warning

PRAW is not thread safe.

In a nutshell, instances of Reddit are not thread-safe for a number of reasons in its own code and each instance depends on an instance of requests.Session, which is not thread-safe [ref].

In theory, having a unique Reddit instance for each thread, and making sure that the instances are used in their respective threads only, will work. Process has been confirmed to work with PRAW, so that is a viable choice as well. However, there are various errors with Pool, thus it is not supported by PRAW. Please use ThreadPool as an alternative to a process pool.

Please see this discussion and this GitHub issue for more information.

Logging in PRAW

It is occasionally useful to observe the HTTP requests that PRAW is issuing. To do so you have to configure and enable logging.

Add the following to your code to log everything available:

import logging

handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
for logger_name in ("praw", "prawcore"):
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(handler)

When properly configured, HTTP requests that are issued should produce output similar to the following:

Fetching: GET https://oauth.reddit.com/api/v1/me
Data: None
Params: {'raw_json': 1}
Response: 200 (876 bytes)

Furthermore, any API ratelimits from POST actions that are handled will produce a log entry with a message similar to the following message:

Rate limit hit, sleeping for 5.5 seconds

For more information on logging, see logging.Logger.

Ratelimits

Even though PRAW respects the X-Ratelimit-* headers and waits the appropriate time between requests, there are other unknown ratelimits that Reddit has that might require additional wait time (anywhere from milliseconds to minutes) for things such as commenting, editing comments/posts, banning users, adding moderators, etc. PRAW will sleep and try the request again if the requested wait time (as much as 600 seconds) is less than or equal to PRAW’s ratelimit_seconds configuration setting (default: 5s), PRAW will wait for the requested time plus 1 second. If the requested wait time exceeds the set value of ratelimit_seconds, PRAW will raise RedditAPIException.

For example, given the following Reddit instance:

import praw

reddit = praw.Reddit(..., ratelimit_seconds=300)

Let’s say your bot posts a comment to Reddit every 30 seconds and Reddit returns the ratelimit error: "You're doing that too much. Try again in 3 minutes.". PRAW will wait for 181 seconds since 181 seconds is less than the configured ratelimit_seconds of 300 seconds. However, if Reddit returns the ratelimit error: "You're doing that too much. Try again in 6 minutes.", PRAW will raise an exception since 360 seconds is greater than the configured ratelimit_seconds of 300 seconds.

Frequently Asked Questions

Q: How can I refresh a comment/subreddit/submission?

A: Directly calling the constructors will refresh the value:

reddit.comment(comment.id)
reddit.subreddit(subreddit.display_name)
reddit.submission(submission.id)

Q: Whenever I try to do anything, I get an invalid_grant error. What is the cause?

A: This means that either you provided the wrong password and/or the account you are trying to sign in with has 2FA enabled, and as such, either needs a 2FA token or a refresh token to sign in. A refresh token is preferred, because then you will not need to enter a 2FA token in order to sign in, and the session will last for longer than an hour. Refer to Two-Factor Authentication and Working with Refresh Tokens in order to use the respective auth methods.

Q: Some options (like getting moderator logs from r/mod) keep on timing out. How can I extend the timeout?

A: Set the timeout config option or initialize Reddit with a timeout of your choosing. Another option is to construct a Subreddit instance with a subset of subreddits (concatenated with +) that you want logs from like so:

reddit.subreddit("pics+LifeProTips")

Q: Help, I keep on getting redirected to /r/subreddit/login/!

Q2: I keep on getting this exception:

prawcore.exceptions.Redirect: Redirect to /r/subreddit/login/ (You may be trying to perform a non-read-only action via a read-only instance.)

A: PRAW is most likely in read-only mode. This normally occurs when PRAW is authenticated without a username and password or a refresh token. In order to perform this action, the Reddit instance needs to be authenticated. See OAuth Configuration Options to see the available authentication methods.

Q: Help, searching for URLs keeps on redirecting me to /submit!

Q2: I keep on getting this exception: prawcore.exceptions.Redirect: Redirect to /submit

A: Reddit redirects URL searches to the submit page of the URL. To search for the URL, prefix url: to the url and surround the url in quotation marks.

For example, the code block:

reddit.subreddit("all").search("https://google.com")

Will become this code block:

reddit.subreddit("all").search('url:"https://google.com"')

The Reddit Instance

class praw.Reddit(site_name: Optional[str] = None, *, config_interpolation: Optional[str] = None, requestor_class: Optional[Type[Requestor]] = None, requestor_kwargs: Optional[Dict[str, Any]] = None, token_manager: Optional[BaseTokenManager] = None, **config_settings: Optional[Union[str, bool, int]])

The Reddit class provides convenient access to Reddit’s API.

Instances of this class are the gateway to interacting with Reddit’s API through PRAW. The canonical way to obtain an instance of this class is via:

import praw

reddit = praw.Reddit(
    client_id="CLIENT_ID",
    client_secret="CLIENT_SECRET",
    password="PASSWORD",
    user_agent="USERAGENT",
    username="USERNAME",
)
__init__(site_name: Optional[str] = None, *, config_interpolation: Optional[str] = None, requestor_class: Optional[Type[Requestor]] = None, requestor_kwargs: Optional[Dict[str, Any]] = None, token_manager: Optional[BaseTokenManager] = None, **config_settings: Optional[Union[str, bool, int]])

Initialize a Reddit instance.

Parameters
  • site_name – The name of a section in your praw.ini file from which to load settings from. This parameter, in tandem with an appropriately configured praw.ini, file is useful if you wish to easily save credentials for different applications, or communicate with other servers running Reddit. If site_name is None, then the site name will be looked for in the environment variable praw_site. If it is not found there, the DEFAULT site will be used (default: None).

  • config_interpolation – Config parser interpolation type that will be passed to Config (default: None).

  • requestor_class – A class that will be used to create a requestor. If not set, use prawcore.Requestor (default: None).

  • requestor_kwargs – Dictionary with additional keyword arguments used to initialize the requestor (default: None).

  • token_manager – When provided, the passed instance, a subclass of BaseTokenManager, will manage tokens via two callback functions. This parameter must be provided in order to work with refresh tokens (default: None).

Additional keyword arguments will be used to initialize the Config object. This can be used to specify configuration settings during instantiation of the Reddit instance. For more details, please see Configuring PRAW.

Required settings are:

  • client_id

  • client_secret (for installed applications set this value to None)

  • user_agent

The requestor_class and requestor_kwargs allow for customization of the requestor Reddit will use. This allows, e.g., easily adding behavior to the requestor or wrapping its Session in a caching layer. Example usage:

import json

import betamax
import requests
from prawcore import Requestor

from praw import Reddit


class JSONDebugRequestor(Requestor):
    def request(self, *args, **kwargs):
        response = super().request(*args, **kwargs)
        print(json.dumps(response.json(), indent=4))
        return response


my_session = betamax.Betamax(requests.Session())
reddit = Reddit(
    ..., requestor_class=JSONDebugRequestor, requestor_kwargs={"session": my_session}
)
auth

An instance of Auth.

Provides the interface for interacting with installed and web applications.

comment(id: Optional[str] = None, *, url: Optional[str] = None)

Return a lazy instance of Comment.

Parameters
  • id – The ID of the comment.

  • url – A permalink pointing to the comment.

Note

If you want to obtain the comment’s replies, you will need to call refresh() on the returned Comment.

delete(path: str, *, data: Optional[Union[Dict[str, Union[str, Any]], bytes, IO, str]] = None, json: Optional[Dict[Any, Any]] = None, params: Optional[Union[str, Dict[str, str]]] = None) Any

Return parsed objects returned from a DELETE request to path.

Parameters
  • path – The path to fetch.

  • data – Dictionary, bytes, or file-like object to send in the body of the request (default: None).

  • json – JSON-serializable object to send in the body of the request with a Content-Type header of application/json (default: None). If json is provided, data should not be.

  • params – The query parameters to add to the request (default: None).

domain(domain: str)

Return an instance of DomainListing.

Parameters

domain – The domain to obtain submission listings for.

drafts

An instance of DraftHelper.

Provides the interface for working with Draft instances.

For example, to list the currently authenticated user’s drafts:

drafts = reddit.drafts()

To create a draft on r/test run:

reddit.drafts.create(title="title", selftext="selftext", subreddit="test")
front

An instance of Front.

Provides the interface for interacting with front page listings. For example:

for submission in reddit.front.hot():
    print(submission)
get(path: str, *, params: Optional[Union[str, Dict[str, Union[str, int]]]] = None)

Return parsed objects returned from a GET request to path.

Parameters
  • path – The path to fetch.

  • params – The query parameters to add to the request (default: None).

inbox

An instance of Inbox.

Provides the interface to a user’s inbox which produces Message, Comment, and Submission instances. For example, to iterate through comments which mention the authorized user run:

for comment in reddit.inbox.mentions():
    print(comment)
info(*, fullnames: Optional[Iterable[str]] = None, subreddits: Optional[Iterable[Union[praw.models.Subreddit, str]]] = None, url: Optional[str] = None) Generator[Union[praw.models.Subreddit, praw.models.Comment, praw.models.Submission], None, None]

Fetch information about each item in fullnames, url, or subreddits.

Parameters
  • fullnames – A list of fullnames for comments, submissions, and/or subreddits.

  • subreddits – A list of subreddit names or Subreddit objects to retrieve subreddits from.

  • url – A url (as a string) to retrieve lists of link submissions from.

Returns

A generator that yields found items in their relative order.

Items that cannot be matched will not be generated. Requests will be issued in batches for each 100 fullnames.

Note

For comments that are retrieved via this method, if you want to obtain its replies, you will need to call refresh() on the yielded Comment.

Note

When using the URL option, it is important to be aware that URLs are treated literally by Reddit’s API. As such, the URLs "youtube.com" and "https://www.youtube.com" will provide a different set of submissions.

live

An instance of LiveHelper.

Provides the interface for working with LiveThread instances. At present only new live threads can be created.

reddit.live.create(title="title", description="description")
multireddit

An instance of MultiredditHelper.

Provides the interface to working with Multireddit instances. For example, you can obtain a Multireddit instance via:

reddit.multireddit(redditor="samuraisam", name="programming")
notes

An instance of RedditModNotes.

Provides the interface for working with ModNotes for multiple redditors across multiple subreddits.

Note

The authenticated user must be a moderator of the provided subreddit(s).

For example, the latest note for u/spez in r/redditdev and r/test, and for u/bboe in r/redditdev can be iterated through like so:

redditor = reddit.redditor("bboe")
subreddit = reddit.subreddit("redditdev")

pairs = [(subreddit, "spez"), ("test", "spez"), (subreddit, redditor)]

for note in reddit.notes(pairs=pairs):
    print(f"{note.label}: {note.note}")
patch(path: str, *, data: Optional[Union[Dict[str, Union[str, Any]], bytes, IO, str]] = None, json: Optional[Dict[Any, Any]] = None) Any

Return parsed objects returned from a PATCH request to path.

Parameters
  • path – The path to fetch.

  • data – Dictionary, bytes, or file-like object to send in the body of the request (default: None).

  • json – JSON-serializable object to send in the body of the request with a Content-Type header of application/json (default: None). If json is provided, data should not be.

post(path: str, *, data: Optional[Union[Dict[str, Union[str, Any]], bytes, IO, str]] = None, files: Optional[Dict[str, IO]] = None, json: Optional[Dict[Any, Any]] = None, params: Optional[Union[str, Dict[str, str]]] = None) Any

Return parsed objects returned from a POST request to path.

Parameters
  • path – The path to fetch.

  • data – Dictionary, bytes, or file-like object to send in the body of the request (default: None).

  • files – Dictionary, filename to file (like) object mapping (default: None).

  • json – JSON-serializable object to send in the body of the request with a Content-Type header of application/json (default: None). If json is provided, data should not be.

  • params – The query parameters to add to the request (default: None).

put(path: str, *, data: Optional[Union[Dict[str, Union[str, Any]], bytes, IO, str]] = None, json: Optional[Dict[Any, Any]] = None)

Return parsed objects returned from a PUT request to path.

Parameters
  • path – The path to fetch.

  • data – Dictionary, bytes, or file-like object to send in the body of the request (default: None).

  • json – JSON-serializable object to send in the body of the request with a Content-Type header of application/json (default: None). If json is provided, data should not be.

random_subreddit(*, nsfw: bool = False) praw.models.Subreddit

Return a random lazy instance of Subreddit.

Parameters

nsfw – Return a random NSFW (not safe for work) subreddit (default: False).

property read_only: bool

Return True when using the ReadOnlyAuthorizer.

redditor(name: Optional[str] = None, *, fullname: Optional[str] = None) praw.models.Redditor

Return a lazy instance of Redditor.

Parameters
  • name – The name of the redditor.

  • fullname – The fullname of the redditor, starting with t2_.

Either name or fullname can be provided, but not both.

redditors

An instance of Redditors.

Provides the interface for Redditor discovery. For example, to iterate over the newest Redditors, run:

for redditor in reddit.redditors.new(limit=None):
    print(redditor)
request(*, data: Optional[Union[Dict[str, Union[str, Any]], bytes, IO, str]] = None, files: Optional[Dict[str, IO]] = None, json: Optional[Dict[Any, Any]] = None, method: str, params: Optional[Union[str, Dict[str, Union[str, int]]]] = None, path: str) Any

Return the parsed JSON data returned from a request to URL.

Parameters
  • data – Dictionary, bytes, or file-like object to send in the body of the request (default: None).

  • files – Dictionary, filename to file (like) object mapping (default: None).

  • json – JSON-serializable object to send in the body of the request with a Content-Type header of application/json (default: None). If json is provided, data should not be.

  • method – The HTTP method (e.g., "GET", "POST", "PUT", "DELETE").

  • params – The query parameters to add to the request (default: None).

  • path – The path to fetch.

submission(id: Optional[str] = None, *, url: Optional[str] = None) praw.models.Submission

Return a lazy instance of Submission.

Parameters

Either id or url can be provided, but not both.

subreddit

An instance of SubredditHelper.

Provides the interface to working with Subreddit instances. For example to create a Subreddit run:

reddit.subreddit.create(name="coolnewsubname")

To obtain a lazy Subreddit instance run:

reddit.subreddit("test")

Multiple subreddits can be combined and filtered views of r/all can also be used just like a subreddit:

reddit.subreddit("redditdev+learnpython+botwatch")
reddit.subreddit("all-redditdev-learnpython")
subreddits

An instance of Subreddits.

Provides the interface for Subreddit discovery. For example, to iterate over the set of default subreddits run:

for subreddit in reddit.subreddits.default(limit=None):
    print(subreddit)
user

An instance of User.

Provides the interface to the currently authorized Redditor. For example to get the name of the current user run:

print(reddit.user.me())
username_available(name: str) bool

Check to see if the username is available.

For example, to check if the username bboe is available, try:

reddit.username_available("bboe")
property validate_on_submit: bool

Get validate_on_submit.

Deprecated since version 7.0: If property validate_on_submit is set to False, the behavior is deprecated by Reddit. This attribute will be removed around May-June 2020.

reddit.live

class praw.models.DraftHelper(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Provide a set of functions to interact with Draft instances.

Note

The methods provided by this class will only work on the currently authenticated user’s Drafts.

__call__(draft_id: Optional[str] = None) Union[List[praw.models.Draft], praw.models.Draft]

Return a list of Draft instances.

Parameters

draft_id – When provided, return Draft instance (default: None).

Returns

A Draft instance if draft_id is provided. Otherwise, a list of Draft objects.

Note

Drafts fetched using a specific draft ID are lazily loaded, so you might have to access an attribute to get all the expected attributes.

This method can be used to fetch a specific draft by ID, like so:

draft_id = "124862bc-e1e9-11eb-aa4f-e68667a77cbb"
draft = reddit.drafts(draft_id)
print(draft)
__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

create(*, flair_id: Optional[str] = None, flair_text: Optional[str] = None, is_public_link: bool = False, nsfw: bool = False, original_content: bool = False, selftext: Optional[str] = None, send_replies: bool = True, spoiler: bool = False, subreddit: Optional[Union[str, praw.models.Subreddit, praw.models.UserSubreddit]] = None, title: Optional[str] = None, url: Optional[str] = None, **draft_kwargs) praw.models.Draft

Create a new Draft.

Parameters
  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • is_public_link – Whether to enable public viewing of the draft before it is submitted (default: False).

  • nsfw – Whether the draft should be marked NSFW (default: False).

  • original_content – Whether the submission should be marked as original content (default: False).

  • selftext – The Markdown formatted content for a text submission draft. Use None to make a title-only submission draft (default: None). selftext can not be provided if url is provided.

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

  • subreddit – The subreddit to create the draft for. This accepts a subreddit display name, Subreddit object, or UserSubreddit object. If None, the UserSubreddit of currently authenticated user will be used (default: None).

  • title – The title of the draft (default: None).

  • url – The URL for a link submission draft (default: None). url can not be provided if selftext is provided.

Additional keyword arguments can be provided to handle new parameters as Reddit introduces them.

Returns

The new Draft object.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

reddit.front

class praw.models.Front(reddit: praw.Reddit)

Front is a Listing class that represents the front page.

__init__(reddit: praw.Reddit)

Initialize a Front instance.

best(**generator_kwargs: Union[str, int]) Iterator[praw.models.Submission]

Return a ListingGenerator for best items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

comments() CommentHelper

Provide an instance of CommentHelper.

For example, to output the author of the 25 most recent comments of r/test execute:

for comment in reddit.subreddit("test").comments(limit=25):
    print(comment.author)
controversial(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for controversial items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").controversial(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").controversial(
    time_filter="day"
)
reddit.redditor("spez").controversial(time_filter="month")
reddit.redditor("spez").comments.controversial(time_filter="year")
reddit.redditor("spez").submissions.controversial(time_filter="all")
reddit.subreddit("all").controversial(time_filter="hour")
gilded(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for gilded items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get gilded items in r/test:

for item in reddit.subreddit("test").gilded():
    print(item.id)
hot(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for hot items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").hot()
reddit.multireddit(redditor="samuraisam", name="programming").hot()
reddit.redditor("spez").hot()
reddit.redditor("spez").comments.hot()
reddit.redditor("spez").submissions.hot()
reddit.subreddit("all").hot()
new(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for new items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").new()
reddit.multireddit(redditor="samuraisam", name="programming").new()
reddit.redditor("spez").new()
reddit.redditor("spez").comments.new()
reddit.redditor("spez").submissions.new()
reddit.subreddit("all").new()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

random_rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for random rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get random rising submissions for r/test:

for submission in reddit.subreddit("test").random_rising():
    print(submission.title)
rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get rising submissions for r/test:

for submission in reddit.subreddit("test").rising():
    print(submission.title)
top(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for top items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").top(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").top(time_filter="day")
reddit.redditor("spez").top(time_filter="month")
reddit.redditor("spez").comments.top(time_filter="year")
reddit.redditor("spez").submissions.top(time_filter="all")
reddit.subreddit("all").top(time_filter="hour")

reddit.inbox

class praw.models.Inbox(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Inbox is a Listing class that represents the inbox.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

all(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Union[praw.models.Message, praw.models.Comment]]

Return a ListingGenerator for all inbox comments and messages.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To output the type and ID of all items available via this listing do:

for item in reddit.inbox.all(limit=None):
    print(repr(item))
collapse(items: List[praw.models.Message])

Mark an inbox message as collapsed.

Parameters

items – A list containing instances of Message.

Requests are batched at 25 items (reddit limit).

For example, to collapse all unread Messages, try:

from praw.models import Message

unread_messages = []
for item in reddit.inbox.unread(limit=None):
    if isinstance(item, Message):
        unread_messages.append(item)
reddit.inbox.collapse(unread_messages)
comment_replies(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Comment]

Return a ListingGenerator for comment replies.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To output the author of one request worth of comment replies try:

for reply in reddit.inbox.comment_replies():
    print(reply.author)
mark_all_read()

Mark all messages as read with just one API call.

Example usage:

reddit.inbox.mark_all_read()

Note

This method returns after Reddit acknowledges your request, instead of after the request has been fulfilled.

mark_read(items: List[Union[praw.models.Comment, praw.models.Message]])

Mark Comments or Messages as read.

Parameters

items – A list containing instances of Comment and/or Message to be marked as read relative to the authorized user’s inbox.

Requests are batched at 25 items (reddit limit).

For example, to mark all unread Messages as read, try:

from praw.models import Message

unread_messages = []
for item in reddit.inbox.unread(limit=None):
    if isinstance(item, Message):
        unread_messages.append(item)
reddit.inbox.mark_read(unread_messages)
mark_unread(items: List[Union[praw.models.Comment, praw.models.Message]])

Unmark Comments or Messages as read.

Parameters

items – A list containing instances of Comment and/or Message to be marked as unread relative to the authorized user’s inbox.

Requests are batched at 25 items (Reddit limit).

For example, to mark the first 10 items as unread try:

to_unread = list(reddit.inbox.all(limit=10))
reddit.inbox.mark_unread(to_unread)
mentions(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Comment]

Return a ListingGenerator for mentions.

A mention is Comment in which the authorized redditor is named in its body like u/spez.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to output the author and body of the first 25 mentions try:

for mention in reddit.inbox.mentions(limit=25):
    print(f"{mention.author}\\n{mention.body}\\n")
message(message_id: str) praw.models.Message

Return a Message corresponding to message_id.

Parameters

message_id – The base36 ID of a message.

For example:

message = reddit.inbox.message("7bnlgu")
messages(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Message]

Return a ListingGenerator for inbox messages.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to output the subject of the most recent 5 messages try:

for message in reddit.inbox.messages(limit=5):
    print(message.subject)
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

sent(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Message]

Return a ListingGenerator for sent messages.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to output the recipient of the most recent 15 messages try:

for message in reddit.inbox.sent(limit=15):
    print(message.dest)
stream(**stream_options: Union[str, int, Dict[str, str]]) Iterator[Union[praw.models.Message, praw.models.Comment]]

Yield new inbox items as they become available.

Items are yielded oldest first. Up to 100 historical items will initially be returned.

Keyword arguments are passed to stream_generator().

For example, to retrieve all new inbox items, try:

for item in reddit.inbox.stream():
    print(item)
submission_replies(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Comment]

Return a ListingGenerator for submission replies.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To output the author of one request worth of submission replies try:

for reply in reddit.inbox.submission_replies():
    print(reply.author)
uncollapse(items: List[praw.models.Message])

Mark an inbox message as uncollapsed.

Parameters

items – A list containing instances of Message.

Requests are batched at 25 items (reddit limit).

For example, to uncollapse all unread Messages, try:

from praw.models import Message

unread_messages = []
for item in reddit.inbox.unread(limit=None):
    if isinstance(item, Message):
        unread_messages.append(item)
reddit.inbox.uncollapse(unread_messages)
unread(*, mark_read: bool = False, **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Union[praw.models.Message, praw.models.Comment]]

Return a ListingGenerator for unread comments and messages.

Parameters

mark_read – Marks the inbox as read (default: False).

Note

This only marks the inbox as read not the messages. Use Inbox.mark_read() to mark the messages.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to output the author of unread comments try:

from praw.models import Comment

for item in reddit.inbox.unread(limit=None):
    if isinstance(item, Comment):
        print(item.author)

reddit.live

class praw.models.LiveHelper(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Provide a set of functions to interact with LiveThreads.

__call__(id: str) praw.models.LiveThread

Return a new lazy instance of LiveThread.

This method is intended to be used as:

livethread = reddit.live("ukaeu1ik4sw5")
Parameters

id – A live thread ID, e.g., ukaeu1ik4sw5.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

create(title: str, *, description: Optional[str] = None, nsfw: bool = False, resources: str = None) praw.models.LiveThread

Create a new LiveThread.

Parameters
  • title – The title of the new LiveThread.

  • description – The new LiveThread’s description.

  • nsfw – Indicate whether this thread is not safe for work (default: False).

  • resources – Markdown formatted information that is useful for the LiveThread.

Returns

The new LiveThread object.

info(ids: List[str]) Generator[praw.models.LiveThread, None, None]

Fetch information about each live thread in ids.

Parameters

ids – A list of IDs for a live thread.

Returns

A generator that yields LiveThread instances.

Live threads that cannot be matched will not be generated. Requests will be issued in batches for each 100 IDs.

Warning

Unlike Reddit.info(), the output of this method may not reflect the order of input.

Usage:

ids = ["3rgnbke2rai6hen7ciytwcxadi", "sw7bubeycai6hey4ciytwamw3a", "t8jnufucss07"]
for thread in reddit.live.info(ids):
    print(thread.title)
now() Optional[praw.models.LiveThread]

Get the currently featured live thread.

Returns

The LiveThread object, or None if there is no currently featured live thread.

Usage:

thread = reddit.live.now()  # LiveThread object or None
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

reddit.multireddit

class praw.models.MultiredditHelper(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Provide a set of functions to interact with multireddits.

__call__(*, name: str, redditor: Union[str, praw.models.Redditor]) praw.models.Multireddit

Return a lazy instance of Multireddit.

Parameters
  • name – The name of the multireddit.

  • redditor – A redditor name or Redditor instance who owns the multireddit.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

create(*, description_md: Optional[str] = None, display_name: str, icon_name: Optional[str] = None, key_color: Optional[str] = None, subreddits: Union[str, praw.models.Subreddit], visibility: str = 'private', weighting_scheme: str = 'classic') praw.models.Multireddit

Create a new Multireddit.

Parameters
  • display_name – The display name for the new multireddit.

  • subreddits – Subreddits to add to the new multireddit. Can be a list of either Subreddit instances or subreddit display names.

  • description_md – Description for the new multireddit, formatted in markdown.

  • icon_name – Can be one of: "art and design", "ask", "books", "business", "cars", "comics", "cute animals", "diy", "entertainment", "food and drink", "funny", "games", "grooming", "health", "life advice", "military", "models pinup", "music", "news", "philosophy", "pictures and gifs", "science", "shopping", "sports", "style", "tech", "travel", "unusual stories", "video", or None.

  • key_color – RGB hex color code of the form "#FFFFFF".

  • visibility – Can be one of: "hidden", "private", or "public" (default: "private").

  • weighting_scheme – Can be one of: "classic" or "fresh" (default: "classic").

Returns

The new Multireddit object.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

reddit.redditors

class praw.models.Redditors(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Redditors is a Listing class that provides various Redditor lists.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

new(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator for new Redditors.

Returns

Redditor profiles, which are a type of Subreddit.

Additional keyword arguments are passed in the initialization of ListingGenerator.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

partial_redditors(ids: Iterable[str]) Iterator[PartialRedditor]

Get user summary data by redditor IDs.

Parameters

ids – An iterable of redditor fullname IDs.

Returns

A iterator producing PartialRedditor objects.

Each ID must be prefixed with t2_.

Invalid IDs are ignored by the server.

popular(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator for popular Redditors.

Returns

Redditor profiles, which are a type of Subreddit.

Additional keyword arguments are passed in the initialization of ListingGenerator.

search(query: str, **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator of Redditors for query.

Parameters

query – The query string to filter Redditors by.

Returns

Redditors.

Additional keyword arguments are passed in the initialization of ListingGenerator.

stream(**stream_options: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Yield new Redditors as they are created.

Redditors are yielded oldest first. Up to 100 historical Redditors will initially be returned.

Keyword arguments are passed to stream_generator().

Returns

Redditor profiles, which are a type of Subreddit.

reddit.subreddit

class praw.models.SubredditHelper(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Provide a set of functions to interact with Subreddits.

__call__(display_name: str) praw.models.Subreddit

Return a lazy instance of Subreddit.

Parameters

display_name – The name of the subreddit.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

create(name: str, *, link_type: str = 'any', subreddit_type: str = 'public', title: Optional[str] = None, wikimode: str = 'disabled', **other_settings: Optional[str]) praw.models.Subreddit

Create a new Subreddit.

Parameters
  • name – The name for the new subreddit.

  • link_type – The types of submissions users can make. One of "any", "link", or "self" (default: "any").

  • subreddit_type – One of "archived", "employees_only", "gold_only", "gold_restricted", "private", "public", or "restricted" (default: "public").

  • title – The title of the subreddit. When None or "" use the value of name.

  • wikimode – One of "anyone", "disabled", or "modonly" (default: "disabled").

Any keyword parameters not provided, or set explicitly to None, will take on a default value assigned by the Reddit server.

See also

update() for documentation of other available settings.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

reddit.subreddits

class praw.models.Subreddits(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Subreddits is a Listing class that provides various subreddit lists.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

default(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator for default subreddits.

Additional keyword arguments are passed in the initialization of ListingGenerator.

gold(**generator_kwargs) Iterator[praw.models.Subreddit]

Alias for premium() to maintain backwards compatibility.

new(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator for new subreddits.

Additional keyword arguments are passed in the initialization of ListingGenerator.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

popular(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator for popular subreddits.

Additional keyword arguments are passed in the initialization of ListingGenerator.

premium(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator for premium subreddits.

Additional keyword arguments are passed in the initialization of ListingGenerator.

recommended(subreddits: List[Union[str, praw.models.Subreddit]], omit_subreddits: Optional[List[Union[str, praw.models.Subreddit]]] = None) List[praw.models.Subreddit]

Return subreddits recommended for the given list of subreddits.

Parameters
  • subreddits – A list of Subreddit instances and/or subreddit names.

  • omit_subreddits – A list of Subreddit instances and/or subreddit names to exclude from the results (Reddit’s end may not work as expected).

search(query: str, **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator of subreddits matching query.

Subreddits are searched by both their title and description.

Parameters

query – The query string to filter subreddits by.

Additional keyword arguments are passed in the initialization of ListingGenerator.

See also

search_by_name() to search by subreddit names

search_by_name(query: str, *, include_nsfw: bool = True, exact: bool = False) List[praw.models.Subreddit]

Return list of Subreddits whose names begin with query.

Parameters
  • query – Search for subreddits beginning with this string.

  • exact – Return only exact matches to query (default: False).

  • include_nsfw – Include subreddits labeled NSFW (default: True).

search_by_topic(query: str) List[praw.models.Subreddit]

Return list of Subreddits whose topics match query.

Parameters

query – Search for subreddits relevant to the search topic.

Note

As of 09/01/2020, this endpoint always returns 404.

stream(**stream_options: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Yield new subreddits as they are created.

Subreddits are yielded oldest first. Up to 100 historical subreddits will initially be returned.

Keyword arguments are passed to stream_generator().

reddit.user

class praw.models.User(reddit: praw.Reddit)

The User class provides methods for the currently authenticated user.

__init__(reddit: praw.Reddit)

Initialize an User instance.

This class is intended to be interfaced with through reddit.user.

blocked() List[praw.models.Redditor]

Return a RedditorList of blocked Redditors.

contributor_subreddits(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator of contributor Subreddits.

These are subreddits in which the user is an approved user.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print a list of the subreddits that you are an approved user in, try:

for subreddit in reddit.user.contributor_subreddits(limit=None):
    print(str(subreddit))
friends(*, user: Optional[Union[praw.models.Redditor, str]] = None) Union[List[praw.models.Redditor], praw.models.Redditor]

Return a RedditorList of friends or a Redditor in the friends list.

Parameters

user – Checks to see if you are friends with the redditor. Either an instance of Redditor or a string can be given.

Returns

A list of Redditors, or a single Redditor if user is specified. The Redditor instance(s) returned also has friend attributes.

Raises

An instance of RedditAPIException if you are not friends with the specified Redditor.

karma() Dict[praw.models.Subreddit, Dict[str, int]]

Return a dictionary mapping Subreddits to their karma.

The returned dict contains subreddits as keys. Each subreddit key contains a sub-dict that have keys for comment_karma and link_karma. The dict is sorted in descending karma order.

Note

Each key of the main dict is an instance of Subreddit. It is recommended to iterate over the dict in order to retrieve the values, preferably through dict.items().

me(*, use_cache: bool = True) Optional[praw.models.Redditor]

Return a Redditor instance for the authenticated user.

Parameters

use_cache – When True, and if this function has been previously called, returned the cached version (default: True).

Note

If you change the Reddit instance’s authorization, you might want to refresh the cached value. Prefer using separate Reddit instances, however, for distinct authorizations.

Deprecated since version 7.2: In read_only mode this method returns None. In PRAW 8 this method will raise ReadOnlyException when called in read_only mode. To operate in PRAW 8 mode, set the config variable praw8_raise_exception_on_me to True.

moderator_subreddits(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator subreddits that the user moderates.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print a list of the names of the subreddits you moderate, try:

for subreddit in reddit.user.moderator_subreddits(limit=None):
    print(str(subreddit))
multireddits() List[praw.models.Multireddit]

Return a list of Multireddits belonging to the user.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

pin(submission: praw.models.Submission, *, num: int = None, state: bool = True)

Set the pin state of a submission on the authenticated user’s profile.

Parameters
  • submission – An instance of Submission that will be pinned/unpinned.

  • num

    If specified, the slot in which the submission will be pinned into. If there is a submission already in the specified slot, it will be replaced. If None or there is not a submission in the specified slot, the first available slot will be used (default: None). If all slots are used the following will occur:

    • Old Reddit:

      1. The submission in the last slot will be unpinned.

      2. The remaining pinned submissions will be shifted down a slot.

      3. The new submission will be pinned in the first slot.

    • New Reddit:

      1. The submission in the first slot will be unpinned.

      2. The remaining pinned submissions will be shifted up a slot.

      3. The new submission will be pinned in the last slot.

    Note

    At the time of writing (10/22/2021), there are 4 pin slots available and pins are in reverse order on old Reddit. If num is an invalid value, Reddit will ignore it and the same behavior will occur as if num is None.

  • stateTrue pins the submission, False unpins (default: True).

Raises

prawcore.BadRequest when pinning a removed or deleted submission.

Raises

prawcore.Forbidden when pinning a submission the authenticated user is not the author of.

submission = next(reddit.user.me().submissions.new())
reddit.user.pin(submission)
preferences() praw.models.Preferences

Get an instance of Preferences.

The preferences can be accessed as a dict like so:

preferences = reddit.user.preferences()
print(preferences["show_link_flair"])

Preferences can be updated via:

reddit.user.preferences.update(show_link_flair=True)

The Preferences.update() method returns the new state of the preferences as a dict, which can be used to check whether a change went through. Changes with invalid types or parameter names fail silently.

original_preferences = reddit.user.preferences()
new_preferences = reddit.user.preferences.update(invalid_param=123)
print(original_preferences == new_preferences)  # True, no change
subreddits(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Subreddit]

Return a ListingGenerator of Subreddits the user is subscribed to.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print a list of the subreddits that you are subscribed to, try:

for subreddit in reddit.user.subreddits(limit=None):
    print(str(subreddit))
trusted() List[praw.models.Redditor]

Return a RedditorList of trusted Redditors.

To display the usernames of your trusted users and the times at which you decided to trust them, try:

trusted_users = reddit.user.trusted()
for user in trusted_users:
    print(f"User: {user.name}, time: {user.date}")

Working with PRAW’s Models

Comment

class praw.models.Comment(reddit: praw.Reddit, id: Optional[str] = None, url: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

A class that represents a Reddit comment.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

author

Provides an instance of Redditor.

body

The body of the comment, as Markdown.

body_html

The body of the comment, as HTML.

created_utc

Time the comment was created, represented in Unix Time.

distinguished

Whether or not the comment is distinguished.

edited

Whether or not the comment has been edited.

id

The ID of the comment.

is_submitter

Whether or not the comment author is also the author of the submission.

link_id

The submission ID that the comment belongs to.

parent_id

The ID of the parent comment (prefixed with t1_). If it is a top-level comment, this returns the submission ID instead (prefixed with t3_).

permalink

A permalink for the comment. Comment objects from the inbox have a context attribute instead.

replies

Provides an instance of CommentForest.

saved

Whether or not the comment is saved.

score

The number of upvotes for the comment.

stickied

Whether or not the comment is stickied.

submission

Provides an instance of Submission. The submission that the comment belongs to.

subreddit

Provides an instance of Subreddit. The subreddit that the comment belongs to.

subreddit_id

The subreddit ID that the comment belongs to.

__init__(reddit: praw.Reddit, id: Optional[str] = None, url: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

Initialize a Comment instance.

award(*, gild_type: str = 'gid_2', is_anonymous: bool = True, message: str = None) dict

Award the author of the item.

Parameters
  • gild_type – Type of award to give. See table below for currently know global award types.

  • is_anonymous – If True, the authenticated user’s username will not be revealed to the recipient.

  • message – Message to include with the award.

Returns

A dict containing info similar to what is shown below:

{
    "subreddit_balance": 85260,
    "treatment_tags": [],
    "coins": 8760,
    "gildings": {"gid_1": 0, "gid_2": 1, "gid_3": 0},
    "awarder_karma_received": 4,
    "all_awardings": [
        {
            "giver_coin_reward": 0,
            "subreddit_id": None,
            "is_new": False,
            "days_of_drip_extension": 0,
            "coin_price": 75,
            "id": "award_9663243a-e77f-44cf-abc6-850ead2cd18d",
            "penny_donate": 0,
            "coin_reward": 0,
            "icon_url": "https://www.redditstatic.com/gold/awards/icon/SnooClappingPremium_512.png",
            "days_of_premium": 0,
            "icon_height": 512,
            "tiers_by_required_awardings": None,
            "icon_width": 512,
            "static_icon_width": 512,
            "start_date": None,
            "is_enabled": True,
            "awardings_required_to_grant_benefits": None,
            "description": "For an especially amazing showing.",
            "end_date": None,
            "subreddit_coin_reward": 0,
            "count": 1,
            "static_icon_height": 512,
            "name": "Bravo Grande!",
            "icon_format": "APNG",
            "award_sub_type": "PREMIUM",
            "penny_price": 0,
            "award_type": "global",
            "static_icon_url": "https://i.redd.it/award_images/t5_q0gj4/59e02tmkl4451_BravoGrande-Static.png",
        }
    ],
}

Warning

Requires the authenticated user to own Reddit Coins. Calling this method will consume Reddit Coins.

To award the gold award anonymously do:

comment = reddit.comment("dkk4qjd")
comment.award()

submission = reddit.submission("8dmv8z")
submission.award()

To award the platinum award with the message ‘Nice!’ and reveal your username to the recipient do:

comment = reddit.comment("dkk4qjd")
comment.award(gild_type="gild_3", message="Nice!", is_anonymous=False)

submission = reddit.submission("8dmv8z")
submission.award(gild_type="gild_3", message="Nice!", is_anonymous=False)

This is a list of known global awards (as of 11/08/2021)

Name

Icon

Gild Type

Description

Cost

Silver

https://www.redditstatic.com/gold/awards/icon/silver_64.png

gid_1

Shows the Silver Award… and that’s it.

100

Gold

https://www.redditstatic.com/gold/awards/icon/gold_64.png

gid_2

Gives 100 Reddit Coins and a week of r/lounge access and ad-free browsing.

500

Platinum

https://www.redditstatic.com/gold/awards/icon/platinum_64.png

gid_3

Gives 700 Reddit Coins and a month of r/lounge access and ad-free browsing.

1800

LOVE!

https://preview.redd.it/award_images/t5_22cerq/j3azv69qjfn51_LOVE.png?width=64&height=64&crop=smart&auto=webp&s=405d338bf34818596ab84bc26a09316917def8bb

award_5eac457f-ebac-449b-93a7-eb17b557f03c

When you follow your heart, love is the answer

20

Starstruck

https://www.redditstatic.com/gold/awards/icon/Starstruck_64.png

award_abb865cf-620b-4219-8777-3658cf9091fb

Can’t stop seeing stars

20

All-Seeing Upvote

https://www.redditstatic.com/gold/awards/icon/Illuminati_64.png

award_b4ff447e-05a5-42dc-9002-63568807cfe6

A glowing commendation for all to see

30

Narwhal Salute

https://preview.redd.it/award_images/t5_22cerq/80j20o397jj41_NarwhalSalute.png?width=64&height=64&crop=smart&auto=webp&s=8629e84ef3188ad75ebca713afb4a0f97e4c3c70

award_a2506925-fc82-4d6c-ae3b-b7217e09d7f0

A golden splash of respect

30

Wholesome Seal of Approval

https://preview.redd.it/award_images/t5_22cerq/b9ks3a5k7jj41_WholesomeSealofApproval.png?width=64&height=64&crop=smart&auto=webp&s=2bcedd41a51b17ff305fc0ec6eb7c5a631a90c60

award_c4b2e438-16bb-4568-88e7-7893b7662944

A glittering stamp for a feel-good thing

30

Ally

https://preview.redd.it/award_images/t5_22cerq/5nswjpyy44551_Ally.png?width=64&height=64&crop=smart&auto=webp&s=655fb8310589a3964a82ac0e56d016eb97aa6d4d

award_69c94eb4-d6a3-48e7-9cf2-0f39fed8b87c

Listen, get educated, and get involved.

50

Take My Energy

https://preview.redd.it/award_images/t5_q0gj4/p4yzxkaed5f61_oldtakemyenergy.png?width=64&height=64&crop=smart&auto=webp&s=f44a28b9ebe879e1be2936e9f6290044237dd458

award_02d9ab2c-162e-4c01-8438-317a016ed3d9

I’m in this with you.

50

Wearing is Caring

https://preview.redd.it/award_images/t5_q0gj4/9auzllkyd5f61_oldwearing.png?width=64&height=64&crop=smart&auto=webp&s=115ba4ee4036317efebfc53d25f11e7f055ab435

award_80d4d339-95d0-43ac-b051-bc3fe0a9bab8

Keep the community and yourself healthy and happy.

50

Facepalm

https://preview.redd.it/award_images/t5_22cerq/ey2iodron2s41_Facepalm.png?width=64&height=64&crop=smart&auto=webp&s=9d3c8e8642dc97c655867ea5ba37b7d76d653203

award_b1b44fa1-8179-4d84-a9ed-f25bb81f1c5f

Lowers face into palm

70

Snek

https://preview.redd.it/award_images/t5_22cerq/rc5iesz2z8t41_Snek.png?width=64&height=64&crop=smart&auto=webp&s=2856d19d59c0af0d38fd0b6058622f6a1e91956a

award_99d95969-6100-45b2-b00c-0ec45ae19596

A smol, delicate danger noodle.

70

Tree Hug

https://preview.redd.it/award_images/t5_22cerq/fukjtec638u41_TreeHug.png?width=64&height=64&crop=smart&auto=webp&s=b46d14cae99b5519775167d0aea8418c480c28c0

award_b92370bb-b7de-4fb3-9608-c5b4a22f714a

Show nature some love.

70

Bravo Grande!

https://www.redditstatic.com/gold/awards/icon/SnooClappingPremium_64.png

award_9663243a-e77f-44cf-abc6-850ead2cd18d

For an especially amazing showing.

75

Party Train

https://www.redditstatic.com/gold/awards/icon/Train/Train_silver_64.png

award_75f9bc56-eba3-4988-a1af-aec974404a0b

All aboard! Every five Party Train Awards gives the author 100 Reddit Coins and a week of r/lounge access and ad-free browsing. Rack up the awards and watch the train level-up!

75

Take My Power

https://www.redditstatic.com/gold/awards/icon/TakeMyPower_64.png

award_92cb6518-a71a-4217-9f8f-7ecbd7ab12ba

Add my power to yours.

75

Defeated

https://preview.redd.it/award_images/t5_22cerq/ooo0r2cq7q161_Defeated.png?width=64&height=64&crop=smart&auto=webp&s=bdbc2e8cd019294341e37330ce8f58c781b85b14

award_58ef8551-8c27-4f03-afa5-748432194e3d

The process of taking a painful L

80

Hugz

https://preview.redd.it/award_images/t5_q0gj4/ks45ij6w05f61_oldHugz.png?width=64&height=64&crop=smart&auto=webp&s=899f5a3267bb4d959f0a3b32be5b48975c681261

award_8352bdff-3e03-4189-8a08-82501dd8f835

Everything is better with a good hug

80

‘MURICA

https://preview.redd.it/award_images/t5_22cerq/18mwqw5th9e51_MURICA.png?width=64&height=64&crop=smart&auto=webp&s=759d235c371d6ae8ad5efb1c98a74b259a3ff8fe

award_869d4135-8738-41e5-8630-de593b4f049f

Did somebody say ‘Murica?

100

Burning Cash

https://preview.redd.it/award_images/t5_22cerq/kqr00h8b7q161_BurningCash.png?width=64&height=64&crop=smart&auto=webp&s=dc1435c6da0830e82e4eee74ebc0b1ac20a5cc73

award_abcdefe4-c92f-4c66-880f-425962d17098

I don’t need it, I don’t even necessarily want it, but I’ve got some cash to burn so I’m gonna get it.

100

Dread

https://preview.redd.it/award_images/t5_22cerq/nvfe4gyawnf51_Dread.png?width=64&height=64&crop=smart&auto=webp&s=34247d8bba8dc5aa7eaed6e81135da0c935d37f3

award_81cf5c92-8500-498c-9c94-3e4034cece0a

Staring into the abyss and it’s staring right back

100

Evil Cackle

https://preview.redd.it/award_images/t5_22cerq/43zl6dfcg9e51_EvilCackle.png?width=64&height=64&crop=smart&auto=webp&s=bd7d6c66b7594ac91ff2d8a7d86340a0f49a153c

award_483d8e29-bbe5-404e-a09a-c2d7b16c4fff

Laugh like a supervillain

100

Glow Up

https://preview.redd.it/award_images/t5_22cerq/2754pa5jvsj51_GlowUp.png?width=64&height=64&crop=smart&auto=webp&s=60f710eccc52d9d05db204bb2b962372a1e45671

award_01178870-6a4f-4172-8f36-9ed5092ee4f9

You look amazing, glowing, incredible!

100

Heartwarming

https://preview.redd.it/award_images/t5_22cerq/v1mxw8i6wnf51_Heartwarming.png?width=64&height=64&crop=smart&auto=webp&s=c09f506dc0be92c9849ee7dd2cfe9d65852d6064

award_19860e30-3331-4bac-b3d1-bd28de0c7974

I needed this today

100

I am disappoint

https://preview.redd.it/award_images/t5_q0gj4/4samff1ud5f61_olddisappoint.png?width=64&height=64&crop=smart&auto=webp&s=874f513220a74b960d64fd560b8213579df2c6e3

award_03c4f93d-efc7-463b-98a7-c01814462ab0

I’m not mad, I’m just disappointed.

100

I’ll Drink to That

https://preview.redd.it/award_images/t5_22cerq/45aeu8mzvsj51_IllDrinktoThat.png?width=64&height=64&crop=smart&auto=webp&s=94580e58d47d0a1eb1c6cc776437c574b5bbad7c

award_3267ca1c-127a-49e9-9a3d-4ba96224af18

Let’s sip to good health and good company

100

Keep Calm

https://preview.redd.it/award_images/t5_22cerq/g77c4oud7hb51_KeepCalm.png?width=64&height=64&crop=smart&auto=webp&s=9510d2496464d0fa8ff2288e1f0e17f114226383

award_1da6ff27-7c0d-4524-9954-86e5cda5fcac

Stop, chill, relax

100

Kiss

https://preview.redd.it/award_images/t5_22cerq/sb42u5gmwsj51_Kiss.png?width=64&height=64&crop=smart&auto=webp&s=12e56d5bba8f00fe467d3efe0c962e70bcbc92ed

award_1e516e18-cbee-4668-b338-32d5530f91fe

You deserve a smooch

100

Lawyer Up

https://preview.redd.it/award_images/t5_22cerq/iq0sgwn5bzy41_LawyerUp.png?width=64&height=64&crop=smart&auto=webp&s=3baf45de6ba3e1535df885b91a2aa714e5ece9d5

award_ae89e420-c4a5-47b8-a007-5dacf1c0f0d4

OBJECTION!

100

Masterpiece

https://preview.redd.it/award_images/t5_22cerq/2juh333m40n51_Masterpiece.png?width=64&height=64&crop=smart&auto=webp&s=0183ad39a56ba3e46c4bcb5d8938392f75d5d9d5

award_b4072731-c0fb-4440-adc7-1063d6a5e6a0

C’est magnifique

100

Shocked

https://preview.redd.it/award_images/t5_22cerq/fck3iedi2ug51_Shocked.png?width=64&height=64&crop=smart&auto=webp&s=627fbd255cb9cce5b72551255cb061bf0c8af71a

award_fbe9527a-adb3-430e-af1a-5fd3489e641b

I’m genuinely flabbergasted.

100

Tearing Up

https://preview.redd.it/award_images/t5_22cerq/lop66ut2wnf51_TearingUp.png?width=64&height=64&crop=smart&auto=webp&s=a6ee8b3c876bdc7a022072134f8157a7ea85d884

award_43f3bf99-92d6-47ab-8205-130d26e7929f

This hits me right in the feels

100

Yummy

https://preview.redd.it/award_images/t5_22cerq/a7dhg27hvnf51_Yummy.png?width=64&height=64&crop=smart&auto=webp&s=7a70c563dbc8bb2659271ddd451c8e657f3a3aa8

award_ae7f17fb-6538-4c75-9ff4-5f48b4cdaa94

That looks so good

100

Faith In Humanity Restored

https://www.redditstatic.com/gold/awards/icon/Faith_in_Humanity_Restored_64.png

award_611ff347-196b-4a14-ad4b-0076f2d8f9d2

This goes a long way to restore my faith in the people of Earth

125

Wholesome

https://preview.redd.it/award_images/t5_22cerq/5izbv4fn0md41_Wholesome.png?width=64&height=64&crop=smart&auto=webp&s=89a077c4955b50fa2e57449eebf8c19e7f23ceb7

award_5f123e3d-4f48-42f4-9c11-e98b566d5897

When you come across a feel-good thing.

125

Beating Heart

https://www.redditstatic.com/gold/awards/icon/Beating_Heart_64.png

award_0d762fb3-17e4-4477-ab6b-9770b71b493c

My valentine makes my heart beat out of my chest.

150

Bless Up

https://preview.redd.it/award_images/t5_22cerq/trfv6ems1md41_BlessUp.png?width=64&height=64&crop=smart&auto=webp&s=5e84fe0dae062adff22f01c384d86c0633d06b28

award_77ba55a2-c33c-4351-ac49-807455a80148

Prayers up for the blessed.

150

Buff Doge

https://preview.redd.it/award_images/t5_22cerq/zc4a9vk5zmc51_BuffDoge.png?width=64&height=64&crop=smart&auto=webp&s=04b5cf5717304307515af46c73431f11bb66c3bd

award_c42dc561-0b41-40b6-a23d-ef7e110e739e

So buff, wow

150

Cake

https://www.redditstatic.com/gold/awards/icon/Animated_Cake_64.png

award_5fb42699-4911-42a2-884c-6fc8bdc36059

Did someone say… cake?

150

Helpful

https://preview.redd.it/award_images/t5_22cerq/klvxk1wggfd41_Helpful.png?width=64&height=64&crop=smart&auto=webp&s=cc59d3722210878a975f8d97eb62f3092e472693

award_f44611f1-b89e-46dc-97fe-892280b13b82

Thank you stranger. Shows the award.

150

I Shy

https://www.redditstatic.com/gold/awards/icon/I_shy_64.png

award_beccaae0-d745-44f9-bc5c-3c9f8117699b

No matter how hard I try, I’m too shy to confess my love!

150

Press F

https://preview.redd.it/award_images/t5_22cerq/tcofsbf92md41_PressF.png?width=64&height=64&crop=smart&auto=webp&s=b33bda0aa0310bbe1877ba2d02a259d7cc52d616

award_88fdcafc-57a0-48db-99cc-76276bfaf28b

To pay respects.

150

Take My Money

https://preview.redd.it/award_images/t5_22cerq/9jr8pv84v7i51_TakeMyMoney.png?width=64&height=64&crop=smart&auto=webp&s=8cae8bb3d91b20e0d13b24010a103842e365ff9f

award_a7f9cbd7-c0f1-4569-a913-ebf8d18de00b

I’m buying what you’re selling

150

2020 Veteran

https://preview.redd.it/award_images/t5_22cerq/xg2lbwcwl8361_2020Veteran.png?width=64&height=64&crop=smart&auto=webp&s=4400e79710036c5cf364f44e3ebf7144968c51ee

award_f0875744-15da-41ee-8591-b88e5a88c430

A reward for making it through the most topsey- turvey year anyone can remember. Gives 100 coins to the recipient.

200

Baby Snoo

https://preview.redd.it/award_images/t5_22cerq/9nh7lk027g461_BabySnoo.png?width=64&height=64&crop=smart&auto=webp&s=81cebff5c3112628a508bb35bca3d3e02c3cf57f

award_4d880932-4b45-4723-a964-5d749ace4df2

Baby Snoo is back and cuter than ever

200

Giggle

https://www.redditstatic.com/gold/awards/icon/Giggle_64.png

award_e813313c-1002-49bf-ac37-e966710f605f

Innocent laughter

200

Got the W

https://preview.redd.it/award_images/t5_22cerq/9avdcwgupta41_GottheW.png?width=64&height=64&crop=smart&auto=webp&s=d7c1acaee0770a6a0ff7853606ba9992824cdcec

award_8dc476c7-1478-4d41-b940-f139e58f7756

200

I’d Like to Thank…

https://preview.redd.it/award_images/t5_22cerq/8ad2jffnclf41_Thanks.png?width=64&height=64&crop=smart&auto=webp&s=430fa4cf2928cc37ed0a3344c8da31277a53929c

award_1703f934-cf44-40cc-a96d-3729d0b48262

My kindergarten teacher, my cat, my mom, and you.

200

I’m Deceased

https://preview.redd.it/award_images/t5_22cerq/2jd92wtn25g41_ImDeceased.png?width=64&height=64&crop=smart&auto=webp&s=106ba80d6001af5b5b47b874b4f86da6ca88113f

award_b28d9565-4137-433d-bb65-5d4aa82ade4c

Call an ambulance, I’m laughing too hard.

200

Looking

https://preview.redd.it/award_images/t5_22cerq/kjpl76213ug51_Looking.png?width=64&height=64&crop=smart&auto=webp&s=5d6beac8304bc8fe28e0d6acb1b4b1339abecc67

award_4922c1be-3646-4d62-96ea-19a56798df51

I can’t help but look.

200

Lurking

https://www.redditstatic.com/gold/awards/icon/Lurking_64.png

award_59ae34c0-14c8-4b16-a527-e157fac0a6c7

Just seeing what’s going on

200

Plus One

https://preview.redd.it/award_images/t5_22cerq/6vgr8y21i9741_PlusOne.png?width=64&height=64&crop=smart&auto=webp&s=ecea37cb71525e80d9ca2dbf2bd504b9f934606e

award_f7562045-905d-413e-9ed2-0a16d4bfe349

You officially endorse and add your voice to the crowd.

200

Sidevote

https://www.redditstatic.com/gold/awards/icon/side_vote_64.png

award_cd297f1a-8368-4f5a-acb8-6ec96fc6e8d6

Not an upvote, not a downvote, just an in-the- middle sidevote.

200

Stone Face

https://preview.redd.it/award_images/t5_22cerq/x1o2hnh9ywq71_StoneFace.png?width=64&height=64&crop=smart&auto=webp&s=657879ff853f573b0ec3fab4a0a568d77ef9562e

award_2c3bb816-f6fc-46e8-aaf7-2b196afffada

You got me stone faced

200

Stonks Falling

https://preview.redd.it/award_images/t5_22cerq/ree13odobef41_StonksFalling.png?width=64&height=64&crop=smart&auto=webp&s=b1016427b3550d229b4ec93437ac8b69c28c5ae2

award_9ee30a8f-463e-4ef7-9da9-a09f270ec026

Losing value fast.

200

Stonks Rising

https://preview.redd.it/award_images/t5_22cerq/s5edqq9abef41_StonksRising.png?width=64&height=64&crop=smart&auto=webp&s=8c11db37505feb2a3e4130eb15e9470e72e65b63

award_d125d124-5c03-490d-af3d-d07c462003da

To the MOON.

200

1UP

https://www.redditstatic.com/gold/awards/icon/Levelup_64.png

award_11be92ba-509e-46d3-991b-593239006521

Extra life

250

Are You Serious?

https://www.redditstatic.com/gold/awards/icon/are_you_serious_64.png

award_ca888c60-cd8c-4875-97f1-b536dc35a9a5

Are you being serious right now?

250

Are You Winning?

https://www.redditstatic.com/gold/awards/icon/AreYouWinSon_64.png

award_5641bae4-e690-4832-a498-4bd78da8b2b1

Well, are you?

250

Awesome Answer

https://preview.redd.it/award_images/t5_22cerq/71v56o5a5v541_AwesomeAnswer.png?width=64&height=64&crop=smart&auto=webp&s=a6c7ee017a2cbab3e291b81823eb179faeb96b99

award_2adc49e8-d6c9-4923-9293-2bfab1648569

For a winning take and the kind soul who nails a question. Gives %{coin_symbol}100 Coins to both the author and the community.

250

Big Brain Time

https://www.redditstatic.com/gold/awards/icon/Big_Brain_Time_64.png

award_e71deb9c-a466-4743-9a73-48771c000077

2000 IQ

250

Calculating

https://www.redditstatic.com/gold/awards/icon/calculating_b_64.png

award_242c4f2c-6f1c-4387-9b5b-d0249d6ecd36

Something isn’t adding up

250

Confetti

https://www.redditstatic.com/gold/awards/icon/ConfettiBall_64.png

award_1671746c-49e2-4cdd-be4e-ec8892434278

Party time, shower them with sparkly paper

250

Doom

https://www.redditstatic.com/gold/awards/icon/2Dread_64.png

award_e03a0c52-56b5-45df-bd6f-5f2da10cfdc5

A sense of impending doom

250

Duck Dance

https://www.redditstatic.com/gold/awards/icon/DuckDance_64.png

award_c3e02835-9444-4a7f-9e7f-206e8bf0ed99

He do be dancing though

250

Endless Coolness

https://www.redditstatic.com/gold/awards/icon/EndlessCoolness_64.png

award_aac76dbe-2272-4fad-ac06-c077d2d9049e

Cool to the infinity

250

It’s Cute!

https://preview.redd.it/award_images/t5_22cerq/n94bgm83in941_ItsCute.png?width=64&height=64&crop=smart&auto=webp&s=2632d9c9236d0501427072373b789fdb5a59377a

award_cc540de7-dfdb-4a68-9acf-6f9ce6b17d21

You made me UwU.

250

Laser Eyes

https://www.redditstatic.com/gold/awards/icon/emotional_fatality_64.png

award_e1ed6fb9-f23e-4cb4-aad9-70c83e4b1924

250

Mind Blown

https://preview.redd.it/award_images/t5_22cerq/wa987k0p4v541_MindBlown.png?width=64&height=64&crop=smart&auto=webp&s=5bcf973d6d2b64223cc5a2995c95b797bcf68dd2

award_9583d210-a7d0-4f3c-b0c7-369ad579d3d4

When a thing immediately combusts your brain. Gives %{coin_symbol}100 Coins to both the author and the community.

250

Original

https://preview.redd.it/award_images/t5_22cerq/b8xt4z8yajz31_Original.png?width=64&height=64&crop=smart&auto=webp&s=8ca70e1f45c2ddca559d456a74798fcedf36427e

award_d306c865-0d49-4a36-a1ab-a4122a0e3480

When something new and creative wows you. Gives %{coin_symbol}100 Coins to both the author and the community.

250

Pranked!

https://www.redditstatic.com/gold/awards/icon/Pranked_64.png

award_e2250c69-8bd9-4e2f-8fb7-e6630e6c5c8a

Cake direct to face

250

Respect

https://www.redditstatic.com/gold/awards/icon/Respect_64.png

award_c8503d66-6450-40c5-963f-35ced99bd361

Tip of my hat to you

250

That Smile

https://www.redditstatic.com/gold/awards/icon/That_Smile_64.png

award_e11fc833-31fe-4c43-bde8-aead928b4b70

Cute but creepy

250

Timeless Beauty

https://www.redditstatic.com/gold/awards/icon/Timeless_64.png

award_31260000-2f4a-4b40-ad20-f5aa46a577bf

Beauty that’s forever. Gives %{coin_symbol}100 Coins each to the author and the community.

250

Today I Learned

https://preview.redd.it/award_images/t5_22cerq/bph2png4ajz31_TodayILearned.png?width=64&height=64&crop=smart&auto=webp&s=0dec60a8d3226978d4b824226b0c864b663293b3

award_a67d649d-5aa5-407e-a98b-32fd9e3a9696

The more you know… Gives %{coin_symbol}100 Coins to both the author and the community.

250

Vibing

https://www.redditstatic.com/gold/awards/icon/Vibing_64.png

award_3f4e6f36-dacc-4919-b170-9d0201cd258f

I’m catching the vibration

250

Wink Wink

https://www.redditstatic.com/gold/awards/icon/Wink_wink_64.png

award_a8196b8f-1a76-4902-b324-b9473854dade

nudge, nudge

250

Woah Dude

https://www.redditstatic.com/gold/awards/icon/Woah_dude_64.png

award_d88c5520-18d0-4ef0-9a36-41f8617584b0

Sometimes you’re left just going WOAH…

250

Yas Queen

https://preview.redd.it/award_images/t5_22cerq/kthj3e4h3bm41_YasQueen.png?width=64&height=64&crop=smart&auto=webp&s=98b385524aee26412e9dcf25bd20b4cff0eb2376

award_d48aad4b-286f-4a3a-bb41-ec05b3cd87cc

YAAAAAAAAAAASSS.

250

You Dropped This

https://www.redditstatic.com/gold/awards/icon/YouDroppedThis_64.png

award_92d8645c-de2c-44ae-8cd7-7b0c6ab25297

King

250

hehehehe

https://www.redditstatic.com/gold/awards/icon/hehehe_b_64.png

award_435a5692-f508-4b31-8083-ddc576f26ad3

That’s a little funny

250

Blow a Kiss

https://www.redditstatic.com/gold/awards/icon/blow_a_kiss_64.png

award_9ef35273-7942-4199-a76a-3d37f3b52a2e

smooch

300

Coin Gift

https://preview.redd.it/award_images/t5_22cerq/cr1mq4yysv541_CoinGift.png?width=64&height=64&crop=smart&auto=webp&s=d39d0850925a193c9f2ca8203243c694d15fb40a

award_3dd248bc-3438-4c5b-98d4-24421fd6d670

Give the gift of %{coin_symbol}250 Reddit Coins.

300

Crab Rave

https://www.redditstatic.com/gold/awards/icon/CrabRave_64.png

award_f7a4fd5e-7cd1-4c11-a1c9-c18d05902e81

[Happy crab noises]

300

GOAT

https://preview.redd.it/award_images/t5_22cerq/x52x5be57fd41_GOAT.png?width=64&height=64&crop=smart&auto=webp&s=d8a0ff8871eeebadc700284d0186073b8e56ac58

award_cc299d65-77de-4828-89de-708b088349a0

Historical anomaly - greatest in eternity.

300

Heartbreak

https://www.redditstatic.com/gold/awards/icon/heart_break_64.png

award_dc85c1f3-b5aa-4970-9a5d-40304252f79e

Suffering from a broken heart

300

Rocket Like

https://preview.redd.it/award_images/t5_q0gj4/35d17tf5e5f61_oldrocketlike.png?width=64&height=64&crop=smart&auto=webp&s=18520df8e628283caffe872837932b34ff675c8f

award_28e8196b-d4e9-45bc-b612-cd4c7d3ed4b3

When an upvote just isn’t enough, smash the Rocket Like.

300

Table Flip

https://preview.redd.it/award_images/t5_22cerq/a05z7bb9v7i51_TableFlip.png?width=64&height=64&crop=smart&auto=webp&s=3efc978414612ce3b518813a124501b8a204e56b

award_3e000ecb-c1a4-49dc-af14-c8ac2029ca97

ARGH!

300

This

https://preview.redd.it/award_images/t5_22cerq/vu6om0xnb7e41_This.png?width=64&height=64&crop=smart&auto=webp&s=4b2a7c5439da6b4a9e2173bbf3cf9a610538600d

award_68ba1ee3-9baf-4252-be52-b808c1e8bdc4

THIS right here! Join together to give multiple This awards and see the award evolve in its display and shower benefits for the recipient. For every 3 This awards given to a post or comment, the author will get 250 coins.

300

Updoot

https://preview.redd.it/award_images/t5_22cerq/7atjjqpy1mc41_Updoot.png?width=64&height=64&crop=smart&auto=webp&s=f07dcd6402653b86d321cff6ded773cfa13d918a

award_725b427d-320b-4d02-8fb0-8bb7aa7b78aa

Sometimes you just got to doot.

300

Wait What?

https://www.redditstatic.com/gold/awards/icon/wait_what_64.png

award_a3b7d374-68b4-4c77-8a57-e11fd6f26c06

Hold up, what was that?

300

Spit-take

https://www.redditstatic.com/gold/awards/icon/Spits_drink_64.png

award_3409a4c0-ba69-43a0-be9f-27bc27c159cc

Shower them with laughs

325

Super Heart Eyes

https://www.redditstatic.com/gold/awards/icon/Superheart_64.png

award_6220ecfe-4552-4949-aa13-fb1fb7db537c

When the love is out of control.

325

Table Slap

https://www.redditstatic.com/gold/awards/icon/TableSlap_64.png

award_9f928aff-c9f5-4e7e-aa91-8619dce60f1c

When laughter meets percussion

325

To The Stars

https://www.redditstatic.com/gold/awards/icon/Rocket_64.png

award_2bc47247-b107-44a8-a78c-613da21869ff

Boldly go where we haven’t been in a long, long time.

325

Into the Magic Portal

https://www.redditstatic.com/gold/awards/icon/TeleportIn_64.png

award_2ff1fdd0-ff73-47e6-a43c-bde6d4de8fbd

Hope to make it to the other side.

350

Out of the Magic Portal

https://www.redditstatic.com/gold/awards/icon/TeleportOut_64.png

award_7fe72f36-1141-4a39-ba76-0d481889b390

That was fun, but I’m glad to be back

350

Bravo!

https://www.redditstatic.com/gold/awards/icon/SnooClapping_64.png

award_84276b1e-cc8f-484f-a19c-be6c09adc1a5

An amazing showing.

400

Doot 🎵 Doot

https://www.redditstatic.com/gold/awards/icon/Updoot_64.png

award_5b39e8fd-7a58-4cbe-8ca0-bdedd5ed1f5a

Sometimes you just got to dance with the doots.

400

Bless Up (Pro)

https://preview.redd.it/award_images/t5_22cerq/xe5mw55w5v541_BlessUp.png?width=64&height=64&crop=smart&auto=webp&s=54b7d71c74cf41fc8ada4a2110babf8b68d2f172

award_43c43a35-15c5-4f73-91ef-fe538426435a

Prayers up for the blessed. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Brighten My Day

https://www.redditstatic.com/gold/awards/icon/Sunny_64.png

award_9591a26e-b2e4-4ef2-bed4-28ff69246691

The clouds part and the sun shines through. Use the Brighten My Day Award to highlight comments that are a ray of sunshine.

500

Eureka!

https://www.redditstatic.com/gold/awards/icon/Bulb_64.png

award_65f78ca2-45d8-4cb6-bf79-a67beadf2e47

Now that is a bright idea. Use the Eureka Award to highlight comments that are brilliant.

500

Heart Eyes

https://preview.redd.it/award_images/t5_22cerq/12kz7a7j4v541_HeartEyes.png?width=64&height=64&crop=smart&auto=webp&s=02bb7182aad468e16e0a711b594110225679c79e

award_a9009ea5-1a36-42ae-aab2-5967563ee054

For love at first sight. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Helpful (Pro)

https://www.redditstatic.com/gold/awards/icon/Animated_Helpful_64.png

award_2ae56630-cfe0-424e-b810-4945b9145358

Thank you stranger. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Made Me Smile

https://preview.redd.it/award_images/t5_22cerq/hwnbr9l67s941_MadeMeSmile.png?width=64&height=64&crop=smart&auto=webp&s=918705b3b6804a6151b6ce4f8b1c86dfa604a470

award_a7a04d6a-8dd8-41bb-b906-04fa8f144014

When you’re smiling before you know it. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Starry

https://www.redditstatic.com/gold/awards/icon/Starry_64.png

award_0e957fb0-c8f1-4ba1-a8ef-e1e524b60d7d

Use the Starry Award to highlight comments that deserve to stand out from the crowd.

500

Wholesome (Pro)

https://preview.redd.it/award_images/t5_22cerq/0o2j782f00e41_WholesomeSuperpro.png?width=64&height=64&crop=smart&auto=webp&s=2a04235b56e4fbc90106067bfe0d61bd60300c4f

award_1f0462ee-18f5-4f33-89cf-f1f79336a452

When you come across a feel-good thing. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Pot o’ Coins

https://www.redditstatic.com/gold/awards/icon/pot_o_coins_64.png

award_35c78e6e-507b-4f1d-b3d8-ed43840909a8

The treasure at the end of the rainbow. Gives the author 800 Coins to do with as they please.

1000

Argentium

https://www.redditstatic.com/gold/awards/icon/Mithril_64.png

award_4ca5a4e6-8873-4ac5-99b9-71b1d5161a91

Latin for distinguished, this award shimmers like silver and is stronger than steel. It’s for those who deserve outsized recognition. Gives 2,500 Reddit Coins and three months of r/lounge access and ad-free browsing.

20000

Ternion All-Powerful

https://www.redditstatic.com/gold/awards/icon/Trinity_64.png

award_2385c499-a1fb-44ec-b9b7-d260f3dc55de

Legendary level, this award is a no holds barred celebration of something that hits you in the heart, mind, and soul. Some might call it unachievanium. Gives 5,000 Reddit Coins and six months of r/lounge access and ad-free browsing.

50000

block()

Block the user who sent the item.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.block()

# or, identically:

comment.author.block()
clear_vote()

Clear the authenticated user’s vote on the object.

Note

Votes must be cast by humans. That is, API clients proxying a human’s action one-for-one are OK, but bots deciding how to vote on content or amplifying a human’s vote are not. See the reddit rules for more details on what constitutes vote manipulation. [Ref]

Example usage:

submission = reddit.submission("5or86n")
submission.clear_vote()

comment = reddit.comment("dxolpyc")
comment.clear_vote()
collapse()

Mark the item as collapsed.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox()

# select first inbox item and collapse it message = next(inbox)
message.collapse()

See also

uncollapse()

delete()

Delete the object.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.delete()

submission = reddit.submission("8dmv8z")
submission.delete()
disable_inbox_replies()

Disable inbox replies for the item.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.disable_inbox_replies()

submission = reddit.submission("8dmv8z")
submission.disable_inbox_replies()
downvote()

Downvote the object.

Note

Votes must be cast by humans. That is, API clients proxying a human’s action one-for-one are OK, but bots deciding how to vote on content or amplifying a human’s vote are not. See the reddit rules for more details on what constitutes vote manipulation. [Ref]

Example usage:

submission = reddit.submission("5or86n")
submission.downvote()

comment = reddit.comment("dxolpyc")
comment.downvote()

See also

upvote()

edit(body: str) Union[praw.models.Comment, praw.models.Submission]

Replace the body of the object with body.

Parameters

body – The Markdown formatted content for the updated object.

Returns

The current instance after updating its attributes.

Example usage:

comment = reddit.comment("dkk4qjd")

# construct the text of an edited comment
# by appending to the old body:
edited_body = comment.body + "Edit: thanks for the gold!"
comment.edit(edited_body)
enable_inbox_replies()

Enable inbox replies for the item.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.enable_inbox_replies()

submission = reddit.submission("8dmv8z")
submission.enable_inbox_replies()
property fullname: str

Return the object’s fullname.

A fullname is an object’s kind mapping like t3 followed by an underscore and the object’s base36 ID, e.g., t1_c5s96e0.

gild() dict

Alias for award() to maintain backwards compatibility.

static id_from_url(url: str) str

Get the ID of a comment from the full URL.

property is_root: bool

Return True when the comment is a top-level comment.

mark_read()

Mark a single inbox item as read.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox.unread()

for message in inbox:
    # process unread messages
    ...

See also

mark_unread()

To mark the whole inbox as read with a single network request, use Inbox.mark_all_read()

mark_unread()

Mark the item as unread.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox(limit=10)

for message in inbox:
    # process messages
    ...

See also

mark_read()

mod() praw.models.reddit.comment.CommentModeration

Provide an instance of CommentModeration.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.mod.approve()
parent() Union[Comment, praw.models.Submission]

Return the parent of the comment.

The returned parent will be an instance of either Comment, or Submission.

If this comment was obtained through a Submission, then its entire ancestry should be immediately available, requiring no extra network requests. However, if this comment was obtained through other means, e.g., reddit.comment("COMMENT_ID"), or reddit.inbox.comment_replies, then the returned parent may be a lazy instance of either Comment, or Submission.

Lazy comment example:

comment = reddit.comment("cklhv0f")
parent = comment.parent()
# 'replies' is empty until the comment is refreshed
print(parent.replies)  # Output: []
parent.refresh()
print(parent.replies)  # Output is at least: [Comment(id="cklhv0f")]

Warning

Successive calls to parent() may result in a network request per call when the comment is not obtained through a Submission. See below for an example of how to minimize requests.

If you have a deeply nested comment and wish to most efficiently discover its top-most Comment ancestor you can chain successive calls to parent() with calls to refresh() at every 9 levels. For example:

comment = reddit.comment("dkk4qjd")
ancestor = comment
refresh_counter = 0
while not ancestor.is_root:
    ancestor = ancestor.parent()
    if refresh_counter % 9 == 0:
        ancestor.refresh()
    refresh_counter += 1
print(f"Top-most Ancestor: {ancestor}")

The above code should result in 5 network requests to Reddit. Without the calls to refresh() it would make at least 31 network requests.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

refresh()

Refresh the comment’s attributes.

If using Reddit.comment() this method must be called in order to obtain the comment’s replies.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.refresh()
property replies: CommentForest

Provide an instance of CommentForest.

This property may return an empty list if the comment has not been refreshed with refresh()

Sort order and reply limit can be set with the reply_sort and reply_limit attributes before replies are fetched, including any call to refresh():

comment.reply_sort = "new"
comment.refresh()
replies = comment.replies

Note

The appropriate values for reply_sort include "confidence", "controversial", "new", "old", "q&a", and "top".

reply(body: str) Optional[Union[praw.models.Comment, praw.models.Message]]

Reply to the object.

Parameters

body – The Markdown formatted content for a comment.

Returns

A Comment or Message object for the newly created comment or message or None if Reddit doesn’t provide one.

Raises

prawcore.exceptions.Forbidden when attempting to reply to some items, such as locked submissions/comments or non-replyable messages.

A None value can be returned if the target is a comment or submission in a quarantined subreddit and the authenticated user has not opt-ed into viewing the content. When this happens the comment will be successfully created on Reddit and can be retried by drawing the comment from the user’s comment history.

Example usage:

submission = reddit.submission("5or86n")
submission.reply("reply")

comment = reddit.comment("dxolpyc")
comment.reply("reply")
report(reason: str)

Report this object to the moderators of its subreddit.

Parameters

reason – The reason for reporting.

Raises

RedditAPIException if reason is longer than 100 characters.

Example usage:

submission = reddit.submission("5or86n")
submission.report("report reason")

comment = reddit.comment("dxolpyc")
comment.report("report reason")
save(*, category: Optional[str] = None)

Save the object.

Parameters

category – The category to save to. If the authenticated user does not have Reddit Premium this value is ignored by Reddit (default: None).

Example usage:

submission = reddit.submission("5or86n")
submission.save(category="view later")

comment = reddit.comment("dxolpyc")
comment.save()

See also

unsave()

property submission: praw.models.Submission

Return the Submission object this comment belongs to.

unblock_subreddit()

Unblock a subreddit.

Note

This method pertains only to objects which were retrieved via the inbox.

For example, to unblock all blocked subreddits that you can find by going through your inbox:

from praw.models import SubredditMessage

subs = set()
for item in reddit.inbox.messages(limit=None):
    if isinstance(item, SubredditMessage):
        if (
            item.subject == "[message from blocked subreddit]"
            and str(item.subreddit) not in subs
        ):
            item.unblock_subreddit()
            subs.add(str(item.subreddit))
uncollapse()

Mark the item as uncollapsed.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox()

# select first inbox item and uncollapse it
message = next(inbox)
message.uncollapse()

See also

collapse()

unsave()

Unsave the object.

Example usage:

submission = reddit.submission("5or86n")
submission.unsave()

comment = reddit.comment("dxolpyc")
comment.unsave()

See also

save()

upvote()

Upvote the object.

Note

Votes must be cast by humans. That is, API clients proxying a human’s action one-for-one are OK, but bots deciding how to vote on content or amplifying a human’s vote are not. See the reddit rules for more details on what constitutes vote manipulation. [Ref]

Example usage:

submission = reddit.submission("5or86n")
submission.upvote()

comment = reddit.comment("dxolpyc")
comment.upvote()

See also

downvote()

Draft

class praw.models.Draft(reddit: praw.Reddit, id: Optional[str] = None, _data: Dict[str, Any] = None)

A class that represents a Reddit submission draft.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

link_flair_template_id

The link flair’s ID.

link_flair_text

The link flair’s text content, or None if not flaired.

modified

Time the submission draft was modified, represented in Unix Time.

original_content

Whether the submission draft will be set as original content.

selftext

The submission draft’s selftext. None if a link submission draft.

spoiler

Whether the submission will be marked as a spoiler.

subreddit

Provides an instance of Subreddit or UserSubreddit (if set).

title

The title of the submission draft.

url

The URL the submission draft links to.

__init__(reddit: praw.Reddit, id: Optional[str] = None, _data: Dict[str, Any] = None)

Initialize a Draft instance.

delete()

Delete the Draft.

Example usage:

draft = reddit.drafts("124862bc-e1e9-11eb-aa4f-e68667a77cbb")
draft.delete()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

submit(*, flair_id: Optional[str] = None, flair_text: Optional[str] = None, nsfw: Optional[bool] = None, selftext: Optional[str] = None, spoiler: Optional[bool] = None, subreddit: Optional[Union[str, praw.models.Subreddit, praw.models.UserSubreddit]] = None, title: Optional[str] = None, url: Optional[str] = None, **submit_kwargs) praw.models.Submission

Submit a draft.

Parameters
  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • nsfw – Whether or not the submission should be marked NSFW (default: None).

  • selftext – The Markdown formatted content for a text submission. Use an empty string, "", to make a title-only submission (default: None).

  • spoiler – Whether or not the submission should be marked as a spoiler (default: None).

  • subreddit – The subreddit to submit the draft to. This accepts a subreddit display name, Subreddit object, or UserSubreddit object.

  • title – The title of the submission (default: None).

  • url – The URL for a link submission (default: None).

Returns

A Submission object for the newly created submission.

Note

Parameters set here will override their respective Draft attributes.

Additional keyword arguments are passed to the Subreddit.submit() method.

For example, to submit a draft as is:

draft = reddit.drafts("5f87d55c-e4fb-11eb-8965-6aeb41b0880e")
submission = draft.submit()

For example, to submit a draft but use a different title than what is set:

draft = reddit.drafts("5f87d55c-e4fb-11eb-8965-6aeb41b0880e")
submission = draft.submit(title="New Title")

See also

update(*, flair_id: Optional[str] = None, flair_text: Optional[str] = None, is_public_link: Optional[bool] = None, nsfw: Optional[bool] = None, original_content: Optional[bool] = None, selftext: Optional[str] = None, send_replies: Optional[bool] = None, spoiler: Optional[bool] = None, subreddit: Optional[Union[str, praw.models.Subreddit, praw.models.UserSubreddit]] = None, title: Optional[str] = None, url: Optional[str] = None, **draft_kwargs)

Update the Draft.

Note

Only provided values will be updated.

Parameters
  • flair_id – The flair template to select.

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text. flair_id is required when flair_text is provided.

  • is_public_link – Whether to enable public viewing of the draft before it is submitted.

  • nsfw – Whether the draft should be marked NSFW.

  • original_content – Whether the submission should be marked as original content.

  • selftext – The Markdown formatted content for a text submission draft. Use None to make a title-only submission draft. selftext can not be provided if url is provided.

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission.

  • spoiler – Whether the submission should be marked as a spoiler.

  • subreddit – The subreddit to create the draft for. This accepts a subreddit display name, Subreddit object, or UserSubreddit object.

  • title – The title of the draft.

  • url – The URL for a link submission draft. url can not be provided if selftext is provided.

Additional keyword arguments can be provided to handle new parameters as Reddit introduces them.

For example, to update the title of a draft do:

draft = reddit.drafts("5f87d55c-e4fb-11eb-8965-6aeb41b0880e")
draft.update(title="New title")

LiveThread

class praw.models.LiveThread(reddit: praw.Reddit, id: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

An individual LiveThread object.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

created_utc

The creation time of the live thread, in Unix Time.

description

Description of the live thread, as Markdown.

description_html

Description of the live thread, as HTML.

id

The ID of the live thread.

nsfw

A bool representing whether or not the live thread is marked as NSFW.

__getitem__(update_id: str) praw.models.LiveUpdate

Return a lazy LiveUpdate instance.

Parameters

update_id – A live update ID, e.g., "7827987a-c998-11e4-a0b9-22000b6a88d2".

Usage:

thread = reddit.live("ukaeu1ik4sw5")
update = thread["7827987a-c998-11e4-a0b9-22000b6a88d2"]
update.thread  # LiveThread(id="ukaeu1ik4sw5")
update.id  # "7827987a-c998-11e4-a0b9-22000b6a88d2"
update.author  # "umbrae"
__init__(reddit: praw.Reddit, id: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

Initialize a LiveThread instance.

Parameters
  • reddit – An instance of Reddit.

  • id – A live thread ID, e.g., "ukaeu1ik4sw5"

contrib() praw.models.reddit.live.LiveThreadContribution

Provide an instance of LiveThreadContribution.

Usage:

thread = reddit.live("ukaeu1ik4sw5")
thread.contrib.add("### update")
contributor() praw.models.reddit.live.LiveContributorRelationship

Provide an instance of LiveContributorRelationship.

You can call the instance to get a list of contributors which is represented as RedditorList instance consists of Redditor instances. Those Redditor instances have permissions attributes as contributors:

thread = reddit.live("ukaeu1ik4sw5")
for contributor in thread.contributor():
    # prints `Redditor(name="Acidtwist") ["all"]`
    print(contributor, contributor.permissions)
discussions(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Get submissions linking to the thread.

Parameters

generator_kwargs – keyword arguments passed to ListingGenerator constructor.

Returns

A ListingGenerator object which yields Submission objects.

Additional keyword arguments are passed in the initialization of ListingGenerator.

Usage:

thread = reddit.live("ukaeu1ik4sw5")
for submission in thread.discussions(limit=None):
    print(submission.title)
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

report(type: str)

Report the thread violating the Reddit rules.

Parameters

type – One of "spam", "vote-manipulation", "personal- information", "sexualizing-minors", or "site-breaking".

Usage:

thread = reddit.live("xyu8kmjvfrww")
thread.report("spam")
stream() praw.models.reddit.live.LiveThreadStream

Provide an instance of LiveThreadStream.

Streams are used to indefinitely retrieve new updates made to a live thread, like:

for live_update in reddit.live("ta535s1hq2je").stream.updates():
    print(live_update.body)

Updates are yielded oldest first as LiveUpdate. Up to 100 historical updates will initially be returned. To only retrieve new updates starting from when the stream is created, pass skip_existing=True:

live_thread = reddit.live("ta535s1hq2je")
for live_update in live_thread.stream.updates(skip_existing=True):
    print(live_update.author)
updates(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.LiveUpdate]

Return a ListingGenerator yields LiveUpdate s.

Parameters

generator_kwargs – keyword arguments passed to ListingGenerator constructor.

Returns

A ListingGenerator object which yields LiveUpdate objects.

Additional keyword arguments are passed in the initialization of ListingGenerator.

Usage:

thread = reddit.live("ukaeu1ik4sw5")
after = "LiveUpdate_fefb3dae-7534-11e6-b259-0ef8c7233633"
for submission in thread.updates(limit=5, params={"after": after}):
    print(submission.body)

LiveUpdate

class praw.models.LiveUpdate(reddit: praw.Reddit, thread_id: Optional[str] = None, update_id: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

An individual LiveUpdate object.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

author

The Redditor who made the update.

body

Body of the update, as Markdown.

body_html

Body of the update, as HTML.

created_utc

The time the update was created, as Unix Time.

stricken

A bool representing whether or not the update was stricken (see strike()).

__init__(reddit: praw.Reddit, thread_id: Optional[str] = None, update_id: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

Initialize a LiveUpdate instance.

Either thread_id and update_id, or _data must be provided.

Parameters
  • reddit – An instance of Reddit.

  • thread_id – A live thread ID, e.g., "ukaeu1ik4sw5".

  • update_id – A live update ID, e.g., "7827987a-c998-11e4-a0b9-22000b6a88d2".

Usage:

update = LiveUpdate(reddit, "ukaeu1ik4sw5", "7827987a-c998-11e4-a0b9-22000b6a88d2")
update.thread  # LiveThread(id="ukaeu1ik4sw5")
update.id  # "7827987a-c998-11e4-a0b9-22000b6a88d2"
update.author  # "umbrae"
contrib() praw.models.reddit.live.LiveUpdateContribution

Provide an instance of LiveUpdateContribution.

Usage:

thread = reddit.live("ukaeu1ik4sw5")
update = thread["7827987a-c998-11e4-a0b9-22000b6a88d2"]
update.contrib  # LiveUpdateContribution instance
property fullname: str

Return the object’s fullname.

A fullname is an object’s kind mapping like t3 followed by an underscore and the object’s base36 ID, e.g., t1_c5s96e0.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

property thread: LiveThread

Return LiveThread object the update object belongs to.

Message

class praw.models.Message(reddit: praw.Reddit, _data: Dict[str, Any])

A class for private messages.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

author

Provides an instance of Redditor.

body

The body of the message, as Markdown.

body_html

The body of the message, as HTML.

created_utc

Time the message was created, represented in Unix Time.

dest

Provides an instance of Redditor. The recipient of the message.

id

The ID of the message.

name

The full ID of the message, prefixed with t4_.

subject

The subject of the message.

was_comment

Whether or not the message was a comment reply.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Message instance.

block()

Block the user who sent the item.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.block()

# or, identically:

comment.author.block()
collapse()

Mark the item as collapsed.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox()

# select first inbox item and collapse it message = next(inbox)
message.collapse()

See also

uncollapse()

delete()

Delete the message.

Note

Reddit does not return an indication of whether or not the message was successfully deleted.

For example, to delete the most recent message in your inbox:

next(reddit.inbox.all()).delete()
property fullname: str

Return the object’s fullname.

A fullname is an object’s kind mapping like t3 followed by an underscore and the object’s base36 ID, e.g., t1_c5s96e0.

mark_read()

Mark a single inbox item as read.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox.unread()

for message in inbox:
    # process unread messages
    ...

See also

mark_unread()

To mark the whole inbox as read with a single network request, use Inbox.mark_all_read()

mark_unread()

Mark the item as unread.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox(limit=10)

for message in inbox:
    # process messages
    ...

See also

mark_read()

property parent: Optional[praw.models.Message]

Return the parent of the message if it exists.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit)

Return an instance of Message or SubredditMessage from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

reply(body: str) Optional[Union[praw.models.Comment, praw.models.Message]]

Reply to the object.

Parameters

body – The Markdown formatted content for a comment.

Returns

A Comment or Message object for the newly created comment or message or None if Reddit doesn’t provide one.

Raises

prawcore.exceptions.Forbidden when attempting to reply to some items, such as locked submissions/comments or non-replyable messages.

A None value can be returned if the target is a comment or submission in a quarantined subreddit and the authenticated user has not opt-ed into viewing the content. When this happens the comment will be successfully created on Reddit and can be retried by drawing the comment from the user’s comment history.

Example usage:

submission = reddit.submission("5or86n")
submission.reply("reply")

comment = reddit.comment("dxolpyc")
comment.reply("reply")
unblock_subreddit()

Unblock a subreddit.

Note

This method pertains only to objects which were retrieved via the inbox.

For example, to unblock all blocked subreddits that you can find by going through your inbox:

from praw.models import SubredditMessage

subs = set()
for item in reddit.inbox.messages(limit=None):
    if isinstance(item, SubredditMessage):
        if (
            item.subject == "[message from blocked subreddit]"
            and str(item.subreddit) not in subs
        ):
            item.unblock_subreddit()
            subs.add(str(item.subreddit))
uncollapse()

Mark the item as uncollapsed.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox()

# select first inbox item and uncollapse it
message = next(inbox)
message.uncollapse()

See also

collapse()

ModmailConversation

class praw.models.reddit.modmail.ModmailConversation(reddit: praw.Reddit, id: Optional[str] = None, mark_read: bool = False, _data: Optional[Dict[str, Any]] = None)

A class for modmail conversations.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

authors

Provides an ordered list of Redditor instances. The authors of each message in the modmail conversation.

id

The ID of the ModmailConversation.

is_highlighted

Whether or not the ModmailConversation is highlighted.

is_internal

Whether or not the ModmailConversation is a private mod conversation.

last_mod_update

Time of the last mod message reply, represented in the ISO 8601 standard with timezone.

last_updated

Time of the last message reply, represented in the ISO 8601 standard with timezone.

last_user_update

Time of the last user message reply, represented in the ISO 8601 standard with timezone.

num_messages

The number of messages in the ModmailConversation.

obj_ids

Provides a list of dictionaries representing mod actions on the ModmailConversation. Each dict contains attributes of "key" and "id". The key can be either ""messages" or "ModAction". "ModAction" represents archiving/highlighting etc.

owner

Provides an instance of Subreddit. The subreddit that the ModmailConversation belongs to.

participant

Provides an instance of Redditor. The participating user in the ModmailConversation.

subject

The subject of the ModmailConversation.

__init__(reddit: praw.Reddit, id: Optional[str] = None, mark_read: bool = False, _data: Optional[Dict[str, Any]] = None)

Initialize a ModmailConversation instance.

Parameters

mark_read – If True, conversation is marked as read (default: False).

archive()

Archive the conversation.

For example:

reddit.subreddit("test").modmail("2gmz").archive()
highlight()

Highlight the conversation.

For example:

reddit.subreddit("test").modmail("2gmz").highlight()
mute(*, num_days=3)

Mute the non-mod user associated with the conversation.

Parameters

num_days – Duration of mute in days. Valid options are 3, 7, or 28 (default: 3).

For example:

reddit.subreddit("test").modmail("2gmz").mute()

To mute for 7 days:

reddit.subreddit("test").modmail("2gmz").mute(num_days=7)
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit, convert_objects: bool = True)

Return an instance of ModmailConversation from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

  • convert_objects – If True, convert message and mod action data into objects (default: True).

read(*, other_conversations: Optional[List[ModmailConversation]] = None)

Mark the conversation(s) as read.

Parameters

other_conversations – A list of other conversations to mark (default: None).

For example, to mark the conversation as read along with other recent conversations from the same user:

subreddit = reddit.subreddit("test")
conversation = subreddit.modmail.conversation("2gmz")
conversation.read(other_conversations=conversation.user.recent_convos)
reply(*, author_hidden: bool = False, body: str, internal: bool = False) ModmailMessage

Reply to the conversation.

Parameters
  • author_hidden – When True, author is hidden from non-moderators (default: False).

  • body – The Markdown formatted content for a message.

  • internal – When True, message is a private moderator note, hidden from non-moderators (default: False).

Returns

A ModmailMessage object for the newly created message.

For example, to reply to the non-mod user while hiding your username:

conversation = reddit.subreddit("test").modmail("2gmz")
conversation.reply(body="Message body", author_hidden=True)

To create a private moderator note on the conversation:

conversation.reply(body="Message body", internal=True)
unarchive()

Unarchive the conversation.

For example:

reddit.subreddit("test").modmail("2gmz").unarchive()
unhighlight()

Un-highlight the conversation.

For example:

reddit.subreddit("test").modmail("2gmz").unhighlight()
unmute()

Unmute the non-mod user associated with the conversation.

For example:

reddit.subreddit("test").modmail("2gmz").unmute()
unread(*, other_conversations: Optional[List[ModmailConversation]] = None)

Mark the conversation(s) as unread.

Parameters

other_conversations – A list of other conversations to mark (default: None).

For example, to mark the conversation as unread along with other recent conversations from the same user:

subreddit = reddit.subreddit("test")
conversation = subreddit.modmail.conversation("2gmz")
conversation.unread(other_conversations=conversation.user.recent_convos)

MoreComments

class praw.models.MoreComments(reddit: praw.Reddit, _data: Dict[str, Any])

A class indicating there are more comments.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a MoreComments instance.

comments(*, update: bool = True) List[praw.models.Comment]

Fetch and return the comments for a single MoreComments object.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Multireddit

class praw.models.Multireddit(reddit: praw.Reddit, _data: Dict[str, Any])

A class for users’ multireddits.

This is referred to as a “Custom Feed” on the Reddit UI.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

can_edit

A bool representing whether or not the authenticated user may edit the multireddit.

copied_from

The multireddit that the multireddit was copied from, if it exists, otherwise None.

created_utc

When the multireddit was created, in Unix Time.

description_html

The description of the multireddit, as HTML.

description_md

The description of the multireddit, as Markdown.

display_name

The display name of the multireddit.

name

The name of the multireddit.

over_18

A bool representing whether or not the multireddit is restricted for users over 18.

subreddits

A list of Subreddits that make up the multireddit.

visibility

The visibility of the multireddit, either "private", "public", or "hidden".

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Multireddit instance.

add(subreddit: praw.models.Subreddit)

Add a subreddit to this multireddit.

Parameters

subreddit – The subreddit to add to this multi.

For example, to add r/test to multireddit bboe/test:

subreddit = reddit.subreddit("test")
reddit.multireddit(redditor="bboe", name="test").add(subreddit)
comments() CommentHelper

Provide an instance of CommentHelper.

For example, to output the author of the 25 most recent comments of r/test execute:

for comment in reddit.subreddit("test").comments(limit=25):
    print(comment.author)
controversial(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for controversial items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").controversial(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").controversial(
    time_filter="day"
)
reddit.redditor("spez").controversial(time_filter="month")
reddit.redditor("spez").comments.controversial(time_filter="year")
reddit.redditor("spez").submissions.controversial(time_filter="all")
reddit.subreddit("all").controversial(time_filter="hour")
copy(*, display_name: Optional[str] = None) praw.models.Multireddit

Copy this multireddit and return the new multireddit.

Parameters

display_name – The display name for the copied multireddit. Reddit will generate the name field from this display name. When not provided the copy will use the same display name and name as this multireddit.

To copy the multireddit bboe/test with a name of "testing":

reddit.multireddit(redditor="bboe", name="test").copy(display_name="testing")
delete()

Delete this multireddit.

For example, to delete multireddit bboe/test:

reddit.multireddit(redditor="bboe", name="test").delete()
gilded(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for gilded items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get gilded items in r/test:

for item in reddit.subreddit("test").gilded():
    print(item.id)
hot(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for hot items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").hot()
reddit.multireddit(redditor="samuraisam", name="programming").hot()
reddit.redditor("spez").hot()
reddit.redditor("spez").comments.hot()
reddit.redditor("spez").submissions.hot()
reddit.subreddit("all").hot()
new(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for new items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").new()
reddit.multireddit(redditor="samuraisam", name="programming").new()
reddit.redditor("spez").new()
reddit.redditor("spez").comments.new()
reddit.redditor("spez").submissions.new()
reddit.subreddit("all").new()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

random_rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for random rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get random rising submissions for r/test:

for submission in reddit.subreddit("test").random_rising():
    print(submission.title)
remove(subreddit: praw.models.Subreddit)

Remove a subreddit from this multireddit.

Parameters

subreddit – The subreddit to remove from this multi.

For example, to remove r/test from multireddit bboe/test:

subreddit = reddit.subreddit("test")
reddit.multireddit(redditor="bboe", name="test").remove(subreddit)
rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get rising submissions for r/test:

for submission in reddit.subreddit("test").rising():
    print(submission.title)
static sluggify(title: str)

Return a slug version of the title.

Parameters

title – The title to make a slug of.

Adapted from Reddit’s utils.py.

stream() SubredditStream

Provide an instance of SubredditStream.

Streams can be used to indefinitely retrieve new comments made to a multireddit, like:

for comment in reddit.multireddit(redditor="spez", name="fun").stream.comments():
    print(comment)

Additionally, new submissions can be retrieved via the stream. In the following example all new submissions to the multireddit are fetched:

for submission in reddit.multireddit(
    redditor="bboe", name="games"
).stream.submissions():
    print(submission)
top(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for top items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").top(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").top(time_filter="day")
reddit.redditor("spez").top(time_filter="month")
reddit.redditor("spez").comments.top(time_filter="year")
reddit.redditor("spez").submissions.top(time_filter="all")
reddit.subreddit("all").top(time_filter="hour")
update(**updated_settings: Union[str, List[Union[str, praw.models.Subreddit, Dict[str, str]]]])

Update this multireddit.

Keyword arguments are passed for settings that should be updated. They can any of:

Parameters
  • display_name – The display name for this multireddit. Must be no longer than 50 characters.

  • subreddits – Subreddits for this multireddit.

  • description_md – Description for this multireddit, formatted in Markdown.

  • icon_name – Can be one of: "art and design", "ask", "books", "business", "cars", "comics", "cute animals", "diy", "entertainment", "food and drink", "funny", "games", "grooming", "health", "life advice", "military", "models pinup", "music", "news", "philosophy", "pictures and gifs", "science", "shopping", "sports", "style", "tech", "travel", "unusual stories", "video", or None.

  • key_color – RGB hex color code of the form "#FFFFFF".

  • visibility – Can be one of: "hidden", "private", or "public".

  • weighting_scheme – Can be one of: "classic" or "fresh".

For example, to rename multireddit "bboe/test" to "bboe/testing":

reddit.multireddit(redditor="bboe", name="test").update(display_name="testing")

Redditor

class praw.models.Redditor(reddit: praw.Reddit, name: Optional[str] = None, fullname: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

A class representing the users of Reddit.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Note

Shadowbanned accounts are treated the same as non-existent accounts, meaning that they will not have any attributes.

Note

Suspended/banned accounts will only return the name and is_suspended attributes.

Attribute

Description

comment_karma

The comment karma for the Redditor.

comments

Provide an instance of SubListing for comment access.

submissions

Provide an instance of SubListing for submission access.

created_utc

Time the account was created, represented in Unix Time.

has_verified_email

Whether or not the Redditor has verified their email.

icon_img

The url of the Redditors’ avatar.

id

The ID of the Redditor.

is_employee

Whether or not the Redditor is a Reddit employee.

is_friend

Whether or not the Redditor is friends with the authenticated user.

is_mod

Whether or not the Redditor mods any subreddits.

is_gold

Whether or not the Redditor has active Reddit Premium status.

is_suspended

Whether or not the Redditor is currently suspended.

link_karma

The link karma for the Redditor.

name

The Redditor’s username.

subreddit

If the Redditor has created a user-subreddit, provides a dictionary of additional attributes. See below.

subreddit["banner_img"]

The URL of the user-subreddit banner.

subreddit["name"]

The fullname of the user-subreddit.

subreddit["over_18"]

Whether or not the user-subreddit is NSFW.

subreddit["public_description"]

The public description of the user-subreddit.

subreddit["subscribers"]

The number of users subscribed to the user-subreddit.

subreddit["title"]

The title of the user-subreddit.

__init__(reddit: praw.Reddit, name: Optional[str] = None, fullname: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

Initialize a Redditor instance.

Parameters
  • reddit – An instance of Reddit.

  • name – The name of the redditor.

  • fullname – The fullname of the redditor, starting with t2_.

Exactly one of name, fullname or _data must be provided.

block()

Block the Redditor.

For example, to block Redditor u/spez:

reddit.redditor("spez").block()

Note

Blocking a trusted user will remove that user from your trusted list.

See also

trust()

comments() SubListing

Provide an instance of SubListing for comment access.

For example, to output the first line of all new comments by u/spez try:

for comment in reddit.redditor("spez").comments.new(limit=None):
    print(comment.body.split("\\n", 1)[0][:79])
controversial(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for controversial items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").controversial(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").controversial(
    time_filter="day"
)
reddit.redditor("spez").controversial(time_filter="month")
reddit.redditor("spez").comments.controversial(time_filter="year")
reddit.redditor("spez").submissions.controversial(time_filter="all")
reddit.subreddit("all").controversial(time_filter="hour")
distrust()

Remove the Redditor from your whitelist of trusted users.

For example, to remove Redditor u/spez from your whitelist:

reddit.redditor("spez").distrust()

See also

trust()

downvoted(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for items the user has downvoted.

Returns

A ListingGenerator object which yields Comment or Submission objects the user has downvoted.

Raises

prawcore.Forbidden if the user is not authorized to access the list.

Note

Since this function returns a ListingGenerator the exception may not occur until sometime after this function has returned.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get all downvoted items of the authenticated user:

for item in reddit.user.me().downvoted():
    print(item.id)
friend(*, note: str = None)

Friend the Redditor.

Parameters

note – A note to save along with the relationship. Requires Reddit Premium (default: None).

Calling this method subsequent times will update the note.

For example, to friend u/spez:

reddit.redditor("spez").friend()

To add a note to the friendship (requires Reddit Premium):

reddit.redditor("spez").friend(note="My favorite admin")
friend_info() praw.models.Redditor

Return a Redditor instance with specific friend-related attributes.

Returns

A Redditor instance with fields date, id, and possibly note if the authenticated user has Reddit Premium.

For example, to get the friendship information of Redditor u/spez:

info = reddit.redditor("spez").friend_info
friend_data = info.date
classmethod from_data(reddit, data)

Return an instance of Redditor, or None from data.

property fullname: str

Return the object’s fullname.

A fullname is an object’s kind mapping like t3 followed by an underscore and the object’s base36 ID, e.g., t1_c5s96e0.

gild(*, months: int = 1)

Gild the Redditor.

Parameters

months – Specifies the number of months to gild up to 36 (default: 1).

For example, to gild Redditor u/spez for 1 month:

reddit.redditor("spez").gild(months=1)
gilded(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for gilded items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get gilded items in r/test:

for item in reddit.subreddit("test").gilded():
    print(item.id)
gildings(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for items the user has gilded.

Returns

A ListingGenerator object which yields Comment or Submission objects the user has gilded.

Raises

prawcore.Forbidden if the user is not authorized to access the list.

Note

Since this function returns a ListingGenerator the exception may not occur until sometime after this function has returned.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get all gilded items of the authenticated user:

for item in reddit.user.me().gildings():
    print(item.id)
hidden(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for items the user has hidden.

Returns

A ListingGenerator object which yields Comment or Submission objects the user has hid.

Raises

prawcore.Forbidden if the user is not authorized to access the list.

Note

Since this function returns a ListingGenerator the exception may not occur until sometime after this function has returned.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get all hidden items of the authenticated user:

for item in reddit.user.me().hidden():
    print(item.id)
hot(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for hot items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").hot()
reddit.multireddit(redditor="samuraisam", name="programming").hot()
reddit.redditor("spez").hot()
reddit.redditor("spez").comments.hot()
reddit.redditor("spez").submissions.hot()
reddit.subreddit("all").hot()
message(*, from_subreddit: Optional[Union[praw.models.Subreddit, str]] = None, message: str, subject: str)

Send a message to a Redditor or a Subreddit’s moderators (modmail).

Parameters
  • from_subreddit

    A Subreddit instance or string to send the message from. When provided, messages are sent from the subreddit rather than from the authenticated user.

    Note

    The authenticated user must be a moderator of the subreddit and have the mail moderator permission.

  • message – The message content.

  • subject – The subject of the message.

For example, to send a private message to u/spez, try:

reddit.redditor("spez").message(subject="TEST", message="test message from PRAW")

To send a message to u/spez from the moderators of r/test try:

reddit.redditor("spez").message(
    subject="TEST", message="test message from r/test", from_subreddit="test"
)

To send a message to the moderators of r/test, try:

reddit.subreddit("test").message(subject="TEST", message="test PM from PRAW")
moderated() List[praw.models.Subreddit]

Return a list of the redditor’s moderated subreddits.

Returns

A list of Subreddit objects. Return [] if the redditor has no moderated subreddits.

Raises

prawcore.ServerError in certain circumstances. See the note below.

Note

The redditor’s own user profile subreddit will not be returned, but other user profile subreddits they moderate will be returned.

Usage:

for subreddit in reddit.redditor("spez").moderated():
    print(subreddit.display_name)
    print(subreddit.title)

Note

A prawcore.ServerError exception may be raised if the redditor moderates a large number of subreddits. If that happens, try switching to read-only mode. For example,

reddit.read_only = True
for subreddit in reddit.redditor("reddit").moderated():
    print(str(subreddit))

It is possible that requests made in read-only mode will also raise a prawcore.ServerError exception.

When used in read-only mode, this method does not retrieve information about subreddits that require certain special permissions to access, e.g., private subreddits and premium-only subreddits.

multireddits() List[praw.models.Multireddit]

Return a list of the redditor’s public multireddits.

For example, to to get Redditor u/spez’s multireddits:

multireddits = reddit.redditor("spez").multireddits()
new(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for new items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").new()
reddit.multireddit(redditor="samuraisam", name="programming").new()
reddit.redditor("spez").new()
reddit.redditor("spez").comments.new()
reddit.redditor("spez").submissions.new()
reddit.subreddit("all").new()
notes() praw.models.RedditorModNotes

Provide an instance of RedditorModNotes.

This provides an interface for managing moderator notes for a redditor.

Note

The authenticated user must be a moderator of the provided subreddit(s).

For example, all the notes for u/spez in r/test can be iterated through like so:

redditor = reddit.redditor("spez")

for note in redditor.notes.subreddits("test"):
    print(f"{note.label}: {note.note}")
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

saved(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for items the user has saved.

Returns

A ListingGenerator object which yields Comment or Submission objects the user has saved.

Raises

prawcore.Forbidden if the user is not authorized to access the list.

Note

Since this function returns a ListingGenerator the exception may not occur until sometime after this function has returned.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get all saved items of the authenticated user:

for item in reddit.user.me().saved(limit=None):
    print(item.id)
stream() praw.models.reddit.redditor.RedditorStream

Provide an instance of RedditorStream.

Streams can be used to indefinitely retrieve new comments made by a redditor, like:

for comment in reddit.redditor("spez").stream.comments():
    print(comment)

Additionally, new submissions can be retrieved via the stream. In the following example all submissions are fetched via the redditor u/spez:

for submission in reddit.redditor("spez").stream.submissions():
    print(submission)
submissions() SubListing

Provide an instance of SubListing for submission access.

For example, to output the title’s of top 100 of all time submissions for u/spez try:

for submission in reddit.redditor("spez").submissions.top(time_filter="all"):
    print(submission.title)
top(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for top items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").top(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").top(time_filter="day")
reddit.redditor("spez").top(time_filter="month")
reddit.redditor("spez").comments.top(time_filter="year")
reddit.redditor("spez").submissions.top(time_filter="all")
reddit.subreddit("all").top(time_filter="hour")
trophies() List[praw.models.Trophy]

Return a list of the redditor’s trophies.

Returns

A list of Trophy objects. Return [] if the redditor has no trophies.

Raises

RedditAPIException if the redditor doesn’t exist.

Usage:

for trophy in reddit.redditor("spez").trophies():
    print(trophy.name)
    print(trophy.description)
trust()

Add the Redditor to your whitelist of trusted users.

Trusted users will always be able to send you PMs.

Example usage:

reddit.redditor("AaronSw").trust()

Use the accept_pms parameter of Preferences.update() to toggle your accept_pms setting between "everyone" and "whitelisted". For example:

# Accept private messages from everyone:
reddit.user.preferences.update(accept_pms="everyone")
# Only accept private messages from trusted users:
reddit.user.preferences.update(accept_pms="whitelisted")

You may trust a user even if your accept_pms setting is switched to "everyone".

Note

You are allowed to have a user on your blocked list and your friends list at the same time. However, you cannot trust a user who is on your blocked list.

unblock()

Unblock the Redditor.

For example, to unblock Redditor u/spez:

reddit.redditor("spez").unblock()
unfriend()

Unfriend the Redditor.

For example, to unfriend Redditor u/spez:

reddit.redditor("spez").unfriend()
upvoted(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for items the user has upvoted.

Returns

A ListingGenerator object which yields Comment or Submission objects the user has upvoted.

Raises

prawcore.Forbidden if the user is not authorized to access the list.

Note

Since this function returns a ListingGenerator the exception may not occur until sometime after this function has returned.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get all upvoted items of the authenticated user:

for item in reddit.user.me().upvoted():
    print(item.id)

Submission

class praw.models.Submission(reddit: praw.Reddit, id: Optional[str] = None, url: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

A class for submissions to Reddit.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

author

Provides an instance of Redditor.

author_flair_text

The text content of the author’s flair, or None if not flaired.

clicked

Whether or not the submission has been clicked by the client.

comments

Provides an instance of CommentForest.

created_utc

Time the submission was created, represented in Unix Time.

distinguished

Whether or not the submission is distinguished.

edited

Whether or not the submission has been edited.

id

ID of the submission.

is_original_content

Whether or not the submission has been set as original content.

is_self

Whether or not the submission is a selfpost (text-only).

link_flair_template_id

The link flair’s ID.

link_flair_text

The link flair’s text content, or None if not flaired.

locked

Whether or not the submission has been locked.

name

Fullname of the submission.

num_comments

The number of comments on the submission.

over_18

Whether or not the submission has been marked as NSFW.

permalink

A permalink for the submission.

poll_data

A PollData object representing the data of this submission, if it is a poll submission.

saved

Whether or not the submission is saved.

score

The number of upvotes for the submission.

selftext

The submissions’ selftext - an empty string if a link post.

spoiler

Whether or not the submission has been marked as a spoiler.

stickied

Whether or not the submission is stickied.

subreddit

Provides an instance of Subreddit.

title

The title of the submission.

upvote_ratio

The percentage of upvotes from all votes on the submission.

url

The URL the submission links to, or the permalink if a selfpost.

__init__(reddit: praw.Reddit, id: Optional[str] = None, url: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

Initialize a Submission instance.

Parameters
  • reddit – An instance of Reddit.

  • id – A reddit base36 submission ID, e.g., "2gmzqe".

  • url – A URL supported by id_from_url().

Either id or url can be provided, but not both.

award(*, gild_type: str = 'gid_2', is_anonymous: bool = True, message: str = None) dict

Award the author of the item.

Parameters
  • gild_type – Type of award to give. See table below for currently know global award types.

  • is_anonymous – If True, the authenticated user’s username will not be revealed to the recipient.

  • message – Message to include with the award.

Returns

A dict containing info similar to what is shown below:

{
    "subreddit_balance": 85260,
    "treatment_tags": [],
    "coins": 8760,
    "gildings": {"gid_1": 0, "gid_2": 1, "gid_3": 0},
    "awarder_karma_received": 4,
    "all_awardings": [
        {
            "giver_coin_reward": 0,
            "subreddit_id": None,
            "is_new": False,
            "days_of_drip_extension": 0,
            "coin_price": 75,
            "id": "award_9663243a-e77f-44cf-abc6-850ead2cd18d",
            "penny_donate": 0,
            "coin_reward": 0,
            "icon_url": "https://www.redditstatic.com/gold/awards/icon/SnooClappingPremium_512.png",
            "days_of_premium": 0,
            "icon_height": 512,
            "tiers_by_required_awardings": None,
            "icon_width": 512,
            "static_icon_width": 512,
            "start_date": None,
            "is_enabled": True,
            "awardings_required_to_grant_benefits": None,
            "description": "For an especially amazing showing.",
            "end_date": None,
            "subreddit_coin_reward": 0,
            "count": 1,
            "static_icon_height": 512,
            "name": "Bravo Grande!",
            "icon_format": "APNG",
            "award_sub_type": "PREMIUM",
            "penny_price": 0,
            "award_type": "global",
            "static_icon_url": "https://i.redd.it/award_images/t5_q0gj4/59e02tmkl4451_BravoGrande-Static.png",
        }
    ],
}

Warning

Requires the authenticated user to own Reddit Coins. Calling this method will consume Reddit Coins.

To award the gold award anonymously do:

comment = reddit.comment("dkk4qjd")
comment.award()

submission = reddit.submission("8dmv8z")
submission.award()

To award the platinum award with the message ‘Nice!’ and reveal your username to the recipient do:

comment = reddit.comment("dkk4qjd")
comment.award(gild_type="gild_3", message="Nice!", is_anonymous=False)

submission = reddit.submission("8dmv8z")
submission.award(gild_type="gild_3", message="Nice!", is_anonymous=False)

This is a list of known global awards (as of 11/08/2021)

Name

Icon

Gild Type

Description

Cost

Silver

https://www.redditstatic.com/gold/awards/icon/silver_64.png

gid_1

Shows the Silver Award… and that’s it.

100

Gold

https://www.redditstatic.com/gold/awards/icon/gold_64.png

gid_2

Gives 100 Reddit Coins and a week of r/lounge access and ad-free browsing.

500

Platinum

https://www.redditstatic.com/gold/awards/icon/platinum_64.png

gid_3

Gives 700 Reddit Coins and a month of r/lounge access and ad-free browsing.

1800

LOVE!

https://preview.redd.it/award_images/t5_22cerq/j3azv69qjfn51_LOVE.png?width=64&height=64&crop=smart&auto=webp&s=405d338bf34818596ab84bc26a09316917def8bb

award_5eac457f-ebac-449b-93a7-eb17b557f03c

When you follow your heart, love is the answer

20

Starstruck

https://www.redditstatic.com/gold/awards/icon/Starstruck_64.png

award_abb865cf-620b-4219-8777-3658cf9091fb

Can’t stop seeing stars

20

All-Seeing Upvote

https://www.redditstatic.com/gold/awards/icon/Illuminati_64.png

award_b4ff447e-05a5-42dc-9002-63568807cfe6

A glowing commendation for all to see

30

Narwhal Salute

https://preview.redd.it/award_images/t5_22cerq/80j20o397jj41_NarwhalSalute.png?width=64&height=64&crop=smart&auto=webp&s=8629e84ef3188ad75ebca713afb4a0f97e4c3c70

award_a2506925-fc82-4d6c-ae3b-b7217e09d7f0

A golden splash of respect

30

Wholesome Seal of Approval

https://preview.redd.it/award_images/t5_22cerq/b9ks3a5k7jj41_WholesomeSealofApproval.png?width=64&height=64&crop=smart&auto=webp&s=2bcedd41a51b17ff305fc0ec6eb7c5a631a90c60

award_c4b2e438-16bb-4568-88e7-7893b7662944

A glittering stamp for a feel-good thing

30

Ally

https://preview.redd.it/award_images/t5_22cerq/5nswjpyy44551_Ally.png?width=64&height=64&crop=smart&auto=webp&s=655fb8310589a3964a82ac0e56d016eb97aa6d4d

award_69c94eb4-d6a3-48e7-9cf2-0f39fed8b87c

Listen, get educated, and get involved.

50

Take My Energy

https://preview.redd.it/award_images/t5_q0gj4/p4yzxkaed5f61_oldtakemyenergy.png?width=64&height=64&crop=smart&auto=webp&s=f44a28b9ebe879e1be2936e9f6290044237dd458

award_02d9ab2c-162e-4c01-8438-317a016ed3d9

I’m in this with you.

50

Wearing is Caring

https://preview.redd.it/award_images/t5_q0gj4/9auzllkyd5f61_oldwearing.png?width=64&height=64&crop=smart&auto=webp&s=115ba4ee4036317efebfc53d25f11e7f055ab435

award_80d4d339-95d0-43ac-b051-bc3fe0a9bab8

Keep the community and yourself healthy and happy.

50

Facepalm

https://preview.redd.it/award_images/t5_22cerq/ey2iodron2s41_Facepalm.png?width=64&height=64&crop=smart&auto=webp&s=9d3c8e8642dc97c655867ea5ba37b7d76d653203

award_b1b44fa1-8179-4d84-a9ed-f25bb81f1c5f

Lowers face into palm

70

Snek

https://preview.redd.it/award_images/t5_22cerq/rc5iesz2z8t41_Snek.png?width=64&height=64&crop=smart&auto=webp&s=2856d19d59c0af0d38fd0b6058622f6a1e91956a

award_99d95969-6100-45b2-b00c-0ec45ae19596

A smol, delicate danger noodle.

70

Tree Hug

https://preview.redd.it/award_images/t5_22cerq/fukjtec638u41_TreeHug.png?width=64&height=64&crop=smart&auto=webp&s=b46d14cae99b5519775167d0aea8418c480c28c0

award_b92370bb-b7de-4fb3-9608-c5b4a22f714a

Show nature some love.

70

Bravo Grande!

https://www.redditstatic.com/gold/awards/icon/SnooClappingPremium_64.png

award_9663243a-e77f-44cf-abc6-850ead2cd18d

For an especially amazing showing.

75

Party Train

https://www.redditstatic.com/gold/awards/icon/Train/Train_silver_64.png

award_75f9bc56-eba3-4988-a1af-aec974404a0b

All aboard! Every five Party Train Awards gives the author 100 Reddit Coins and a week of r/lounge access and ad-free browsing. Rack up the awards and watch the train level-up!

75

Take My Power

https://www.redditstatic.com/gold/awards/icon/TakeMyPower_64.png

award_92cb6518-a71a-4217-9f8f-7ecbd7ab12ba

Add my power to yours.

75

Defeated

https://preview.redd.it/award_images/t5_22cerq/ooo0r2cq7q161_Defeated.png?width=64&height=64&crop=smart&auto=webp&s=bdbc2e8cd019294341e37330ce8f58c781b85b14

award_58ef8551-8c27-4f03-afa5-748432194e3d

The process of taking a painful L

80

Hugz

https://preview.redd.it/award_images/t5_q0gj4/ks45ij6w05f61_oldHugz.png?width=64&height=64&crop=smart&auto=webp&s=899f5a3267bb4d959f0a3b32be5b48975c681261

award_8352bdff-3e03-4189-8a08-82501dd8f835

Everything is better with a good hug

80

‘MURICA

https://preview.redd.it/award_images/t5_22cerq/18mwqw5th9e51_MURICA.png?width=64&height=64&crop=smart&auto=webp&s=759d235c371d6ae8ad5efb1c98a74b259a3ff8fe

award_869d4135-8738-41e5-8630-de593b4f049f

Did somebody say ‘Murica?

100

Burning Cash

https://preview.redd.it/award_images/t5_22cerq/kqr00h8b7q161_BurningCash.png?width=64&height=64&crop=smart&auto=webp&s=dc1435c6da0830e82e4eee74ebc0b1ac20a5cc73

award_abcdefe4-c92f-4c66-880f-425962d17098

I don’t need it, I don’t even necessarily want it, but I’ve got some cash to burn so I’m gonna get it.

100

Dread

https://preview.redd.it/award_images/t5_22cerq/nvfe4gyawnf51_Dread.png?width=64&height=64&crop=smart&auto=webp&s=34247d8bba8dc5aa7eaed6e81135da0c935d37f3

award_81cf5c92-8500-498c-9c94-3e4034cece0a

Staring into the abyss and it’s staring right back

100

Evil Cackle

https://preview.redd.it/award_images/t5_22cerq/43zl6dfcg9e51_EvilCackle.png?width=64&height=64&crop=smart&auto=webp&s=bd7d6c66b7594ac91ff2d8a7d86340a0f49a153c

award_483d8e29-bbe5-404e-a09a-c2d7b16c4fff

Laugh like a supervillain

100

Glow Up

https://preview.redd.it/award_images/t5_22cerq/2754pa5jvsj51_GlowUp.png?width=64&height=64&crop=smart&auto=webp&s=60f710eccc52d9d05db204bb2b962372a1e45671

award_01178870-6a4f-4172-8f36-9ed5092ee4f9

You look amazing, glowing, incredible!

100

Heartwarming

https://preview.redd.it/award_images/t5_22cerq/v1mxw8i6wnf51_Heartwarming.png?width=64&height=64&crop=smart&auto=webp&s=c09f506dc0be92c9849ee7dd2cfe9d65852d6064

award_19860e30-3331-4bac-b3d1-bd28de0c7974

I needed this today

100

I am disappoint

https://preview.redd.it/award_images/t5_q0gj4/4samff1ud5f61_olddisappoint.png?width=64&height=64&crop=smart&auto=webp&s=874f513220a74b960d64fd560b8213579df2c6e3

award_03c4f93d-efc7-463b-98a7-c01814462ab0

I’m not mad, I’m just disappointed.

100

I’ll Drink to That

https://preview.redd.it/award_images/t5_22cerq/45aeu8mzvsj51_IllDrinktoThat.png?width=64&height=64&crop=smart&auto=webp&s=94580e58d47d0a1eb1c6cc776437c574b5bbad7c

award_3267ca1c-127a-49e9-9a3d-4ba96224af18

Let’s sip to good health and good company

100

Keep Calm

https://preview.redd.it/award_images/t5_22cerq/g77c4oud7hb51_KeepCalm.png?width=64&height=64&crop=smart&auto=webp&s=9510d2496464d0fa8ff2288e1f0e17f114226383

award_1da6ff27-7c0d-4524-9954-86e5cda5fcac

Stop, chill, relax

100

Kiss

https://preview.redd.it/award_images/t5_22cerq/sb42u5gmwsj51_Kiss.png?width=64&height=64&crop=smart&auto=webp&s=12e56d5bba8f00fe467d3efe0c962e70bcbc92ed

award_1e516e18-cbee-4668-b338-32d5530f91fe

You deserve a smooch

100

Lawyer Up

https://preview.redd.it/award_images/t5_22cerq/iq0sgwn5bzy41_LawyerUp.png?width=64&height=64&crop=smart&auto=webp&s=3baf45de6ba3e1535df885b91a2aa714e5ece9d5

award_ae89e420-c4a5-47b8-a007-5dacf1c0f0d4

OBJECTION!

100

Masterpiece

https://preview.redd.it/award_images/t5_22cerq/2juh333m40n51_Masterpiece.png?width=64&height=64&crop=smart&auto=webp&s=0183ad39a56ba3e46c4bcb5d8938392f75d5d9d5

award_b4072731-c0fb-4440-adc7-1063d6a5e6a0

C’est magnifique

100

Shocked

https://preview.redd.it/award_images/t5_22cerq/fck3iedi2ug51_Shocked.png?width=64&height=64&crop=smart&auto=webp&s=627fbd255cb9cce5b72551255cb061bf0c8af71a

award_fbe9527a-adb3-430e-af1a-5fd3489e641b

I’m genuinely flabbergasted.

100

Tearing Up

https://preview.redd.it/award_images/t5_22cerq/lop66ut2wnf51_TearingUp.png?width=64&height=64&crop=smart&auto=webp&s=a6ee8b3c876bdc7a022072134f8157a7ea85d884

award_43f3bf99-92d6-47ab-8205-130d26e7929f

This hits me right in the feels

100

Yummy

https://preview.redd.it/award_images/t5_22cerq/a7dhg27hvnf51_Yummy.png?width=64&height=64&crop=smart&auto=webp&s=7a70c563dbc8bb2659271ddd451c8e657f3a3aa8

award_ae7f17fb-6538-4c75-9ff4-5f48b4cdaa94

That looks so good

100

Faith In Humanity Restored

https://www.redditstatic.com/gold/awards/icon/Faith_in_Humanity_Restored_64.png

award_611ff347-196b-4a14-ad4b-0076f2d8f9d2

This goes a long way to restore my faith in the people of Earth

125

Wholesome

https://preview.redd.it/award_images/t5_22cerq/5izbv4fn0md41_Wholesome.png?width=64&height=64&crop=smart&auto=webp&s=89a077c4955b50fa2e57449eebf8c19e7f23ceb7

award_5f123e3d-4f48-42f4-9c11-e98b566d5897

When you come across a feel-good thing.

125

Beating Heart

https://www.redditstatic.com/gold/awards/icon/Beating_Heart_64.png

award_0d762fb3-17e4-4477-ab6b-9770b71b493c

My valentine makes my heart beat out of my chest.

150

Bless Up

https://preview.redd.it/award_images/t5_22cerq/trfv6ems1md41_BlessUp.png?width=64&height=64&crop=smart&auto=webp&s=5e84fe0dae062adff22f01c384d86c0633d06b28

award_77ba55a2-c33c-4351-ac49-807455a80148

Prayers up for the blessed.

150

Buff Doge

https://preview.redd.it/award_images/t5_22cerq/zc4a9vk5zmc51_BuffDoge.png?width=64&height=64&crop=smart&auto=webp&s=04b5cf5717304307515af46c73431f11bb66c3bd

award_c42dc561-0b41-40b6-a23d-ef7e110e739e

So buff, wow

150

Cake

https://www.redditstatic.com/gold/awards/icon/Animated_Cake_64.png

award_5fb42699-4911-42a2-884c-6fc8bdc36059

Did someone say… cake?

150

Helpful

https://preview.redd.it/award_images/t5_22cerq/klvxk1wggfd41_Helpful.png?width=64&height=64&crop=smart&auto=webp&s=cc59d3722210878a975f8d97eb62f3092e472693

award_f44611f1-b89e-46dc-97fe-892280b13b82

Thank you stranger. Shows the award.

150

I Shy

https://www.redditstatic.com/gold/awards/icon/I_shy_64.png

award_beccaae0-d745-44f9-bc5c-3c9f8117699b

No matter how hard I try, I’m too shy to confess my love!

150

Press F

https://preview.redd.it/award_images/t5_22cerq/tcofsbf92md41_PressF.png?width=64&height=64&crop=smart&auto=webp&s=b33bda0aa0310bbe1877ba2d02a259d7cc52d616

award_88fdcafc-57a0-48db-99cc-76276bfaf28b

To pay respects.

150

Take My Money

https://preview.redd.it/award_images/t5_22cerq/9jr8pv84v7i51_TakeMyMoney.png?width=64&height=64&crop=smart&auto=webp&s=8cae8bb3d91b20e0d13b24010a103842e365ff9f

award_a7f9cbd7-c0f1-4569-a913-ebf8d18de00b

I’m buying what you’re selling

150

2020 Veteran

https://preview.redd.it/award_images/t5_22cerq/xg2lbwcwl8361_2020Veteran.png?width=64&height=64&crop=smart&auto=webp&s=4400e79710036c5cf364f44e3ebf7144968c51ee

award_f0875744-15da-41ee-8591-b88e5a88c430

A reward for making it through the most topsey- turvey year anyone can remember. Gives 100 coins to the recipient.

200

Baby Snoo

https://preview.redd.it/award_images/t5_22cerq/9nh7lk027g461_BabySnoo.png?width=64&height=64&crop=smart&auto=webp&s=81cebff5c3112628a508bb35bca3d3e02c3cf57f

award_4d880932-4b45-4723-a964-5d749ace4df2

Baby Snoo is back and cuter than ever

200

Giggle

https://www.redditstatic.com/gold/awards/icon/Giggle_64.png

award_e813313c-1002-49bf-ac37-e966710f605f

Innocent laughter

200

Got the W

https://preview.redd.it/award_images/t5_22cerq/9avdcwgupta41_GottheW.png?width=64&height=64&crop=smart&auto=webp&s=d7c1acaee0770a6a0ff7853606ba9992824cdcec

award_8dc476c7-1478-4d41-b940-f139e58f7756

200

I’d Like to Thank…

https://preview.redd.it/award_images/t5_22cerq/8ad2jffnclf41_Thanks.png?width=64&height=64&crop=smart&auto=webp&s=430fa4cf2928cc37ed0a3344c8da31277a53929c

award_1703f934-cf44-40cc-a96d-3729d0b48262

My kindergarten teacher, my cat, my mom, and you.

200

I’m Deceased

https://preview.redd.it/award_images/t5_22cerq/2jd92wtn25g41_ImDeceased.png?width=64&height=64&crop=smart&auto=webp&s=106ba80d6001af5b5b47b874b4f86da6ca88113f

award_b28d9565-4137-433d-bb65-5d4aa82ade4c

Call an ambulance, I’m laughing too hard.

200

Looking

https://preview.redd.it/award_images/t5_22cerq/kjpl76213ug51_Looking.png?width=64&height=64&crop=smart&auto=webp&s=5d6beac8304bc8fe28e0d6acb1b4b1339abecc67

award_4922c1be-3646-4d62-96ea-19a56798df51

I can’t help but look.

200

Lurking

https://www.redditstatic.com/gold/awards/icon/Lurking_64.png

award_59ae34c0-14c8-4b16-a527-e157fac0a6c7

Just seeing what’s going on

200

Plus One

https://preview.redd.it/award_images/t5_22cerq/6vgr8y21i9741_PlusOne.png?width=64&height=64&crop=smart&auto=webp&s=ecea37cb71525e80d9ca2dbf2bd504b9f934606e

award_f7562045-905d-413e-9ed2-0a16d4bfe349

You officially endorse and add your voice to the crowd.

200

Sidevote

https://www.redditstatic.com/gold/awards/icon/side_vote_64.png

award_cd297f1a-8368-4f5a-acb8-6ec96fc6e8d6

Not an upvote, not a downvote, just an in-the- middle sidevote.

200

Stone Face

https://preview.redd.it/award_images/t5_22cerq/x1o2hnh9ywq71_StoneFace.png?width=64&height=64&crop=smart&auto=webp&s=657879ff853f573b0ec3fab4a0a568d77ef9562e

award_2c3bb816-f6fc-46e8-aaf7-2b196afffada

You got me stone faced

200

Stonks Falling

https://preview.redd.it/award_images/t5_22cerq/ree13odobef41_StonksFalling.png?width=64&height=64&crop=smart&auto=webp&s=b1016427b3550d229b4ec93437ac8b69c28c5ae2

award_9ee30a8f-463e-4ef7-9da9-a09f270ec026

Losing value fast.

200

Stonks Rising

https://preview.redd.it/award_images/t5_22cerq/s5edqq9abef41_StonksRising.png?width=64&height=64&crop=smart&auto=webp&s=8c11db37505feb2a3e4130eb15e9470e72e65b63

award_d125d124-5c03-490d-af3d-d07c462003da

To the MOON.

200

1UP

https://www.redditstatic.com/gold/awards/icon/Levelup_64.png

award_11be92ba-509e-46d3-991b-593239006521

Extra life

250

Are You Serious?

https://www.redditstatic.com/gold/awards/icon/are_you_serious_64.png

award_ca888c60-cd8c-4875-97f1-b536dc35a9a5

Are you being serious right now?

250

Are You Winning?

https://www.redditstatic.com/gold/awards/icon/AreYouWinSon_64.png

award_5641bae4-e690-4832-a498-4bd78da8b2b1

Well, are you?

250

Awesome Answer

https://preview.redd.it/award_images/t5_22cerq/71v56o5a5v541_AwesomeAnswer.png?width=64&height=64&crop=smart&auto=webp&s=a6c7ee017a2cbab3e291b81823eb179faeb96b99

award_2adc49e8-d6c9-4923-9293-2bfab1648569

For a winning take and the kind soul who nails a question. Gives %{coin_symbol}100 Coins to both the author and the community.

250

Big Brain Time

https://www.redditstatic.com/gold/awards/icon/Big_Brain_Time_64.png

award_e71deb9c-a466-4743-9a73-48771c000077

2000 IQ

250

Calculating

https://www.redditstatic.com/gold/awards/icon/calculating_b_64.png

award_242c4f2c-6f1c-4387-9b5b-d0249d6ecd36

Something isn’t adding up

250

Confetti

https://www.redditstatic.com/gold/awards/icon/ConfettiBall_64.png

award_1671746c-49e2-4cdd-be4e-ec8892434278

Party time, shower them with sparkly paper

250

Doom

https://www.redditstatic.com/gold/awards/icon/2Dread_64.png

award_e03a0c52-56b5-45df-bd6f-5f2da10cfdc5

A sense of impending doom

250

Duck Dance

https://www.redditstatic.com/gold/awards/icon/DuckDance_64.png

award_c3e02835-9444-4a7f-9e7f-206e8bf0ed99

He do be dancing though

250

Endless Coolness

https://www.redditstatic.com/gold/awards/icon/EndlessCoolness_64.png

award_aac76dbe-2272-4fad-ac06-c077d2d9049e

Cool to the infinity

250

It’s Cute!

https://preview.redd.it/award_images/t5_22cerq/n94bgm83in941_ItsCute.png?width=64&height=64&crop=smart&auto=webp&s=2632d9c9236d0501427072373b789fdb5a59377a

award_cc540de7-dfdb-4a68-9acf-6f9ce6b17d21

You made me UwU.

250

Laser Eyes

https://www.redditstatic.com/gold/awards/icon/emotional_fatality_64.png

award_e1ed6fb9-f23e-4cb4-aad9-70c83e4b1924

250

Mind Blown

https://preview.redd.it/award_images/t5_22cerq/wa987k0p4v541_MindBlown.png?width=64&height=64&crop=smart&auto=webp&s=5bcf973d6d2b64223cc5a2995c95b797bcf68dd2

award_9583d210-a7d0-4f3c-b0c7-369ad579d3d4

When a thing immediately combusts your brain. Gives %{coin_symbol}100 Coins to both the author and the community.

250

Original

https://preview.redd.it/award_images/t5_22cerq/b8xt4z8yajz31_Original.png?width=64&height=64&crop=smart&auto=webp&s=8ca70e1f45c2ddca559d456a74798fcedf36427e

award_d306c865-0d49-4a36-a1ab-a4122a0e3480

When something new and creative wows you. Gives %{coin_symbol}100 Coins to both the author and the community.

250

Pranked!

https://www.redditstatic.com/gold/awards/icon/Pranked_64.png

award_e2250c69-8bd9-4e2f-8fb7-e6630e6c5c8a

Cake direct to face

250

Respect

https://www.redditstatic.com/gold/awards/icon/Respect_64.png

award_c8503d66-6450-40c5-963f-35ced99bd361

Tip of my hat to you

250

That Smile

https://www.redditstatic.com/gold/awards/icon/That_Smile_64.png

award_e11fc833-31fe-4c43-bde8-aead928b4b70

Cute but creepy

250

Timeless Beauty

https://www.redditstatic.com/gold/awards/icon/Timeless_64.png

award_31260000-2f4a-4b40-ad20-f5aa46a577bf

Beauty that’s forever. Gives %{coin_symbol}100 Coins each to the author and the community.

250

Today I Learned

https://preview.redd.it/award_images/t5_22cerq/bph2png4ajz31_TodayILearned.png?width=64&height=64&crop=smart&auto=webp&s=0dec60a8d3226978d4b824226b0c864b663293b3

award_a67d649d-5aa5-407e-a98b-32fd9e3a9696

The more you know… Gives %{coin_symbol}100 Coins to both the author and the community.

250

Vibing

https://www.redditstatic.com/gold/awards/icon/Vibing_64.png

award_3f4e6f36-dacc-4919-b170-9d0201cd258f

I’m catching the vibration

250

Wink Wink

https://www.redditstatic.com/gold/awards/icon/Wink_wink_64.png

award_a8196b8f-1a76-4902-b324-b9473854dade

nudge, nudge

250

Woah Dude

https://www.redditstatic.com/gold/awards/icon/Woah_dude_64.png

award_d88c5520-18d0-4ef0-9a36-41f8617584b0

Sometimes you’re left just going WOAH…

250

Yas Queen

https://preview.redd.it/award_images/t5_22cerq/kthj3e4h3bm41_YasQueen.png?width=64&height=64&crop=smart&auto=webp&s=98b385524aee26412e9dcf25bd20b4cff0eb2376

award_d48aad4b-286f-4a3a-bb41-ec05b3cd87cc

YAAAAAAAAAAASSS.

250

You Dropped This

https://www.redditstatic.com/gold/awards/icon/YouDroppedThis_64.png

award_92d8645c-de2c-44ae-8cd7-7b0c6ab25297

King

250

hehehehe

https://www.redditstatic.com/gold/awards/icon/hehehe_b_64.png

award_435a5692-f508-4b31-8083-ddc576f26ad3

That’s a little funny

250

Blow a Kiss

https://www.redditstatic.com/gold/awards/icon/blow_a_kiss_64.png

award_9ef35273-7942-4199-a76a-3d37f3b52a2e

smooch

300

Coin Gift

https://preview.redd.it/award_images/t5_22cerq/cr1mq4yysv541_CoinGift.png?width=64&height=64&crop=smart&auto=webp&s=d39d0850925a193c9f2ca8203243c694d15fb40a

award_3dd248bc-3438-4c5b-98d4-24421fd6d670

Give the gift of %{coin_symbol}250 Reddit Coins.

300

Crab Rave

https://www.redditstatic.com/gold/awards/icon/CrabRave_64.png

award_f7a4fd5e-7cd1-4c11-a1c9-c18d05902e81

[Happy crab noises]

300

GOAT

https://preview.redd.it/award_images/t5_22cerq/x52x5be57fd41_GOAT.png?width=64&height=64&crop=smart&auto=webp&s=d8a0ff8871eeebadc700284d0186073b8e56ac58

award_cc299d65-77de-4828-89de-708b088349a0

Historical anomaly - greatest in eternity.

300

Heartbreak

https://www.redditstatic.com/gold/awards/icon/heart_break_64.png

award_dc85c1f3-b5aa-4970-9a5d-40304252f79e

Suffering from a broken heart

300

Rocket Like

https://preview.redd.it/award_images/t5_q0gj4/35d17tf5e5f61_oldrocketlike.png?width=64&height=64&crop=smart&auto=webp&s=18520df8e628283caffe872837932b34ff675c8f

award_28e8196b-d4e9-45bc-b612-cd4c7d3ed4b3

When an upvote just isn’t enough, smash the Rocket Like.

300

Table Flip

https://preview.redd.it/award_images/t5_22cerq/a05z7bb9v7i51_TableFlip.png?width=64&height=64&crop=smart&auto=webp&s=3efc978414612ce3b518813a124501b8a204e56b

award_3e000ecb-c1a4-49dc-af14-c8ac2029ca97

ARGH!

300

This

https://preview.redd.it/award_images/t5_22cerq/vu6om0xnb7e41_This.png?width=64&height=64&crop=smart&auto=webp&s=4b2a7c5439da6b4a9e2173bbf3cf9a610538600d

award_68ba1ee3-9baf-4252-be52-b808c1e8bdc4

THIS right here! Join together to give multiple This awards and see the award evolve in its display and shower benefits for the recipient. For every 3 This awards given to a post or comment, the author will get 250 coins.

300

Updoot

https://preview.redd.it/award_images/t5_22cerq/7atjjqpy1mc41_Updoot.png?width=64&height=64&crop=smart&auto=webp&s=f07dcd6402653b86d321cff6ded773cfa13d918a

award_725b427d-320b-4d02-8fb0-8bb7aa7b78aa

Sometimes you just got to doot.

300

Wait What?

https://www.redditstatic.com/gold/awards/icon/wait_what_64.png

award_a3b7d374-68b4-4c77-8a57-e11fd6f26c06

Hold up, what was that?

300

Spit-take

https://www.redditstatic.com/gold/awards/icon/Spits_drink_64.png

award_3409a4c0-ba69-43a0-be9f-27bc27c159cc

Shower them with laughs

325

Super Heart Eyes

https://www.redditstatic.com/gold/awards/icon/Superheart_64.png

award_6220ecfe-4552-4949-aa13-fb1fb7db537c

When the love is out of control.

325

Table Slap

https://www.redditstatic.com/gold/awards/icon/TableSlap_64.png

award_9f928aff-c9f5-4e7e-aa91-8619dce60f1c

When laughter meets percussion

325

To The Stars

https://www.redditstatic.com/gold/awards/icon/Rocket_64.png

award_2bc47247-b107-44a8-a78c-613da21869ff

Boldly go where we haven’t been in a long, long time.

325

Into the Magic Portal

https://www.redditstatic.com/gold/awards/icon/TeleportIn_64.png

award_2ff1fdd0-ff73-47e6-a43c-bde6d4de8fbd

Hope to make it to the other side.

350

Out of the Magic Portal

https://www.redditstatic.com/gold/awards/icon/TeleportOut_64.png

award_7fe72f36-1141-4a39-ba76-0d481889b390

That was fun, but I’m glad to be back

350

Bravo!

https://www.redditstatic.com/gold/awards/icon/SnooClapping_64.png

award_84276b1e-cc8f-484f-a19c-be6c09adc1a5

An amazing showing.

400

Doot 🎵 Doot

https://www.redditstatic.com/gold/awards/icon/Updoot_64.png

award_5b39e8fd-7a58-4cbe-8ca0-bdedd5ed1f5a

Sometimes you just got to dance with the doots.

400

Bless Up (Pro)

https://preview.redd.it/award_images/t5_22cerq/xe5mw55w5v541_BlessUp.png?width=64&height=64&crop=smart&auto=webp&s=54b7d71c74cf41fc8ada4a2110babf8b68d2f172

award_43c43a35-15c5-4f73-91ef-fe538426435a

Prayers up for the blessed. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Brighten My Day

https://www.redditstatic.com/gold/awards/icon/Sunny_64.png

award_9591a26e-b2e4-4ef2-bed4-28ff69246691

The clouds part and the sun shines through. Use the Brighten My Day Award to highlight comments that are a ray of sunshine.

500

Eureka!

https://www.redditstatic.com/gold/awards/icon/Bulb_64.png

award_65f78ca2-45d8-4cb6-bf79-a67beadf2e47

Now that is a bright idea. Use the Eureka Award to highlight comments that are brilliant.

500

Heart Eyes

https://preview.redd.it/award_images/t5_22cerq/12kz7a7j4v541_HeartEyes.png?width=64&height=64&crop=smart&auto=webp&s=02bb7182aad468e16e0a711b594110225679c79e

award_a9009ea5-1a36-42ae-aab2-5967563ee054

For love at first sight. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Helpful (Pro)

https://www.redditstatic.com/gold/awards/icon/Animated_Helpful_64.png

award_2ae56630-cfe0-424e-b810-4945b9145358

Thank you stranger. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Made Me Smile

https://preview.redd.it/award_images/t5_22cerq/hwnbr9l67s941_MadeMeSmile.png?width=64&height=64&crop=smart&auto=webp&s=918705b3b6804a6151b6ce4f8b1c86dfa604a470

award_a7a04d6a-8dd8-41bb-b906-04fa8f144014

When you’re smiling before you know it. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Starry

https://www.redditstatic.com/gold/awards/icon/Starry_64.png

award_0e957fb0-c8f1-4ba1-a8ef-e1e524b60d7d

Use the Starry Award to highlight comments that deserve to stand out from the crowd.

500

Wholesome (Pro)

https://preview.redd.it/award_images/t5_22cerq/0o2j782f00e41_WholesomeSuperpro.png?width=64&height=64&crop=smart&auto=webp&s=2a04235b56e4fbc90106067bfe0d61bd60300c4f

award_1f0462ee-18f5-4f33-89cf-f1f79336a452

When you come across a feel-good thing. Gives %{coin_symbol}100 Coins to both the author and the community.

500

Pot o’ Coins

https://www.redditstatic.com/gold/awards/icon/pot_o_coins_64.png

award_35c78e6e-507b-4f1d-b3d8-ed43840909a8

The treasure at the end of the rainbow. Gives the author 800 Coins to do with as they please.

1000

Argentium

https://www.redditstatic.com/gold/awards/icon/Mithril_64.png

award_4ca5a4e6-8873-4ac5-99b9-71b1d5161a91

Latin for distinguished, this award shimmers like silver and is stronger than steel. It’s for those who deserve outsized recognition. Gives 2,500 Reddit Coins and three months of r/lounge access and ad-free browsing.

20000

Ternion All-Powerful

https://www.redditstatic.com/gold/awards/icon/Trinity_64.png

award_2385c499-a1fb-44ec-b9b7-d260f3dc55de

Legendary level, this award is a no holds barred celebration of something that hits you in the heart, mind, and soul. Some might call it unachievanium. Gives 5,000 Reddit Coins and six months of r/lounge access and ad-free browsing.

50000

clear_vote()

Clear the authenticated user’s vote on the object.

Note

Votes must be cast by humans. That is, API clients proxying a human’s action one-for-one are OK, but bots deciding how to vote on content or amplifying a human’s vote are not. See the reddit rules for more details on what constitutes vote manipulation. [Ref]

Example usage:

submission = reddit.submission("5or86n")
submission.clear_vote()

comment = reddit.comment("dxolpyc")
comment.clear_vote()
property comments: CommentForest

Provide an instance of CommentForest.

This attribute can be used, for example, to obtain a flat list of comments, with any MoreComments removed:

submission.comments.replace_more(limit=0)
comments = submission.comments.list()

Sort order and comment limit can be set with the comment_sort and comment_limit attributes before comments are fetched, including any call to replace_more():

submission.comment_sort = "new"
comments = submission.comments.list()

Note

The appropriate values for "comment_sort" include "confidence", "controversial", "new", "old", "q&a", and "top"

See Extracting comments with PRAW for more on working with a CommentForest.

crosspost(subreddit: praw.models.Subreddit, *, flair_id: Optional[str] = None, flair_text: Optional[str] = None, nsfw: bool = False, send_replies: bool = True, spoiler: bool = False, title: Optional[str] = None) praw.models.Submission

Crosspost the submission to a subreddit.

Note

Be aware you have to be subscribed to the target subreddit.

Parameters
  • subreddit – Name of the subreddit or Subreddit object to crosspost into.

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None).

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • send_replies – When True, messages will be sent to the created submission’s author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

  • title – Title of the submission. Will use this submission’s title if None (default: None).

Returns

A Submission object for the newly created submission.

Example usage:

submission = reddit.submission("5or86n")
cross_post = submission.crosspost("learnprogramming", send_replies=False)

See also

hide()

delete()

Delete the object.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.delete()

submission = reddit.submission("8dmv8z")
submission.delete()
disable_inbox_replies()

Disable inbox replies for the item.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.disable_inbox_replies()

submission = reddit.submission("8dmv8z")
submission.disable_inbox_replies()
downvote()

Downvote the object.

Note

Votes must be cast by humans. That is, API clients proxying a human’s action one-for-one are OK, but bots deciding how to vote on content or amplifying a human’s vote are not. See the reddit rules for more details on what constitutes vote manipulation. [Ref]

Example usage:

submission = reddit.submission("5or86n")
submission.downvote()

comment = reddit.comment("dxolpyc")
comment.downvote()

See also

upvote()

duplicates(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for the submission’s duplicates.

Additional keyword arguments are passed in the initialization of ListingGenerator.

Example usage:

submission = reddit.submission("5or86n")

for duplicate in submission.duplicates():
    # process each duplicate
    ...

See also

upvote()

edit(body: str) Union[praw.models.Comment, praw.models.Submission]

Replace the body of the object with body.

Parameters

body – The Markdown formatted content for the updated object.

Returns

The current instance after updating its attributes.

Example usage:

comment = reddit.comment("dkk4qjd")

# construct the text of an edited comment
# by appending to the old body:
edited_body = comment.body + "Edit: thanks for the gold!"
comment.edit(edited_body)
enable_inbox_replies()

Enable inbox replies for the item.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.enable_inbox_replies()

submission = reddit.submission("8dmv8z")
submission.enable_inbox_replies()
flair() SubmissionFlair

Provide an instance of SubmissionFlair.

This attribute is used to work with flair as a regular user of the subreddit the submission belongs to. Moderators can directly use flair().

For example, to select an arbitrary editable flair text (assuming there is one) and set a custom value try:

choices = submission.flair.choices()
template_id = next(x for x in choices if x["flair_text_editable"])["flair_template_id"]
submission.flair.select(template_id, text="my custom value")
property fullname: str

Return the object’s fullname.

A fullname is an object’s kind mapping like t3 followed by an underscore and the object’s base36 ID, e.g., t1_c5s96e0.

gild() dict

Alias for award() to maintain backwards compatibility.

hide(*, other_submissions: Optional[List[praw.models.Submission]] = None)

Hide Submission.

Parameters

other_submissions – When provided, additionally hide this list of Submission instances as part of a single request (default: None).

Example usage:

submission = reddit.submission("5or86n")
submission.hide()

See also

unhide()

static id_from_url(url: str) str

Return the ID contained within a submission URL.

Parameters

url

A url to a submission in one of the following formats (http urls will also work):

  • "https://redd.it/2gmzqe"

  • "https://reddit.com/comments/2gmzqe/"

  • "https://www.reddit.com/r/redditdev/comments/2gmzqe/praw_https/"

  • "https://www.reddit.com/gallery/2gmzqe"

Raises

InvalidURL if url is not a valid submission URL.

mark_visited()

Mark submission as visited.

This method requires a subscription to reddit premium.

Example usage:

submission = reddit.submission("5or86n")
submission.mark_visited()
mod() SubmissionModeration

Provide an instance of SubmissionModeration.

Example usage:

submission = reddit.submission("8dmv8z")
submission.mod.approve()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

reply(body: str) Optional[Union[praw.models.Comment, praw.models.Message]]

Reply to the object.

Parameters

body – The Markdown formatted content for a comment.

Returns

A Comment or Message object for the newly created comment or message or None if Reddit doesn’t provide one.

Raises

prawcore.exceptions.Forbidden when attempting to reply to some items, such as locked submissions/comments or non-replyable messages.

A None value can be returned if the target is a comment or submission in a quarantined subreddit and the authenticated user has not opt-ed into viewing the content. When this happens the comment will be successfully created on Reddit and can be retried by drawing the comment from the user’s comment history.

Example usage:

submission = reddit.submission("5or86n")
submission.reply("reply")

comment = reddit.comment("dxolpyc")
comment.reply("reply")
report(reason: str)

Report this object to the moderators of its subreddit.

Parameters

reason – The reason for reporting.

Raises

RedditAPIException if reason is longer than 100 characters.

Example usage:

submission = reddit.submission("5or86n")
submission.report("report reason")

comment = reddit.comment("dxolpyc")
comment.report("report reason")
save(*, category: Optional[str] = None)

Save the object.

Parameters

category – The category to save to. If the authenticated user does not have Reddit Premium this value is ignored by Reddit (default: None).

Example usage:

submission = reddit.submission("5or86n")
submission.save(category="view later")

comment = reddit.comment("dxolpyc")
comment.save()

See also

unsave()

Return a shortlink to the submission.

For example, https://redd.it/eorhm is a shortlink for https://www.reddit.com/r/announcements/comments/eorhm/reddit_30_less_typing/.

unhide(*, other_submissions: Optional[List[praw.models.Submission]] = None)

Unhide Submission.

Parameters

other_submissions – When provided, additionally unhide this list of Submission instances as part of a single request (default: None).

Example usage:

submission = reddit.submission("5or86n")
submission.unhide()

See also

hide()

unsave()

Unsave the object.

Example usage:

submission = reddit.submission("5or86n")
submission.unsave()

comment = reddit.comment("dxolpyc")
comment.unsave()

See also

save()

upvote()

Upvote the object.

Note

Votes must be cast by humans. That is, API clients proxying a human’s action one-for-one are OK, but bots deciding how to vote on content or amplifying a human’s vote are not. See the reddit rules for more details on what constitutes vote manipulation. [Ref]

Example usage:

submission = reddit.submission("5or86n")
submission.upvote()

comment = reddit.comment("dxolpyc")
comment.upvote()

See also

downvote()

Subreddit

class praw.models.Subreddit(reddit: praw.Reddit, display_name: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

A class for Subreddits.

To obtain an instance of this class for r/test execute:

subreddit = reddit.subreddit("test")

While r/all is not a real subreddit, it can still be treated like one. The following outputs the titles of the 25 hottest submissions in r/all:

for submission in reddit.subreddit("all").hot(limit=25):
    print(submission.title)

Multiple subreddits can be combined with a + like so:

for submission in reddit.subreddit("redditdev+learnpython").top(time_filter="all"):
    print(submission)

Subreddits can be filtered from combined listings as follows.

Note

These filters are ignored by certain methods, including comments, gilded(), and SubredditStream.comments().

for submission in reddit.subreddit("all-redditdev").new():
    print(submission)

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

can_assign_link_flair

Whether users can assign their own link flair.

can_assign_user_flair

Whether users can assign their own user flair.

created_utc

Time the subreddit was created, represented in Unix Time.

description

Subreddit description, in Markdown.

description_html

Subreddit description, in HTML.

display_name

Name of the subreddit.

id

ID of the subreddit.

name

Fullname of the subreddit.

over18

Whether the subreddit is NSFW.

public_description

Description of the subreddit, shown in searches and on the “You must be invited to visit this community” page (if applicable).

spoilers_enabled

Whether the spoiler tag feature is enabled.

subscribers

Count of subscribers.

user_is_banned

Whether the authenticated user is banned.

user_is_moderator

Whether the authenticated user is a moderator.

user_is_subscriber

Whether the authenticated user is subscribed.

Note

Trying to retrieve attributes of quarantined or private subreddits will result in a 403 error. Trying to retrieve attributes of a banned subreddit will result in a 404 error.

__init__(reddit: praw.Reddit, display_name: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

Initialize a Subreddit instance.

Parameters
  • reddit – An instance of Reddit.

  • display_name – The name of the subreddit.

Note

This class should not be initialized directly. Instead, obtain an instance via: reddit.subreddit("test")

banned() praw.models.reddit.subreddit.SubredditRelationship

Provide an instance of SubredditRelationship.

For example, to ban a user try:

reddit.subreddit("test").banned.add("spez", ban_reason="...")

To list the banned users along with any notes, try:

for ban in reddit.subreddit("test").banned():
    print(f"{ban}: {ban.note}")
collections() praw.models.reddit.collections.SubredditCollections

Provide an instance of SubredditCollections.

To see the permalinks of all Collections that belong to a subreddit, try:

for collection in reddit.subreddit("test").collections:
    print(collection.permalink)

To get a specific Collection by its UUID or permalink, use one of the following:

collection = reddit.subreddit("test").collections("some_uuid")
collection = reddit.subreddit("test").collections(
    permalink="https://reddit.com/r/SUBREDDIT/collection/some_uuid"
)
comments() CommentHelper

Provide an instance of CommentHelper.

For example, to output the author of the 25 most recent comments of r/test execute:

for comment in reddit.subreddit("test").comments(limit=25):
    print(comment.author)
contributor() praw.models.reddit.subreddit.ContributorRelationship

Provide an instance of ContributorRelationship.

Contributors are also known as approved submitters.

To add a contributor try:

reddit.subreddit("test").contributor.add("spez")
controversial(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for controversial items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").controversial(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").controversial(
    time_filter="day"
)
reddit.redditor("spez").controversial(time_filter="month")
reddit.redditor("spez").comments.controversial(time_filter="year")
reddit.redditor("spez").submissions.controversial(time_filter="all")
reddit.subreddit("all").controversial(time_filter="hour")
emoji() SubredditEmoji

Provide an instance of SubredditEmoji.

This attribute can be used to discover all emoji for a subreddit:

for emoji in reddit.subreddit("test").emoji:
    print(emoji)

A single emoji can be lazily retrieved via:

reddit.subreddit("test").emoji["emoji_name"]

Note

Attempting to access attributes of a nonexistent emoji will result in a ClientException.

filters() praw.models.reddit.subreddit.SubredditFilters

Provide an instance of SubredditFilters.

For example, to add a filter, run:

reddit.subreddit("all").filters.add("test")
flair() praw.models.reddit.subreddit.SubredditFlair

Provide an instance of SubredditFlair.

Use this attribute for interacting with a Subreddit’s flair. For example, to list all the flair for a subreddit which you have the flair moderator permission on try:

for flair in reddit.subreddit("test").flair():
    print(flair)

Flair templates can be interacted with through this attribute via:

for template in reddit.subreddit("test").flair.templates:
    print(template)
property fullname: str

Return the object’s fullname.

A fullname is an object’s kind mapping like t3 followed by an underscore and the object’s base36 ID, e.g., t1_c5s96e0.

gilded(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for gilded items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get gilded items in r/test:

for item in reddit.subreddit("test").gilded():
    print(item.id)
hot(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for hot items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").hot()
reddit.multireddit(redditor="samuraisam", name="programming").hot()
reddit.redditor("spez").hot()
reddit.redditor("spez").comments.hot()
reddit.redditor("spez").submissions.hot()
reddit.subreddit("all").hot()
message(*, from_subreddit: Optional[Union[praw.models.Subreddit, str]] = None, message: str, subject: str)

Send a message to a Redditor or a Subreddit’s moderators (modmail).

Parameters
  • from_subreddit

    A Subreddit instance or string to send the message from. When provided, messages are sent from the subreddit rather than from the authenticated user.

    Note

    The authenticated user must be a moderator of the subreddit and have the mail moderator permission.

  • message – The message content.

  • subject – The subject of the message.

For example, to send a private message to u/spez, try:

reddit.redditor("spez").message(subject="TEST", message="test message from PRAW")

To send a message to u/spez from the moderators of r/test try:

reddit.redditor("spez").message(
    subject="TEST", message="test message from r/test", from_subreddit="test"
)

To send a message to the moderators of r/test, try:

reddit.subreddit("test").message(subject="TEST", message="test PM from PRAW")
mod() SubredditModeration

Provide an instance of SubredditModeration.

For example, to accept a moderation invite from r/test:

reddit.subreddit("test").mod.accept_invite()
moderator() praw.models.reddit.subreddit.ModeratorRelationship

Provide an instance of ModeratorRelationship.

For example, to add a moderator try:

reddit.subreddit("test").moderator.add("spez")

To list the moderators along with their permissions try:

for moderator in reddit.subreddit("test").moderator():
    print(f"{moderator}: {moderator.mod_permissions}")
modmail() praw.models.reddit.subreddit.Modmail

Provide an instance of Modmail.

For example, to send a new modmail from r/test to u/spez with the subject "test" along with a message body of "hello":

reddit.subreddit("test").modmail.create(subject="test", body="hello", recipient="spez")
muted() praw.models.reddit.subreddit.SubredditRelationship

Provide an instance of SubredditRelationship.

For example, muted users can be iterated through like so:

for mute in reddit.subreddit("test").muted():
    print(f"{mute}: {mute.note}")
new(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for new items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").new()
reddit.multireddit(redditor="samuraisam", name="programming").new()
reddit.redditor("spez").new()
reddit.redditor("spez").comments.new()
reddit.redditor("spez").submissions.new()
reddit.subreddit("all").new()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

post_requirements() Dict[str, Union[str, int, bool]]

Get the post requirements for a subreddit.

Returns

A dict with the various requirements.

The returned dict contains the following keys:

  • domain_blacklist

  • body_restriction_policy

  • domain_whitelist

  • title_regexes

  • body_blacklisted_strings

  • body_required_strings

  • title_text_min_length

  • is_flair_required

  • title_text_max_length

  • body_regexes

  • link_repost_age

  • body_text_min_length

  • link_restriction_policy

  • body_text_max_length

  • title_required_strings

  • title_blacklisted_strings

  • guidelines_text

  • guidelines_display_policy

For example, to fetch the post requirements for r/test:

print(reddit.subreddit("test").post_requirements)
quaran() praw.models.reddit.subreddit.SubredditQuarantine

Provide an instance of SubredditQuarantine.

This property is named quaran because quarantine is a subreddit attribute returned by Reddit to indicate whether or not a subreddit is quarantined.

To opt-in into a quarantined subreddit:

reddit.subreddit("test").quaran.opt_in()
random() Optional[praw.models.Submission]

Return a random Submission.

Returns None on subreddits that do not support the random feature. One example, at the time of writing, is r/wallpapers.

For example, to get a random submission off of r/AskReddit:

submission = reddit.subreddit("AskReddit").random()
print(submission.title)
random_rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for random rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get random rising submissions for r/test:

for submission in reddit.subreddit("test").random_rising():
    print(submission.title)
rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get rising submissions for r/test:

for submission in reddit.subreddit("test").rising():
    print(submission.title)
rules() SubredditRules

Provide an instance of SubredditRules.

Use this attribute for interacting with a Subreddit’s rules.

For example, to list all the rules for a subreddit:

for rule in reddit.subreddit("test").rules:
    print(rule)

Moderators can also add rules to the subreddit. For example, to make a rule called "No spam" in r/test:

reddit.subreddit("test").rules.mod.add(
    short_name="No spam", kind="all", description="Do not spam. Spam bad"
)
search(query: str, *, sort: str = 'relevance', syntax: str = 'lucene', time_filter: str = 'all', **generator_kwargs: Any) Iterator[praw.models.Submission]

Return a ListingGenerator for items that match query.

Parameters
  • query – The query string to search for.

  • sort – Can be one of: "relevance", "hot", "top", "new", or "comments". (default: "relevance").

  • syntax – Can be one of: "cloudsearch", "lucene", or "plain" (default: "lucene").

  • time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

For more information on building a search query see: https://www.reddit.com/wiki/search

For example, to search all subreddits for "praw" try:

for submission in reddit.subreddit("all").search("praw"):
    print(submission.title)
sticky(*, number: int = 1) praw.models.Submission

Return a Submission object for a sticky of the subreddit.

Parameters

number – Specify which sticky to return. 1 appears at the top (default: 1).

Raises

prawcore.NotFound if the sticky does not exist.

For example, to get the stickied post on r/test:

reddit.subreddit("test").sticky()
stream() praw.models.reddit.subreddit.SubredditStream

Provide an instance of SubredditStream.

Streams can be used to indefinitely retrieve new comments made to a subreddit, like:

for comment in reddit.subreddit("test").stream.comments():
    print(comment)

Additionally, new submissions can be retrieved via the stream. In the following example all submissions are fetched via the special r/all:

for submission in reddit.subreddit("all").stream.submissions():
    print(submission)
stylesheet() praw.models.reddit.subreddit.SubredditStylesheet

Provide an instance of SubredditStylesheet.

For example, to add the css data .test{color:blue} to the existing stylesheet:

subreddit = reddit.subreddit("test")
stylesheet = subreddit.stylesheet()
stylesheet.stylesheet += ".test{color:blue}"
subreddit.stylesheet.update(stylesheet.stylesheet)
submit(title: str, *, collection_id: Optional[str] = None, discussion_type: Optional[str] = None, draft_id: Optional[str] = None, flair_id: Optional[str] = None, flair_text: Optional[str] = None, inline_media: Optional[Dict[str, praw.models.InlineMedia]] = None, nsfw: bool = False, resubmit: bool = True, selftext: Optional[str] = None, send_replies: bool = True, spoiler: bool = False, url: Optional[str] = None) praw.models.Submission

Add a submission to the Subreddit.

Parameters
  • title – The title of the submission.

  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • draft_id – The ID of a draft to submit.

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • inline_media – A dict of InlineMedia objects where the key is the placeholder name in selftext.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • resubmit – When False, an error will occur if the URL has already been submitted (default: True).

  • selftext – The Markdown formatted content for a text submission. Use an empty string, "", to make a title-only submission.

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

  • url – The URL for a link submission.

Returns

A Submission object for the newly created submission.

Either selftext or url can be provided, but not both.

For example, to submit a URL to r/test do:

title = "PRAW documentation"
url = "https://praw.readthedocs.io"
reddit.subreddit("test").submit(title, url=url)

For example, to submit a self post with inline media do:

from praw.models import InlineGif, InlineImage, InlineVideo

gif = InlineGif(path="path/to/image.gif", caption="optional caption")
image = InlineImage(path="path/to/image.jpg", caption="optional caption")
video = InlineVideo(path="path/to/video.mp4", caption="optional caption")
selftext = "Text with a gif {gif1} an image {image1} and a video {video1} inline"
media = {"gif1": gif, "image1": image, "video1": video}
reddit.subreddit("test").submit("title", inline_media=media, selftext=selftext)

Note

Inserted media will have a padding of \\n\\n automatically added. This is due to the weirdness with Reddit’s API. Using the example above, the result selftext body will look like so:

Text with a gif

![gif](u1rchuphryq51 "optional caption")

an image

![img](srnr8tshryq51 "optional caption")

and video

![video](gmc7rvthryq51 "optional caption")

inline

Note

To submit a post to a subreddit with the "news" flair, you can get the flair id like this:

choices = list(subreddit.flair.link_templates.user_selectable())
template_id = next(x for x in choices if x["flair_text"] == "news")["flair_template_id"]
subreddit.submit("title", flair_id=template_id, url="https://www.news.com/")

See also

Add an image gallery submission to the subreddit.

Parameters
  • title – The title of the submission.

  • images – The images to post in dict with the following structure: {"image_path": "path", "caption": "caption", "outbound_url": "url"}, only image_path is required.

  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked asa spoiler (default: False).

Returns

A Submission object for the newly created submission.

Raises

ClientException if image_path in images refers to a file that is not an image.

For example, to submit an image gallery to r/test do:

title = "My favorite pictures"
image = "/path/to/image.png"
image2 = "/path/to/image2.png"
image3 = "/path/to/image3.png"
images = [
    {"image_path": image},
    {
        "image_path": image2,
        "caption": "Image caption 2",
    },
    {
        "image_path": image3,
        "caption": "Image caption 3",
        "outbound_url": "https://example.com/link3",
    },
]
reddit.subreddit("test").submit_gallery(title, images)

See also

submit_image(title: str, image_path: str, *, collection_id: Optional[str] = None, discussion_type: Optional[str] = None, flair_id: Optional[str] = None, flair_text: Optional[str] = None, nsfw: bool = False, resubmit: bool = True, send_replies: bool = True, spoiler: bool = False, timeout: int = 10, without_websockets: bool = False)

Add an image submission to the subreddit.

Parameters
  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • image_path – The path to an image, to upload and post.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • resubmit – When False, an error will occur if the URL has already been submitted (default: True).

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

  • timeout – Specifies a particular timeout, in seconds. Use to avoid “Websocket error” exceptions (default: 10).

  • title – The title of the submission.

  • without_websockets – Set to True to disable use of WebSockets (see note below for an explanation). If True, this method doesn’t return anything (default: False).

Returns

A Submission object for the newly created submission, unless without_websockets is True.

Raises

ClientException if image_path refers to a file that is not an image.

Note

Reddit’s API uses WebSockets to respond with the link of the newly created post. If this fails, the method will raise WebSocketException. Occasionally, the Reddit post will still be created. More often, there is an error with the image file. If you frequently get exceptions but successfully created posts, try setting the timeout parameter to a value above 10.

To disable the use of WebSockets, set without_websockets=True. This will make the method return None, though the post will still be created. You may wish to do this if you are running your program in a restricted network environment, or using a proxy that doesn’t support WebSockets connections.

For example, to submit an image to r/test do:

title = "My favorite picture"
image = "/path/to/image.png"
reddit.subreddit("test").submit_image(title, image)

See also

submit_poll(title: str, *, collection_id: Optional[str] = None, discussion_type: Optional[str] = None, duration: int, flair_id: Optional[str] = None, flair_text: Optional[str] = None, nsfw: bool = False, options: List[str], resubmit: bool = True, selftext: str, send_replies: bool = True, spoiler: bool = False)

Add a poll submission to the subreddit.

Parameters
  • title – The title of the submission.

  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • duration – The number of days the poll should accept votes, as an int. Valid values are between 1 and 7, inclusive.

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • options – A list of two to six poll options as str.

  • resubmit – When False, an error will occur if the URL has already been submitted (default: True).

  • selftext – The Markdown formatted content for the submission. Use an empty string, "", to make a submission with no text contents.

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

Returns

A Submission object for the newly created submission.

For example, to submit a poll to r/test do:

title = "Do you like PRAW?"
reddit.subreddit("test").submit_poll(
    title, selftext="", options=["Yes", "No"], duration=3
)

See also

submit_video(title: str, video_path: str, *, collection_id: Optional[str] = None, discussion_type: Optional[str] = None, flair_id: Optional[str] = None, flair_text: Optional[str] = None, nsfw: bool = False, resubmit: bool = True, send_replies: bool = True, spoiler: bool = False, thumbnail_path: Optional[str] = None, timeout: int = 10, videogif: bool = False, without_websockets: bool = False)

Add a video or videogif submission to the subreddit.

Parameters
  • title – The title of the submission.

  • video_path – The path to a video, to upload and post.

  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • resubmit – When False, an error will occur if the URL has already been submitted (default: True).

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

  • thumbnail_path – The path to an image, to be uploaded and used as the thumbnail for this video. If not provided, the PRAW logo will be used as the thumbnail.

  • timeout – Specifies a particular timeout, in seconds. Use to avoid “Websocket error” exceptions (default: 10).

  • videogif – If True, the video is uploaded as a videogif, which is essentially a silent video (default: False).

  • without_websockets – Set to True to disable use of WebSockets (see note below for an explanation). If True, this method doesn’t return anything (default: False).

Returns

A Submission object for the newly created submission, unless without_websockets is True.

Raises

ClientException if video_path refers to a file that is not a video.

Note

Reddit’s API uses WebSockets to respond with the link of the newly created post. If this fails, the method will raise WebSocketException. Occasionally, the Reddit post will still be created. More often, there is an error with the image file. If you frequently get exceptions but successfully created posts, try setting the timeout parameter to a value above 10.

To disable the use of WebSockets, set without_websockets=True. This will make the method return None, though the post will still be created. You may wish to do this if you are running your program in a restricted network environment, or using a proxy that doesn’t support WebSockets connections.

For example, to submit a video to r/test do:

title = "My favorite movie"
video = "/path/to/video.mp4"
reddit.subreddit("test").submit_video(title, video)

See also

subscribe(*, other_subreddits: Optional[List[praw.models.Subreddit]] = None)

Subscribe to the subreddit.

Parameters

other_subreddits – When provided, also subscribe to the provided list of subreddits.

For example, to subscribe to r/test:

reddit.subreddit("test").subscribe()
top(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for top items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").top(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").top(time_filter="day")
reddit.redditor("spez").top(time_filter="month")
reddit.redditor("spez").comments.top(time_filter="year")
reddit.redditor("spez").submissions.top(time_filter="all")
reddit.subreddit("all").top(time_filter="hour")
traffic() Dict[str, List[List[int]]]

Return a dictionary of the Subreddit’s traffic statistics.

Raises

prawcore.NotFound when the traffic stats aren’t available to the authenticated user, that is, they are not public and the authenticated user is not a moderator of the subreddit.

The traffic method returns a dict with three keys. The keys are day, hour and month. Each key contains a list of lists with 3 or 4 values. The first value is a timestamp indicating the start of the category (start of the day for the day key, start of the hour for the hour key, etc.). The second, third, and fourth values indicate the unique pageviews, total pageviews, and subscribers, respectively.

Note

The hour key does not contain subscribers, and therefore each sub-list contains three values.

For example, to get the traffic stats for r/test:

stats = reddit.subreddit("test").traffic()
unsubscribe(*, other_subreddits: Optional[List[praw.models.Subreddit]] = None)

Unsubscribe from the subreddit.

Parameters

other_subreddits – When provided, also unsubscribe from the provided list of subreddits.

To unsubscribe from r/test:

reddit.subreddit("test").unsubscribe()
widgets() praw.models.SubredditWidgets

Provide an instance of SubredditWidgets.

Example usage

Get all sidebar widgets:

for widget in reddit.subreddit("test").widgets.sidebar:
    print(widget)

Get ID card widget:

print(reddit.subreddit("test").widgets.id_card)
wiki() praw.models.reddit.subreddit.SubredditWiki

Provide an instance of SubredditWiki.

This attribute can be used to discover all wikipages for a subreddit:

for wikipage in reddit.subreddit("test").wiki:
    print(wikipage)

To fetch the content for a given wikipage try:

wikipage = reddit.subreddit("test").wiki["proof"]
print(wikipage.content_md)

WikiPage

class praw.models.reddit.wikipage.WikiPage(reddit: praw.Reddit, subreddit: praw.models.Subreddit, name: str, revision: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

An individual WikiPage object.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

content_html

The contents of the wiki page, as HTML.

content_md

The contents of the wiki page, as Markdown.

may_revise

A bool representing whether or not the authenticated user may edit the wiki page.

name

The name of the wiki page.

revision_by

The Redditor who authored this revision of the wiki page.

revision_date

The time of this revision, in Unix Time.

subreddit

The Subreddit this wiki page belongs to.

__init__(reddit: praw.Reddit, subreddit: praw.models.Subreddit, name: str, revision: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

Initialize a WikiPage instance.

Parameters

revision – A specific revision ID to fetch. By default, fetches the most recent revision.

discussions(**generator_kwargs: Any) Iterator[praw.models.Submission]

Return a ListingGenerator for discussions of a wiki page.

Discussions are site-wide links to a wiki page.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To view the titles of discussions of the page "praw_test" in r/test, try:

for submission in reddit.subreddit("test").wiki["praw_test"].discussions():
    print(submission.title)
edit(*, content: str, reason: Optional[str] = None, **other_settings: Any)

Edit this wiki page’s contents.

Parameters
  • content – The updated Markdown content of the page.

  • reason – The reason for the revision.

  • other_settings – Additional keyword arguments to pass.

For example, to replace the first wiki page of r/test with the phrase "test wiki page":

page = next(iter(reddit.subreddit("test").wiki))
page.edit(content="test wiki page")
mod() WikiPageModeration

Provide an instance of WikiPageModeration.

For example, to add u/spez as an editor on the wikipage "praw_test" try:

reddit.subreddit("test").wiki["praw_test"].mod.add("spez")
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

revision(revision: str)

Return a specific version of this page by revision ID.

To view revision "1234abc" of "praw_test" in r/test:

page = reddit.subreddit("test").wiki["praw_test"].revision("1234abc")
revisions(**generator_kwargs: Union[str, int, Dict[str, str]]) Generator[WikiPage, None, None]

Return a ListingGenerator for page revisions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To view the wiki revisions for "praw_test" in r/test try:

for item in reddit.subreddit("test").wiki["praw_test"].revisions():
    print(item)

To get WikiPage objects for each revision:

for item in reddit.subreddit("test").wiki["praw_test"].revisions():
    print(item["page"])

Exceptions in PRAW

In addition to exceptions under the praw.exceptions namespace shown below, exceptions might be raised that inherit from prawcore.PrawcoreException. Please see the following resource for information on those exceptions: https://github.com/praw-dev/prawcore/blob/master/prawcore/exceptions.py

praw.exceptions

PRAW exception classes.

Includes two main exceptions: RedditAPIException for when something goes wrong on the server side, and ClientException when something goes wrong on the client side. Both of these classes extend PRAWException.

All other exceptions are subclassed from ClientException.

exception praw.exceptions.APIException(items: Union[List[Union[RedditErrorItem, List[str], str]], str], *optional_args: str)

Old class preserved for alias purposes.

Deprecated since version 7.0: Class APIException has been deprecated in favor of RedditAPIException. This class will be removed in PRAW 8.0.

__init__(items: Union[List[Union[RedditErrorItem, List[str], str]], str], *optional_args: str)

Initialize a RedditAPIException instance.

Parameters
  • items – Either a list of instances of RedditErrorItem or a list containing lists of unformed errors.

  • optional_args – Takes the second and third arguments that APIException used to take.

property error_type: str

Get error_type.

Deprecated since version 7.0: Accessing attributes through instances of RedditAPIException is deprecated. This behavior will be removed in PRAW 8.0. Check out the PRAW 7 Migration tutorial on how to migrate code from this behavior.

property field: str

Get field.

Deprecated since version 7.0: Accessing attributes through instances of RedditAPIException is deprecated. This behavior will be removed in PRAW 8.0. Check out the PRAW 7 Migration tutorial on how to migrate code from this behavior.

property message: str

Get message.

Deprecated since version 7.0: Accessing attributes through instances of RedditAPIException is deprecated. This behavior will be removed in PRAW 8.0. Check out the PRAW 7 Migration tutorial on how to migrate code from this behavior.

static parse_exception_list(exceptions: List[Union[RedditErrorItem, List[str]]])

Covert an exception list into a RedditErrorItem list.

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.ClientException

Indicate exceptions that don’t involve interaction with Reddit’s API.

__init__(*args, **kwargs)
with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.DuplicateReplaceException

Indicate exceptions that involve the replacement of MoreComments.

__init__()

Initialize a DuplicateReplaceException instance.

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.InvalidFlairTemplateID(template_id: str)

Indicate exceptions where an invalid flair template ID is given.

__init__(template_id: str)

Initialize an InvalidFlairTemplateID instance.

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.InvalidImplicitAuth

Indicate exceptions where an implicit auth type is used incorrectly.

__init__()

Initialize an InvalidImplicitAuth instance.

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.InvalidURL(url: str, *, message: str = 'Invalid URL: {}')

Indicate exceptions where an invalid URL is entered.

__init__(url: str, *, message: str = 'Invalid URL: {}')

Initialize an InvalidURL instance.

Parameters
  • url – The invalid URL.

  • message – The message to display. Must contain a format identifier ({} or {0}) (default: "Invalid URL: {}").

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.MediaPostFailed

Indicate exceptions where media uploads failed..

__init__()

Initialize a MediaPostFailed instance.

property original_exception: Exception

Access the original_exception attribute (now deprecated).

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.MissingRequiredAttributeException

Indicate exceptions caused by not including a required attribute.

__init__(*args, **kwargs)
with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.PRAWException

The base PRAW Exception that all other exception classes extend.

__init__(*args, **kwargs)
with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.ReadOnlyException

Raised when a method call requires read_only mode to be disabled.

__init__(*args, **kwargs)
with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.RedditAPIException(items: Union[List[Union[RedditErrorItem, List[str], str]], str], *optional_args: str)

Container for error messages from Reddit’s API.

__init__(items: Union[List[Union[RedditErrorItem, List[str], str]], str], *optional_args: str)

Initialize a RedditAPIException instance.

Parameters
  • items – Either a list of instances of RedditErrorItem or a list containing lists of unformed errors.

  • optional_args – Takes the second and third arguments that APIException used to take.

property error_type: str

Get error_type.

Deprecated since version 7.0: Accessing attributes through instances of RedditAPIException is deprecated. This behavior will be removed in PRAW 8.0. Check out the PRAW 7 Migration tutorial on how to migrate code from this behavior.

property field: str

Get field.

Deprecated since version 7.0: Accessing attributes through instances of RedditAPIException is deprecated. This behavior will be removed in PRAW 8.0. Check out the PRAW 7 Migration tutorial on how to migrate code from this behavior.

property message: str

Get message.

Deprecated since version 7.0: Accessing attributes through instances of RedditAPIException is deprecated. This behavior will be removed in PRAW 8.0. Check out the PRAW 7 Migration tutorial on how to migrate code from this behavior.

static parse_exception_list(exceptions: List[Union[RedditErrorItem, List[str]]])

Covert an exception list into a RedditErrorItem list.

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class praw.exceptions.RedditErrorItem(error_type: str, *, field: Optional[str] = None, message: Optional[str] = None)

Represents a single error returned from Reddit’s API.

__init__(error_type: str, *, field: Optional[str] = None, message: Optional[str] = None)

Initialize a RedditErrorItem instance.

Parameters
  • error_type – The error type set on Reddit’s end.

  • field – The input field associated with the error, if available.

  • message – The associated message for the error.

property error_message: str

Get the completed error message string.

exception praw.exceptions.TooLargeMediaException(*, actual: int, maximum_size: int)

Indicate exceptions from uploading media that’s too large.

__init__(*, actual: int, maximum_size: int)

Initialize a TooLargeMediaException instance.

Parameters
  • actual – The actual size of the uploaded media.

  • maximum_size – The maximum size of the uploaded media.

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception praw.exceptions.WebSocketException(message: str, exception: Optional[Exception])

Indicate exceptions caused by use of WebSockets.

__init__(message: str, exception: Optional[Exception])

Initialize a WebSocketException instance.

Parameters
  • message – The exception message.

  • exception

    The exception thrown by the websocket library.

    Note

    This parameter is deprecated. It will be removed in PRAW 8.0.

property original_exception: Exception

Access the original_exception attribute (now deprecated).

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

Other Classes

The following list of classes are provided here for complete documentation. You should not likely need to work with these classes directly, but rather through instances of them bound to an attribute of one of the PRAW models.

Collection

class praw.models.Collection(reddit: praw.Reddit, _data: Dict[str, Any] = None, collection_id: Optional[str] = None, permalink: Optional[str] = None)

Class to represent a Collection.

Obtain an instance via:

collection = reddit.subreddit("test").collections("some_uuid")

or

collection = reddit.subreddit("test").collections(
    permalink="https://reddit.com/r/SUBREDDIT/collection/some_uuid"
)

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

author

The Redditor who created the collection.

collection_id

The UUID of the collection.

created_at_utc

Time the collection was created, represented in Unix Time.

description

The collection description.

display_layout

The collection display layout.

last_update_utc

Time the collection was last updated, represented in Unix Time.

link_ids

A list of Submission fullnames.

permalink

The collection’s permalink (to view on the web).

sorted_links

An iterable listing of the posts in this collection.

title

The title of the collection.

__init__(reddit: praw.Reddit, _data: Dict[str, Any] = None, collection_id: Optional[str] = None, permalink: Optional[str] = None)

Initialize a Collection instance.

Parameters
__iter__() Generator[Any, None, None]

Provide a way to iterate over the posts in this Collection.

Example usage:

collection = reddit.subreddit("test").collections("some_uuid")
for submission in collection:
    print(submission.title, submission.permalink)
__len__() int

Get the number of posts in this Collection.

Example usage:

collection = reddit.subreddit("test").collections("some_uuid")
print(len(collection))
follow()

Follow this Collection.

Example usage:

reddit.subreddit("test").collections("some_uuid").follow()

See also

unfollow()

mod() CollectionModeration

Get an instance of CollectionModeration.

Provides access to various methods, including add_post(), delete(), reorder(), and update_title().

Example usage:

collection = reddit.subreddit("test").collections("some_uuid")
collection.mod.update_title("My new title!")
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

subreddit() praw.models.Subreddit

Get the subreddit that this collection belongs to.

For example:

collection = reddit.subreddit("test").collections("some_uuid")
subreddit = collection.subreddit
unfollow()

Unfollow this Collection.

Example usage:

reddit.subreddit("test").collections("some_uuid").unfollow()

See also

follow()

CollectionModeration

class praw.models.reddit.collections.CollectionModeration(reddit: praw.Reddit, collection_id: str)

Class to support moderation actions on a Collection.

Obtain an instance via:

reddit.subreddit("test").collections("some_uuid").mod
__init__(reddit: praw.Reddit, collection_id: str)

Initialize a CollectionModeration instance.

Parameters

collection_id – The ID of a Collection.

add_post(submission: praw.models.Submission)

Add a post to the collection.

Parameters

submission – The post to add, a Submission, its permalink as a str, its fullname as a str, or its ID as a str.

Example usage:

collection = reddit.subreddit("test").collections("some_uuid")
collection.mod.add_post("bgibu9")

See also

remove_post()

delete()

Delete this collection.

Example usage:

reddit.subreddit("test").collections("some_uuid").mod.delete()

See also

create()

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

remove_post(submission: praw.models.Submission)

Remove a post from the collection.

Parameters

submission – The post to remove, a Submission, its permalink as a str, its fullname as a str, or its ID as a str.

Example usage:

collection = reddit.subreddit("test").collections("some_uuid")
collection.mod.remove_post("bgibu9")

See also

add_post()

reorder(links: List[Union[str, praw.models.Submission]])

Reorder posts in the collection.

Parameters

links – A list of Submissions or a str that is either a fullname or an ID.

Example usage:

collection = reddit.subreddit("test").collections("some_uuid")
current_order = collection.link_ids
new_order = reversed(current_order)
collection.mod.reorder(new_order)
update_description(description: str)

Update the collection’s description.

Parameters

description – The new description.

Example usage:

collection = reddit.subreddit("test").collections("some_uuid")
collection.mod.update_description("Please enjoy these links!")

See also

update_title()

update_display_layout(display_layout: str)

Update the collection’s display layout.

Parameters

display_layout – Either "TIMELINE" for events or discussions or "GALLERY" for images or memes. Passing None will clear the set layout and collection.display_layout will be None, however, the collection will appear on Reddit as if display_layout is set to "TIMELINE".

Example usage:

collection = reddit.subreddit("test").collections("some_uuid")
collection.mod.update_display_layout("GALLERY")
update_title(title: str)

Update the collection’s title.

Parameters

title – The new title.

Example usage:

collection = reddit.subreddit("test").collections("some_uuid")
collection.mod.update_title("Titley McTitleface")

SubredditCollections

class praw.models.reddit.collections.SubredditCollections(reddit: praw.Reddit, subreddit: praw.models.Subreddit, _data: Optional[Dict[str, Any]] = None)

Class to represent a Subreddit’s Collections.

Obtain an instance via:

reddit.subreddit("test").collections
__call__(collection_id: Optional[str] = None, permalink: Optional[str] = None)

Return the Collection with the specified ID.

Parameters
  • collection_id – The ID of a Collection (default: None).

  • permalink – The permalink of a collection (default: None).

Returns

The specified Collection.

Exactly one of collection_id or permalink is required.

Example usage:

subreddit = reddit.subreddit("test")

uuid = "847e4548-a3b5-4ad7-afb4-edbfc2ed0a6b"
collection = subreddit.collections(uuid)
print(collection.title)
print(collection.description)

permalink = "https://www.reddit.com/r/SUBREDDIT/collection/" + uuid
collection = subreddit.collections(permalink=permalink)
print(collection.title)
print(collection.description)
__init__(reddit: praw.Reddit, subreddit: praw.models.Subreddit, _data: Optional[Dict[str, Any]] = None)

Initialize a SubredditCollections instance.

__iter__()

Iterate over the Subreddit’s Collections.

Example usage:

for collection in reddit.subreddit("test").collections:
    print(collection.permalink)
mod() SubredditCollectionsModeration

Get an instance of SubredditCollectionsModeration.

Provides create():

my_sub = reddit.subreddit("test")
new_collection = my_sub.collections.mod.create(title="Title", description="desc")
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

SubredditCollectionsModeration

class praw.models.reddit.collections.SubredditCollectionsModeration(reddit: praw.Reddit, sub_fullname: str, _data: Optional[Dict[str, Any]] = None)

Class to represent moderator actions on a Subreddit’s Collections.

Obtain an instance via:

reddit.subreddit("test").collections.mod
__init__(reddit: praw.Reddit, sub_fullname: str, _data: Optional[Dict[str, Any]] = None)

Initialize a SubredditCollectionsModeration instance.

create(*, description: str, display_layout: Optional[str] = None, title: str)

Create a new Collection.

The authenticated account must have appropriate moderator permissions in the subreddit this collection belongs to.

Parameters
  • description – The description, up to 500 characters.

  • display_layout – Either "TIMELINE" for events or discussions or "GALLERY" for images or memes. Passing "" or None will make the collection appear on Reddit as if this is set to "TIMELINE" (default: None).

  • title – The title of the collection, up to 300 characters.

Returns

The newly created Collection.

Example usage:

my_sub = reddit.subreddit("test")
new_collection = my_sub.collections.mod.create(title="Title", description="desc")
new_collection.mod.add_post("bgibu9")

To specify the display layout as "GALLERY" when creating the collection:

my_sub = reddit.subreddit("test")
new_collection = my_sub.collections.mod.create(
    title="Title", description="desc", display_layout="GALLERY"
)
new_collection.mod.add_post("bgibu9")

See also

delete()

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

SubmissionFlair

class praw.models.reddit.submission.SubmissionFlair(submission: praw.models.Submission)

Provide a set of functions pertaining to Submission flair.

__init__(submission: praw.models.Submission)

Initialize a SubmissionFlair instance.

Parameters

submission – The Submission associated with the flair functions.

choices() List[Dict[str, Union[bool, list, str]]]

Return list of available flair choices.

Choices are required in order to use select().

For example:

choices = submission.flair.choices()
select(flair_template_id: str, *, text: Optional[str] = None)

Select flair for submission.

Parameters
  • flair_template_id – The flair template to select. The possible values can be discovered through choices().

  • text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None).

For example, to select an arbitrary editable flair text (assuming there is one) and set a custom value try:

choices = submission.flair.choices()
template_id = next(x for x in choices if x["flair_text_editable"])["flair_template_id"]
submission.flair.select(template_id, text="my custom value")

SubredditFlair

class praw.models.reddit.subreddit.SubredditFlair(subreddit: praw.models.Subreddit)

Provide a set of functions to interact with a Subreddit’s flair.

__call__(redditor: Optional[Union[praw.models.Redditor, str]] = None, **generator_kwargs: Any) Iterator[praw.models.Redditor]

Return a ListingGenerator for Redditors and their flairs.

Parameters

redditor – When provided, yield at most a single Redditor instance (default: None).

Additional keyword arguments are passed in the initialization of ListingGenerator.

Usage:

for flair in reddit.subreddit("test").flair(limit=None):
    print(flair)
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditFlair instance.

Parameters

subreddit – The subreddit whose flair to work with.

configure(*, link_position: str = 'left', link_self_assign: bool = False, position: str = 'right', self_assign: bool = False, **settings: Any)

Update the Subreddit’s flair configuration.

Parameters
  • link_position – One of "left", "right", or False to disable (default: "left").

  • link_self_assign – Permit self assignment of link flair (default: False).

  • position – One of "left", "right", or False to disable (default: "right").

  • self_assign – Permit self assignment of user flair (default: False).

subreddit = reddit.subreddit("test")
subreddit.flair.configure(link_position="right", self_assign=True)

Additional keyword arguments can be provided to handle new settings as Reddit introduces them.

delete(redditor: Union[praw.models.Redditor, str])

Delete flair for a Redditor.

Parameters

redditor – A redditor name or Redditor instance.

See also

update() to delete the flair of many redditors at once.

delete_all() List[Dict[str, Union[str, bool, Dict[str, str]]]]

Delete all Redditor flair in the Subreddit.

Returns

List of dictionaries indicating the success or failure of each delete.

Provide an instance of SubredditLinkFlairTemplates.

Use this attribute for interacting with a Subreddit’s link flair templates. For example to list all the link flair templates for a subreddit which you have the flair moderator permission on try:

for template in reddit.subreddit("test").flair.link_templates:
    print(template)
set(redditor: Union[praw.models.Redditor, str], *, css_class: str = '', flair_template_id: Optional[str] = None, text: str = '')

Set flair for a Redditor.

Parameters
  • redditor – A redditor name or Redditor instance.

  • text – The flair text to associate with the Redditor or Submission (default: "").

  • css_class – The css class to associate with the flair html (default: ""). Use either this or flair_template_id.

  • flair_template_id – The ID of the flair template to be used (default: None). Use either this or css_class.

This method can only be used by an authenticated user who is a moderator of the associated Subreddit.

For example:

reddit.subreddit("test").flair.set("bboe", text="PRAW author", css_class="mods")
template = "6bd28436-1aa7-11e9-9902-0e05ab0fad46"
reddit.subreddit("test").flair.set(
    "spez", text="Reddit CEO", flair_template_id=template
)
templates() praw.models.reddit.subreddit.SubredditRedditorFlairTemplates

Provide an instance of SubredditRedditorFlairTemplates.

Use this attribute for interacting with a Subreddit’s flair templates. For example to list all the flair templates for a subreddit which you have the flair moderator permission on try:

for template in reddit.subreddit("test").flair.templates:
    print(template)
update(flair_list: Iterator[Union[str, praw.models.Redditor, Dict[str, Union[str, praw.models.Redditor]]]], *, text: str = '', css_class: str = '') List[Dict[str, Union[str, bool, Dict[str, str]]]]

Set or clear the flair for many redditors at once.

Parameters
  • flair_list

    Each item in this list should be either:

    • The name of a redditor.

    • An instance of Redditor.

    • A dictionary mapping keys "user", "flair_text", and "flair_css_class" to their respective values. The "user" key should map to a redditor, as described above. When a dictionary isn’t provided, or the dictionary is missing either "flair_text" or "flair_css_class" keys, the default values will come from the other arguments.

  • css_class – The css class to use when not explicitly provided in flair_list (default: "").

  • text – The flair text to use when not explicitly provided in flair_list (default: "").

Returns

List of dictionaries indicating the success or failure of each update.

For example, to clear the flair text, and set the "praw" flair css class on a few users try:

subreddit.flair.update(["bboe", "spez", "spladug"], css_class="praw")

SubredditFlairTemplates

class praw.models.reddit.subreddit.SubredditFlairTemplates(subreddit: praw.models.Subreddit)

Provide functions to interact with a Subreddit’s flair templates.

__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditFlairTemplates instance.

Parameters

subreddit – The subreddit whose flair templates to work with.

Note

This class should not be initialized directly. Instead, obtain an instance via: reddit.subreddit("test").flair.templates or reddit.subreddit("test").flair.link_templates.

__iter__()

Abstract method to return flair templates.

delete(template_id: str)

Remove a flair template provided by template_id.

For example, to delete the first Redditor flair template listed, try:

template_info = list(subreddit.flair.templates)[0]
subreddit.flair.templates.delete(template_info["id"])
static flair_type(is_link: bool) str

Return "LINK_FLAIR" or "USER_FLAIR" depending on is_link value.

update(template_id: str, *, allowable_content: Optional[str] = None, background_color: Optional[str] = None, css_class: Optional[str] = None, fetch: bool = True, max_emojis: Optional[int] = None, mod_only: Optional[bool] = None, text: Optional[str] = None, text_color: Optional[str] = None, text_editable: Optional[bool] = None)

Update the flair template provided by template_id.

Parameters
  • template_id – The flair template to update. If not valid then an exception will be thrown.

  • allowable_content – If specified, most be one of "all", "emoji", or "text" to restrict content to that type. If set to "emoji" then the "text" param must be a valid emoji string, for example, ":snoo:".

  • background_color – The flair template’s new background color, as a hex color.

  • css_class – The flair template’s new css_class (default: "").

  • fetch – Whether PRAW will fetch existing information on the existing flair before updating (default: True).

  • max_emojis – Maximum emojis in the flair (Reddit defaults this value to 10).

  • mod_only – Indicate if the flair can only be used by moderators.

  • text – The flair template’s new text.

  • text_color – The flair template’s new text color, either "light" or "dark".

  • text_editable – Indicate if the flair text can be modified for each redditor that sets it (default: False).

Warning

If parameter fetch is set to False, all parameters not provided will be reset to their default (None or False) values.

For example, to make a user flair template text editable, try:

template_info = list(subreddit.flair.templates)[0]
subreddit.flair.templates.update(
    template_info["id"],
    text=template_info["flair_text"],
    text_editable=True,
)

SubredditLinkFlairTemplates

class praw.models.reddit.subreddit.SubredditLinkFlairTemplates(subreddit: praw.models.Subreddit)

Provide functions to interact with link flair templates.

__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditFlairTemplates instance.

Parameters

subreddit – The subreddit whose flair templates to work with.

Note

This class should not be initialized directly. Instead, obtain an instance via: reddit.subreddit("test").flair.templates or reddit.subreddit("test").flair.link_templates.

__iter__() Generator[Dict[str, Union[str, int, bool, List[Dict[str, str]]]], None, None]

Iterate through the link flair templates as a moderator.

For example:

for template in reddit.subreddit("test").flair.link_templates:
    print(template)
add(text: str, *, allowable_content: Optional[str] = None, background_color: Optional[str] = None, css_class: str = '', max_emojis: Optional[int] = None, mod_only: Optional[bool] = None, text_color: Optional[str] = None, text_editable: bool = False)

Add a link flair template to the associated subreddit.

Parameters
  • text – The flair template’s text.

  • allowable_content – If specified, most be one of "all", "emoji", or "text" to restrict content to that type. If set to "emoji" then the "text" param must be a valid emoji string, for example, ":snoo:".

  • background_color – The flair template’s new background color, as a hex color.

  • css_class – The flair template’s css_class (default: "").

  • max_emojis – Maximum emojis in the flair (Reddit defaults this value to 10).

  • mod_only – Indicate if the flair can only be used by moderators.

  • text_color – The flair template’s new text color, either "light" or "dark".

  • text_editable – Indicate if the flair text can be modified for each redditor that sets it (default: False).

For example, to add an editable link flair try:

reddit.subreddit("test").flair.link_templates.add(
    "PRAW",
    css_class="praw",
    text_editable=True,
)
clear()

Remove all link flair templates from the subreddit.

For example:

reddit.subreddit("test").flair.link_templates.clear()
delete(template_id: str)

Remove a flair template provided by template_id.

For example, to delete the first Redditor flair template listed, try:

template_info = list(subreddit.flair.templates)[0]
subreddit.flair.templates.delete(template_info["id"])
static flair_type(is_link: bool) str

Return "LINK_FLAIR" or "USER_FLAIR" depending on is_link value.

update(template_id: str, *, allowable_content: Optional[str] = None, background_color: Optional[str] = None, css_class: Optional[str] = None, fetch: bool = True, max_emojis: Optional[int] = None, mod_only: Optional[bool] = None, text: Optional[str] = None, text_color: Optional[str] = None, text_editable: Optional[bool] = None)

Update the flair template provided by template_id.

Parameters
  • template_id – The flair template to update. If not valid then an exception will be thrown.

  • allowable_content – If specified, most be one of "all", "emoji", or "text" to restrict content to that type. If set to "emoji" then the "text" param must be a valid emoji string, for example, ":snoo:".

  • background_color – The flair template’s new background color, as a hex color.

  • css_class – The flair template’s new css_class (default: "").

  • fetch – Whether PRAW will fetch existing information on the existing flair before updating (default: True).

  • max_emojis – Maximum emojis in the flair (Reddit defaults this value to 10).

  • mod_only – Indicate if the flair can only be used by moderators.

  • text – The flair template’s new text.

  • text_color – The flair template’s new text color, either "light" or "dark".

  • text_editable – Indicate if the flair text can be modified for each redditor that sets it (default: False).

Warning

If parameter fetch is set to False, all parameters not provided will be reset to their default (None or False) values.

For example, to make a user flair template text editable, try:

template_info = list(subreddit.flair.templates)[0]
subreddit.flair.templates.update(
    template_info["id"],
    text=template_info["flair_text"],
    text_editable=True,
)
user_selectable() Generator[Dict[str, Union[str, bool]], None, None]

Iterate through the link flair templates as a regular user.

For example:

for template in reddit.subreddit("test").flair.link_templates.user_selectable():
    print(template)

SubredditRedditorFlairTemplates

class praw.models.reddit.subreddit.SubredditRedditorFlairTemplates(subreddit: praw.models.Subreddit)

Provide functions to interact with Redditor flair templates.

__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditFlairTemplates instance.

Parameters

subreddit – The subreddit whose flair templates to work with.

Note

This class should not be initialized directly. Instead, obtain an instance via: reddit.subreddit("test").flair.templates or reddit.subreddit("test").flair.link_templates.

__iter__() Generator[Dict[str, Union[str, int, bool, List[Dict[str, str]]]], None, None]

Iterate through the user flair templates.

For example:

for template in reddit.subreddit("test").flair.templates:
    print(template)
add(text: str, *, allowable_content: Optional[str] = None, background_color: Optional[str] = None, css_class: str = '', max_emojis: Optional[int] = None, mod_only: Optional[bool] = None, text_color: Optional[str] = None, text_editable: bool = False)

Add a redditor flair template to the associated subreddit.

Parameters
  • text – The flair template’s text.

  • allowable_content – If specified, most be one of "all", "emoji", or "text" to restrict content to that type. If set to "emoji" then the "text" param must be a valid emoji string, for example, ":snoo:".

  • background_color – The flair template’s new background color, as a hex color.

  • css_class – The flair template’s css_class (default: "").

  • max_emojis – Maximum emojis in the flair (Reddit defaults this value to 10).

  • mod_only – Indicate if the flair can only be used by moderators.

  • text_color – The flair template’s new text color, either "light" or "dark".

  • text_editable – Indicate if the flair text can be modified for each redditor that sets it (default: False).

For example, to add an editable redditor flair try:

reddit.subreddit("test").flair.templates.add(
    "PRAW",
    css_class="praw",
    text_editable=True,
)
clear()

Remove all Redditor flair templates from the subreddit.

For example:

reddit.subreddit("test").flair.templates.clear()
delete(template_id: str)

Remove a flair template provided by template_id.

For example, to delete the first Redditor flair template listed, try:

template_info = list(subreddit.flair.templates)[0]
subreddit.flair.templates.delete(template_info["id"])
static flair_type(is_link: bool) str

Return "LINK_FLAIR" or "USER_FLAIR" depending on is_link value.

update(template_id: str, *, allowable_content: Optional[str] = None, background_color: Optional[str] = None, css_class: Optional[str] = None, fetch: bool = True, max_emojis: Optional[int] = None, mod_only: Optional[bool] = None, text: Optional[str] = None, text_color: Optional[str] = None, text_editable: Optional[bool] = None)

Update the flair template provided by template_id.

Parameters
  • template_id – The flair template to update. If not valid then an exception will be thrown.

  • allowable_content – If specified, most be one of "all", "emoji", or "text" to restrict content to that type. If set to "emoji" then the "text" param must be a valid emoji string, for example, ":snoo:".

  • background_color – The flair template’s new background color, as a hex color.

  • css_class – The flair template’s new css_class (default: "").

  • fetch – Whether PRAW will fetch existing information on the existing flair before updating (default: True).

  • max_emojis – Maximum emojis in the flair (Reddit defaults this value to 10).

  • mod_only – Indicate if the flair can only be used by moderators.

  • text – The flair template’s new text.

  • text_color – The flair template’s new text color, either "light" or "dark".

  • text_editable – Indicate if the flair text can be modified for each redditor that sets it (default: False).

Warning

If parameter fetch is set to False, all parameters not provided will be reset to their default (None or False) values.

For example, to make a user flair template text editable, try:

template_info = list(subreddit.flair.templates)[0]
subreddit.flair.templates.update(
    template_info["id"],
    text=template_info["flair_text"],
    text_editable=True,
)

InlineGif

class praw.models.InlineGif(*, caption: str = None, path: str)

Class to provide a gif to embed in text.

__init__(*, caption: str = None, path: str)

Initialize an InlineMedia instance.

Parameters
  • caption – An optional caption to add to the image (default: None).

  • path – The path to a media file.

InlineImage

class praw.models.InlineImage(*, caption: str = None, path: str)

Class to provide am image to embed in text.

__init__(*, caption: str = None, path: str)

Initialize an InlineMedia instance.

Parameters
  • caption – An optional caption to add to the image (default: None).

  • path – The path to a media file.

InlineMedia

class praw.models.InlineMedia(*, caption: str = None, path: str)

Provides a way to embed media in self posts.

__init__(*, caption: str = None, path: str)

Initialize an InlineMedia instance.

Parameters
  • caption – An optional caption to add to the image (default: None).

  • path – The path to a media file.

InlineVideo

class praw.models.InlineVideo(*, caption: str = None, path: str)

Class to provide a video to embed in text.

__init__(*, caption: str = None, path: str)

Initialize an InlineMedia instance.

Parameters
  • caption – An optional caption to add to the image (default: None).

  • path – The path to a media file.

BaseModNotes

class praw.models.mod_notes.BaseModNotes(reddit: praw.Reddit)

Provides base methods to interact with moderator notes.

__init__(reddit: praw.Reddit)

Initialize a BaseModNotes instance.

Parameters

reddit – An instance of Reddit.

create(*, label: Optional[str] = None, note: str, redditor: Optional[Union[Redditor, str]] = None, subreddit: Optional[Union[praw.models.Subreddit, str]] = None, thing: Optional[Union[Comment, Submission, str]] = None, **other_settings: Any) praw.models.ModNote

Create a ModNote for a redditor in the specified subreddit.

Parameters
  • label – The label for the note. As of this writing, this can be one of the following: "ABUSE_WARNING", "BAN", "BOT_BAN", "HELPFUL_USER", "PERMA_BAN", "SOLID_CONTRIBUTOR", "SPAM_WARNING", "SPAM_WATCH", or None (default: None).

  • note – The content of the note. As of this writing, this is limited to 250 characters.

  • redditor

    The redditor to create the note for (default: None).

    Note

    This parameter is required if thing is not provided or this is not called from a Redditor instance (e.g., reddit.redditor.notes).

  • subreddit

    The subreddit associated with the note (default: None).

    Note

    This parameter is required if thing is not provided or this is not called from a Subreddit instance (e.g., reddit.subreddit.mod).

  • thing – Either the fullname of a comment/submission, a Comment, or a Submission to associate with the note.

  • other_settings – Additional keyword arguments can be provided to handle new parameters as Reddit introduces them.

Returns

The new ModNote object.

For example, to create a note for u/spez in r/test:

reddit.subreddit("test").mod.notes.create(
    label="HELPFUL_USER", note="Test note", redditor="spez"
)
# or
reddit.redditor("spez").mod.notes.create(
    label="HELPFUL_USER", note="Test note", subreddit="test"
)
# or
reddit.notes.create(
    label="HELPFUL_USER", note="Test note", redditor="spez", subreddit="test"
)
delete(*, delete_all: bool = False, note_id: Optional[str] = None, redditor: Optional[Union[Redditor, str]] = None, subreddit: Optional[Union[praw.models.Subreddit, str]] = None)

Delete note(s) for a redditor.

Parameters
  • delete_all

    When True, delete all notes for the specified redditor in the specified subreddit (default: False).

    Note

    This will make a request for each note.

  • note_id – The ID of the note to delete. This parameter is ignored if delete_all is True.

  • redditor

    The redditor to delete the note(s) for (default: None). Can be a Redditor instance or a redditor name.

    Note

    This parameter is required if this method is not called from a Redditor instance (e.g., redditor.notes).

  • subreddit

    The subreddit to delete the note(s) from (default: None). Can be a Subreddit instance or a subreddit name.

    Note

    This parameter is required if this method is not called from a Subreddit instance (e.g., reddit.subreddit.mod).

For example, to delete a note with the ID "ModNote_d324b280-5ecc-435d-8159-3e259e84e339", try:

reddit.subreddit("test").mod.notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", redditor="spez"
)
# or
reddit.redditor("spez").notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", subreddit="test"
)
# or
reddit.notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339",
    subreddit="test",
    redditor="spez",
)

To delete all notes for u/spez, try:

reddit.subreddit("test").mod.notes.delete(delete_all=True, redditor="spez")
# or
reddit.redditor("spez").notes.delete(delete_all=True, subreddit="test")
# or
reddit.notes.delete(delete_all=True, subreddit="test", redditor="spez")

ModNote

class praw.models.ModNote(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Represent a moderator note.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

action

If this note represents a moderator action, this field indicates the type of action. For example, "banuser" if the action was banning a user.

created_at

Time the moderator note was created, represented in Unix Time.

description

If this note represents a moderator action, this field indicates the description of the action. For example, if the action was banning the user, this is the ban reason.

details

If this note represents a moderator action, this field indicates the details of the action. For example, if the action was banning the user, this is the duration of the ban.

id

The ID of the moderator note.

label

The label applied to the note, currently one of: "ABUSE_WARNING", "BAN", "BOT_BAN", "HELPFUL_USER", "PERMA_BAN", "SOLID_CONTRIBUTOR", "SPAM_WARNING", "SPAM_WATCH", or None.

moderator

The moderator who created the note.

note

The text of the note.

reddit_id

The fullname of the object this note is attributed to, or None if not set. If this note represents a moderators action, this is the fullname of the object the action was performed on.

subreddit

The subreddit this note belongs to.

type

The type of note, currently one of: "APPROVAL", "BAN", "CONTENT_CHANGE", "INVITE", "MUTE", "NOTE", "REMOVAL", or "SPAM".

user

The redditor the note is for.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

delete()

Delete this note.

For example, to delete the last note for u/spez from r/test, try:

for note in reddit.subreddit("test").mod.notes("spez"):
    note.delete()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

ModNoteMixin

class praw.models.reddit.mixins.ModNoteMixin

Interface for classes that can have a moderator note set on them.

author_notes(**generator_kwargs) Generator[praw.models.ModNote, None, None]

Get the moderator notes for the author of this object in the subreddit it’s posted in.

Parameters

generator_kwargs – Additional keyword arguments are passed in the initialization of the moderator note generator.

Returns

A generator of ModNote.

For example, to list all notes the author of a submission, try:

for note in reddit.submission("92dd8").mod.author_notes():
    print(f"{note.label}: {note.note}")
create_note(*, label: Optional[str] = None, note: str, **other_settings) praw.models.ModNote

Create a moderator note on the author of this object in the subreddit it’s posted in.

Parameters
  • label – The label for the note. As of this writing, this can be one of the following: "ABUSE_WARNING", "BAN", "BOT_BAN", "HELPFUL_USER", "PERMA_BAN", "SOLID_CONTRIBUTOR", "SPAM_WARNING", "SPAM_WATCH", or None (default: None).

  • note – The content of the note. As of this writing, this is limited to 250 characters.

  • other_settings – Additional keyword arguments are passed to create().

Returns

The new ModNote object.

For example, to create a note on a Submission, try:

reddit.submission("92dd8").mod.create_note(label="HELPFUL_USER", note="Test note")

RedditModNotes

class praw.models.RedditModNotes(reddit: praw.Reddit)

Provides methods to interact with moderator notes at a global level.

Note

The authenticated user must be a moderator of the provided subreddit(s).

For example, the latest note for u/spez in r/redditdev and r/test, and for u/bboe in r/redditdev can be iterated through like so:

redditor = reddit.redditor("bboe")
subreddit = reddit.subreddit("redditdev")

pairs = [(subreddit, "spez"), ("test", "spez"), (subreddit, redditor)]

for note in reddit.notes(pairs=pairs):
    print(f"{note.label}: {note.note}")
__call__(*, all_notes: bool = False, pairs: Optional[List[Tuple[Union[praw.models.Subreddit, str], Union[Redditor, str]]]] = None, redditors: Optional[List[Union[Redditor, str]]] = None, subreddits: Optional[List[Union[str, praw.models.Subreddit]]] = None, things: Optional[List[Union[Comment, Submission]]] = None, **generator_kwargs: Any) Generator[praw.models.ModNote, None, None]

Get note(s) for each subreddit/user pair, or None if they don’t have any.

Parameters
  • all_notes

    Whether to return all notes or only the latest note for each subreddit/redditor pair (default: False).

    Note

    Setting this to True will result in a request for each unique subreddit/redditor pair. If subreddits and redditors are provided, this will make a request equivalent to number of redditors multiplied by the number of subreddits.

  • pairs

    A list of subreddit/redditor tuples.

    Note

    Required if subreddits, redditors, nor things are provided.

  • redditors

    A list of redditors to return notes for. This parameter is used in tandem with subreddits to get notes from multiple subreddits for each of the provided redditors.

    Note

    Required if items or things is not provided or if subreddits is provided.

  • subreddits

    A list of subreddits to return notes for. This parameter is used in tandem with redditors to get notes for multiple redditors from each of the provided subreddits.

    Note

    Required if items or things is not provided or if redditors is provided.

  • things – A list of comments and/or submissions to return notes for.

  • generator_kwargs – Additional keyword arguments passed to the generator. This parameter is ignored when all_notes is False.

Returns

A generator that yields the most recent ModNote (or None if the user doesn’t have any notes) per entry in their relative order. If all_notes is True, this will yield all notes for each entry.

Note

This method will merge the subreddits and redditors provided from pairs, redditors, subreddits, and things.

Note

This method accepts Redditor instances or redditor names and Subreddit instances or subreddit names where applicable.

For example, the latest note for u/spez in r/redditdev and r/test, and for u/bboe in r/redditdev can be iterated through like so:

redditor = reddit.redditor("bboe")
subreddit = reddit.subreddit("redditdev")

pairs = [(subreddit, "spez"), ("test", "spez"), (subreddit, redditor)]

for note in reddit.notes(pairs=pairs):
    print(f"{note.label}: {note.note}")

For example, all the notes for u/spez and u/bboe in r/announcements, r/redditdev, and r/test can be iterated through like so:

redditor = reddit.redditor("bboe")
subreddit = reddit.subreddit("redditdev")

for note in reddit.notes(
    redditors=["spez", redditor],
    subreddits=["announcements", subreddit, "test"],
    all_notes=True,
):
    print(f"{note.label}: {note.note}")

For example, the latest note for the authors of the last 5 comments and submissions from r/test can be iterated through like so:

submissions = list(reddit.subreddit("test").new(limit=5))
comments = list(reddit.subreddit("test").comments(limit=5))

for note in reddit.notes(things=submissions + comments):
    print(f"{note.label}: {note.note}")

Note

Setting all_notes to True will make a request for each redditor and subreddit combination. The previous example will make 6 requests.

__init__(reddit: praw.Reddit)

Initialize a BaseModNotes instance.

Parameters

reddit – An instance of Reddit.

create(*, label: Optional[str] = None, note: str, redditor: Optional[Union[Redditor, str]] = None, subreddit: Optional[Union[praw.models.Subreddit, str]] = None, thing: Optional[Union[Comment, Submission, str]] = None, **other_settings: Any) praw.models.ModNote

Create a ModNote for a redditor in the specified subreddit.

Parameters
  • label – The label for the note. As of this writing, this can be one of the following: "ABUSE_WARNING", "BAN", "BOT_BAN", "HELPFUL_USER", "PERMA_BAN", "SOLID_CONTRIBUTOR", "SPAM_WARNING", "SPAM_WATCH", or None (default: None).

  • note – The content of the note. As of this writing, this is limited to 250 characters.

  • redditor

    The redditor to create the note for (default: None).

    Note

    This parameter is required if thing is not provided or this is not called from a Redditor instance (e.g., reddit.redditor.notes).

  • subreddit

    The subreddit associated with the note (default: None).

    Note

    This parameter is required if thing is not provided or this is not called from a Subreddit instance (e.g., reddit.subreddit.mod).

  • thing – Either the fullname of a comment/submission, a Comment, or a Submission to associate with the note.

  • other_settings – Additional keyword arguments can be provided to handle new parameters as Reddit introduces them.

Returns

The new ModNote object.

For example, to create a note for u/spez in r/test:

reddit.subreddit("test").mod.notes.create(
    label="HELPFUL_USER", note="Test note", redditor="spez"
)
# or
reddit.redditor("spez").mod.notes.create(
    label="HELPFUL_USER", note="Test note", subreddit="test"
)
# or
reddit.notes.create(
    label="HELPFUL_USER", note="Test note", redditor="spez", subreddit="test"
)
delete(*, delete_all: bool = False, note_id: Optional[str] = None, redditor: Optional[Union[Redditor, str]] = None, subreddit: Optional[Union[praw.models.Subreddit, str]] = None)

Delete note(s) for a redditor.

Parameters
  • delete_all

    When True, delete all notes for the specified redditor in the specified subreddit (default: False).

    Note

    This will make a request for each note.

  • note_id – The ID of the note to delete. This parameter is ignored if delete_all is True.

  • redditor

    The redditor to delete the note(s) for (default: None). Can be a Redditor instance or a redditor name.

    Note

    This parameter is required if this method is not called from a Redditor instance (e.g., redditor.notes).

  • subreddit

    The subreddit to delete the note(s) from (default: None). Can be a Subreddit instance or a subreddit name.

    Note

    This parameter is required if this method is not called from a Subreddit instance (e.g., reddit.subreddit.mod).

For example, to delete a note with the ID "ModNote_d324b280-5ecc-435d-8159-3e259e84e339", try:

reddit.subreddit("test").mod.notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", redditor="spez"
)
# or
reddit.redditor("spez").notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", subreddit="test"
)
# or
reddit.notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339",
    subreddit="test",
    redditor="spez",
)

To delete all notes for u/spez, try:

reddit.subreddit("test").mod.notes.delete(delete_all=True, redditor="spez")
# or
reddit.redditor("spez").notes.delete(delete_all=True, subreddit="test")
# or
reddit.notes.delete(delete_all=True, subreddit="test", redditor="spez")
things(*things: Union[Comment, Submission], all_notes: Optional[bool] = None, **generator_kwargs: Any) Generator[praw.models.ModNote, None, None]

Return notes associated with the author of a Comment or Submission.

Parameters
  • things – One or more things to return notes on. Must be a Comment or Submission.

  • all_notes

    Whether to return all notes, or only the latest (default: True if only one thing is provided otherwise False).

    Note

    Setting this to True will result in a request for each thing.

Returns

A generator that yields the most recent ModNote (or None if the user doesn’t have any notes) per entry in their relative order. If all_notes is True, this will yield all notes for each entry.

For example, to get the latest note for the authors of the top 25 submissions in r/test:

submissions = reddit.subreddit("test").top(limit=25)
for note in reddit.notes.things(*submissions):
    print(f"{note.label}: {note.note}")

For example, to get the latest note for the authors of the last 25 comments in r/test:

comments = reddit.subreddit("test").comments(limit=25)
for note in reddit.notes.things(*comments):
    print(f"{note.label}: {note.note}")

RedditorModNotes

class praw.models.RedditorModNotes(reddit: praw.Reddit, redditor: Union[Redditor, str])

Provides methods to interact with moderator notes at the redditor level.

Note

The authenticated user must be a moderator of the provided subreddit(s).

For example, all the notes for u/spez in r/test can be iterated through like so:

redditor = reddit.redditor("spez")

for note in redditor.notes.subreddits("test"):
    print(f"{note.label}: {note.note}")
__init__(reddit: praw.Reddit, redditor: Union[Redditor, str])

Initialize a RedditorModNotes instance.

Parameters
  • reddit – An instance of Reddit.

  • redditor – An instance of Redditor.

create(*, label: Optional[str] = None, note: str, redditor: Optional[Union[Redditor, str]] = None, subreddit: Optional[Union[praw.models.Subreddit, str]] = None, thing: Optional[Union[Comment, Submission, str]] = None, **other_settings: Any) praw.models.ModNote

Create a ModNote for a redditor in the specified subreddit.

Parameters
  • label – The label for the note. As of this writing, this can be one of the following: "ABUSE_WARNING", "BAN", "BOT_BAN", "HELPFUL_USER", "PERMA_BAN", "SOLID_CONTRIBUTOR", "SPAM_WARNING", "SPAM_WATCH", or None (default: None).

  • note – The content of the note. As of this writing, this is limited to 250 characters.

  • redditor

    The redditor to create the note for (default: None).

    Note

    This parameter is required if thing is not provided or this is not called from a Redditor instance (e.g., reddit.redditor.notes).

  • subreddit

    The subreddit associated with the note (default: None).

    Note

    This parameter is required if thing is not provided or this is not called from a Subreddit instance (e.g., reddit.subreddit.mod).

  • thing – Either the fullname of a comment/submission, a Comment, or a Submission to associate with the note.

  • other_settings – Additional keyword arguments can be provided to handle new parameters as Reddit introduces them.

Returns

The new ModNote object.

For example, to create a note for u/spez in r/test:

reddit.subreddit("test").mod.notes.create(
    label="HELPFUL_USER", note="Test note", redditor="spez"
)
# or
reddit.redditor("spez").mod.notes.create(
    label="HELPFUL_USER", note="Test note", subreddit="test"
)
# or
reddit.notes.create(
    label="HELPFUL_USER", note="Test note", redditor="spez", subreddit="test"
)
delete(*, delete_all: bool = False, note_id: Optional[str] = None, redditor: Optional[Union[Redditor, str]] = None, subreddit: Optional[Union[praw.models.Subreddit, str]] = None)

Delete note(s) for a redditor.

Parameters
  • delete_all

    When True, delete all notes for the specified redditor in the specified subreddit (default: False).

    Note

    This will make a request for each note.

  • note_id – The ID of the note to delete. This parameter is ignored if delete_all is True.

  • redditor

    The redditor to delete the note(s) for (default: None). Can be a Redditor instance or a redditor name.

    Note

    This parameter is required if this method is not called from a Redditor instance (e.g., redditor.notes).

  • subreddit

    The subreddit to delete the note(s) from (default: None). Can be a Subreddit instance or a subreddit name.

    Note

    This parameter is required if this method is not called from a Subreddit instance (e.g., reddit.subreddit.mod).

For example, to delete a note with the ID "ModNote_d324b280-5ecc-435d-8159-3e259e84e339", try:

reddit.subreddit("test").mod.notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", redditor="spez"
)
# or
reddit.redditor("spez").notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", subreddit="test"
)
# or
reddit.notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339",
    subreddit="test",
    redditor="spez",
)

To delete all notes for u/spez, try:

reddit.subreddit("test").mod.notes.delete(delete_all=True, redditor="spez")
# or
reddit.redditor("spez").notes.delete(delete_all=True, subreddit="test")
# or
reddit.notes.delete(delete_all=True, subreddit="test", redditor="spez")
subreddits(*subreddits: Union[praw.models.Subreddit, str], all_notes: Optional[bool] = None, **generator_kwargs: Any) Generator[praw.models.ModNote, None, None]

Return notes for this Redditor from one or more subreddits.

Parameters
  • subreddits – One or more subreddits to retrieve the notes from. Must be either a Subreddit or a subreddit name.

  • all_notes

    Whether to return all notes or only the latest note (default: True if only one subreddit is provided otherwise False).

    Note

    Setting this to True will result in a request for each subreddit.

Returns

A generator that yields the most recent ModNote (or None if this redditor doesn’t have any notes) per subreddit in their relative order. If all_notes is True, this will yield all notes or None from each subreddit for this redditor.

For example, all the notes for u/spez in r/test can be iterated through like so:

redditor = reddit.redditor("spez")

for note in redditor.notes.subreddits("test"):
    print(f"{note.label}: {note.note}")

For example, the latest note for u/spez from r/test and r/redditdev can be iterated through like so:

redditor = reddit.redditor("spez")
subreddit = reddit.subreddit("redditdev")

for note in redditor.notes.subreddits("test", subreddit):
    print(f"{note.label}: {note.note}")

For example, all the notes for u/spez in r/test and r/redditdev can be iterated through like so:

redditor = reddit.redditor("spez")
subreddit = reddit.subreddit("redditdev")

for note in redditor.notes.subreddits("test", subreddit, all_notes=True):
    print(f"{note.label}: {note.note}")

SubredditModNotes

class praw.models.SubredditModNotes(reddit: praw.Reddit, subreddit: Union[praw.models.Subreddit, str])

Provides methods to interact with moderator notes at the subreddit level.

Note

The authenticated user must be a moderator of this subreddit.

For example, all the notes for u/spez in r/test can be iterated through like so:

subreddit = reddit.subreddit("test")

for note in subreddit.mod.notes.redditors("spez"):
    print(f"{note.label}: {note.note}")
__init__(reddit: praw.Reddit, subreddit: Union[praw.models.Subreddit, str])

Initialize a SubredditModNotes instance.

Parameters
  • reddit – An instance of Reddit.

  • subreddit – An instance of Subreddit.

create(*, label: Optional[str] = None, note: str, redditor: Optional[Union[Redditor, str]] = None, subreddit: Optional[Union[praw.models.Subreddit, str]] = None, thing: Optional[Union[Comment, Submission, str]] = None, **other_settings: Any) praw.models.ModNote

Create a ModNote for a redditor in the specified subreddit.

Parameters
  • label – The label for the note. As of this writing, this can be one of the following: "ABUSE_WARNING", "BAN", "BOT_BAN", "HELPFUL_USER", "PERMA_BAN", "SOLID_CONTRIBUTOR", "SPAM_WARNING", "SPAM_WATCH", or None (default: None).

  • note – The content of the note. As of this writing, this is limited to 250 characters.

  • redditor

    The redditor to create the note for (default: None).

    Note

    This parameter is required if thing is not provided or this is not called from a Redditor instance (e.g., reddit.redditor.notes).

  • subreddit

    The subreddit associated with the note (default: None).

    Note

    This parameter is required if thing is not provided or this is not called from a Subreddit instance (e.g., reddit.subreddit.mod).

  • thing – Either the fullname of a comment/submission, a Comment, or a Submission to associate with the note.

  • other_settings – Additional keyword arguments can be provided to handle new parameters as Reddit introduces them.

Returns

The new ModNote object.

For example, to create a note for u/spez in r/test:

reddit.subreddit("test").mod.notes.create(
    label="HELPFUL_USER", note="Test note", redditor="spez"
)
# or
reddit.redditor("spez").mod.notes.create(
    label="HELPFUL_USER", note="Test note", subreddit="test"
)
# or
reddit.notes.create(
    label="HELPFUL_USER", note="Test note", redditor="spez", subreddit="test"
)
delete(*, delete_all: bool = False, note_id: Optional[str] = None, redditor: Optional[Union[Redditor, str]] = None, subreddit: Optional[Union[praw.models.Subreddit, str]] = None)

Delete note(s) for a redditor.

Parameters
  • delete_all

    When True, delete all notes for the specified redditor in the specified subreddit (default: False).

    Note

    This will make a request for each note.

  • note_id – The ID of the note to delete. This parameter is ignored if delete_all is True.

  • redditor

    The redditor to delete the note(s) for (default: None). Can be a Redditor instance or a redditor name.

    Note

    This parameter is required if this method is not called from a Redditor instance (e.g., redditor.notes).

  • subreddit

    The subreddit to delete the note(s) from (default: None). Can be a Subreddit instance or a subreddit name.

    Note

    This parameter is required if this method is not called from a Subreddit instance (e.g., reddit.subreddit.mod).

For example, to delete a note with the ID "ModNote_d324b280-5ecc-435d-8159-3e259e84e339", try:

reddit.subreddit("test").mod.notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", redditor="spez"
)
# or
reddit.redditor("spez").notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339", subreddit="test"
)
# or
reddit.notes.delete(
    note_id="ModNote_d324b280-5ecc-435d-8159-3e259e84e339",
    subreddit="test",
    redditor="spez",
)

To delete all notes for u/spez, try:

reddit.subreddit("test").mod.notes.delete(delete_all=True, redditor="spez")
# or
reddit.redditor("spez").notes.delete(delete_all=True, subreddit="test")
# or
reddit.notes.delete(delete_all=True, subreddit="test", redditor="spez")
redditors(*redditors: Union[Redditor, str], all_notes: Optional[bool] = None, **generator_kwargs: Any) Generator[praw.models.ModNote, None, None]

Return notes from this Subreddit for one or more redditors.

Parameters
  • redditors – One or more redditors to retrieve notes for. Must be either a Redditor or a redditor name.

  • all_notes

    Whether to return all notes or only the latest note (default: True if only one redditor is provided otherwise False).

    Note

    Setting this to True will result in a request for each redditor.

Returns

A generator that yields the most recent ModNote (or None if the user doesn’t have any notes in this subreddit) per redditor in their relative order. If all_notes is True, this will yield all notes for each redditor.

For example, all the notes for u/spez in r/test can be iterated through like so:

subreddit = reddit.subreddit("test")

for note in subreddit.mod.notes.redditors("spez"):
    print(f"{note.label}: {note.note}")

For example, the latest note for u/spez and u/bboe from r/test can be iterated through like so:

subreddit = reddit.subreddit("test")
redditor = reddit.redditor("bboe")

for note in subreddit.mod.notes.redditors("spez", redditor):
    print(f"{note.label}: {note.note}")

For example, all the notes for both u/spez and u/bboe in r/test can be iterated through like so:

subreddit = reddit.subreddit("test")
redditor = reddit.redditor("bboe")

for note in subreddit.mod.notes.redditors("spez", redditor, all_notes=True):
    print(f"{note.label}: {note.note}")

CommentModeration

class praw.models.reddit.comment.CommentModeration(comment: praw.models.Comment)

Provide a set of functions pertaining to Comment moderation.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.mod.approve()
__init__(comment: praw.models.Comment)

Initialize a CommentModeration instance.

Parameters

comment – The comment to moderate.

approve()

Approve a Comment or Submission.

Approving a comment or submission reverts a removal, resets the report counter, adds a green check mark indicator (only visible to other moderators) on the website view, and sets the approved_by attribute to the authenticated user.

Example usage:

# approve a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.approve()
# approve a submission:
submission = reddit.submission("5or86n")
submission.mod.approve()
author_notes(**generator_kwargs) Generator[praw.models.ModNote, None, None]

Get the moderator notes for the author of this object in the subreddit it’s posted in.

Parameters

generator_kwargs – Additional keyword arguments are passed in the initialization of the moderator note generator.

Returns

A generator of ModNote.

For example, to list all notes the author of a submission, try:

for note in reddit.submission("92dd8").mod.author_notes():
    print(f"{note.label}: {note.note}")
create_note(*, label: Optional[str] = None, note: str, **other_settings) praw.models.ModNote

Create a moderator note on the author of this object in the subreddit it’s posted in.

Parameters
  • label – The label for the note. As of this writing, this can be one of the following: "ABUSE_WARNING", "BAN", "BOT_BAN", "HELPFUL_USER", "PERMA_BAN", "SOLID_CONTRIBUTOR", "SPAM_WARNING", "SPAM_WATCH", or None (default: None).

  • note – The content of the note. As of this writing, this is limited to 250 characters.

  • other_settings – Additional keyword arguments are passed to create().

Returns

The new ModNote object.

For example, to create a note on a Submission, try:

reddit.submission("92dd8").mod.create_note(label="HELPFUL_USER", note="Test note")
distinguish(*, how: str = 'yes', sticky: bool = False)

Distinguish a Comment or Submission.

Parameters
  • how – One of "yes", "no", "admin", or "special". "yes" adds a moderator level distinguish. "no" removes any distinction. "admin" and "special" require special user privileges to use (default "yes").

  • stickyComment is stickied if True, placing it at the top of the comment page regardless of score. If thing is not a top-level comment, this parameter is silently ignored (default False).

Example usage:

# distinguish and sticky a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.distinguish(sticky=True)
# undistinguish a submission:
submission = reddit.submission("5or86n")
submission.mod.distinguish(how="no")

See also

undistinguish()

ignore_reports()

Ignore future reports on a Comment or Submission.

Calling this method will prevent future reports on this Comment or Submission from both triggering notifications and appearing in the various moderation listings. The report count will still increment on the Comment or Submission.

Example usage:

# ignore future reports on a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.ignore_reports()
# ignore future reports on a submission:
submission = reddit.submission("5or86n")
submission.mod.ignore_reports()
lock()

Lock a Comment or Submission.

Example usage:

# lock a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.lock()
# lock a submission:
submission = reddit.submission("5or86n")
submission.mod.lock()

See also

unlock()

remove(*, mod_note: str = '', spam: bool = False, reason_id: Optional[str] = None)

Remove a Comment or Submission.

Parameters
  • mod_note – A message for the other moderators.

  • spam – When True, use the removal to help train the Subreddit’s spam filter (default: False).

  • reason_id – The removal reason ID.

If either reason_id or mod_note are provided, a second API call is made to add the removal reason.

Example usage:

# remove a comment and mark as spam:
comment = reddit.comment("dkk4qjd")
comment.mod.remove(spam=True)
# remove a submission
submission = reddit.submission("5or86n")
submission.mod.remove()
# remove a submission with a removal reason
reason = reddit.subreddit.mod.removal_reasons["110ni21zo23ql"]
submission = reddit.submission("5or86n")
submission.mod.remove(reason_id=reason.id)
send_removal_message(*, message: str, title: str = 'ignored', type: str = 'public') Optional[praw.models.Comment]

Send a removal message for a Comment or Submission.

Warning

The object has to be removed before giving it a removal reason. Remove the object with remove(). Trying to add a removal reason without removing the object will result in RedditAPIException being thrown with an INVALID_ID error_type.

Reddit adds human-readable information about the object to the message.

Parameters
  • type – One of "public", "private", or "private_exposed". "public" leaves a stickied comment on the post. "private" sends a modmail message with hidden username. "private_exposed" sends a modmail message without hidden username (default: "public").

  • title – The short reason given in the message. Ignored if type is "public".

  • message – The body of the message.

Returns

The new Comment if type is "public".

show()

Uncollapse a Comment that has been collapsed by Crowd Control.

Example usage:

# Uncollapse a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.show()
undistinguish()

Remove mod, admin, or special distinguishing from an object.

Also unstickies the object if applicable.

Example usage:

# undistinguish a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.undistinguish()
# undistinguish a submission:
submission = reddit.submission("5or86n")
submission.mod.undistinguish()

See also

distinguish()

unignore_reports()

Resume receiving future reports on a Comment or Submission.

Future reports on this Comment or Submission will cause notifications, and appear in the various moderation listings.

Example usage:

# accept future reports on a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.unignore_reports()
# accept future reports on a submission:
submission = reddit.submission("5or86n")
submission.mod.unignore_reports()

See also

ignore_reports()

unlock()

Unlock a Comment or Submission.

Example usage:

# unlock a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.unlock()
# unlock a submission:
submission = reddit.submission("5or86n")
submission.mod.unlock()

See also

lock()

RuleModeration

class praw.models.reddit.rules.RuleModeration(rule: praw.models.Rule)

Contain methods used to moderate rules.

To delete "No spam" from r/test try:

reddit.subreddit("test").rules["No spam"].mod.delete()

To update "No spam" from r/test try:

reddit.subreddit("test").removal_reasons["No spam"].mod.update(
    description="Don't do this!", violation_reason="Spam post"
)
__init__(rule: praw.models.Rule)

Initialize a RuleModeration instance.

delete()

Delete a rule from this subreddit.

To delete "No spam" from r/test try:

reddit.subreddit("test").rules["No spam"].mod.delete()
update(*, description: Optional[str] = None, kind: Optional[str] = None, short_name: Optional[str] = None, violation_reason: Optional[str] = None) praw.models.Rule

Update the rule from this subreddit.

Note

Existing values will be used for any unspecified arguments.

Parameters
  • description – The new description for the rule. Can be empty.

  • kind – The kind of item that the rule applies to. One of "link", "comment", or "all".

  • short_name – The name of the rule.

  • violation_reason – The reason that is shown on the report menu.

Returns

A Rule object containing the updated values.

To update "No spam" from r/test try:

reddit.subreddit("test").removal_reasons["No spam"].mod.update(
    description="Don't do this!", violation_reason="Spam post"
)

SubmissionModeration

class praw.models.reddit.submission.SubmissionModeration(submission: praw.models.Submission)

Provide a set of functions pertaining to Submission moderation.

Example usage:

submission = reddit.submission("8dmv8z")
submission.mod.approve()
__init__(submission: praw.models.Submission)

Initialize a SubmissionModeration instance.

Parameters

submission – The submission to moderate.

approve()

Approve a Comment or Submission.

Approving a comment or submission reverts a removal, resets the report counter, adds a green check mark indicator (only visible to other moderators) on the website view, and sets the approved_by attribute to the authenticated user.

Example usage:

# approve a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.approve()
# approve a submission:
submission = reddit.submission("5or86n")
submission.mod.approve()
author_notes(**generator_kwargs) Generator[praw.models.ModNote, None, None]

Get the moderator notes for the author of this object in the subreddit it’s posted in.

Parameters

generator_kwargs – Additional keyword arguments are passed in the initialization of the moderator note generator.

Returns

A generator of ModNote.

For example, to list all notes the author of a submission, try:

for note in reddit.submission("92dd8").mod.author_notes():
    print(f"{note.label}: {note.note}")
contest_mode(*, state: bool = True)

Set contest mode for the comments of this submission.

Parameters

stateTrue enables contest mode and False disables (default: True).

Contest mode have the following effects:

  • The comment thread will default to being sorted randomly.

  • Replies to top-level comments will be hidden behind “[show replies]” buttons.

  • Scores will be hidden from non-moderators.

  • Scores accessed through the API (mobile apps, bots) will be obscured to “1” for non-moderators.

Example usage:

submission = reddit.submission("5or86n")
submission.mod.contest_mode()
create_note(*, label: Optional[str] = None, note: str, **other_settings) praw.models.ModNote

Create a moderator note on the author of this object in the subreddit it’s posted in.

Parameters
  • label – The label for the note. As of this writing, this can be one of the following: "ABUSE_WARNING", "BAN", "BOT_BAN", "HELPFUL_USER", "PERMA_BAN", "SOLID_CONTRIBUTOR", "SPAM_WARNING", "SPAM_WATCH", or None (default: None).

  • note – The content of the note. As of this writing, this is limited to 250 characters.

  • other_settings – Additional keyword arguments are passed to create().

Returns

The new ModNote object.

For example, to create a note on a Submission, try:

reddit.submission("92dd8").mod.create_note(label="HELPFUL_USER", note="Test note")
distinguish(*, how: str = 'yes', sticky: bool = False)

Distinguish a Comment or Submission.

Parameters
  • how – One of "yes", "no", "admin", or "special". "yes" adds a moderator level distinguish. "no" removes any distinction. "admin" and "special" require special user privileges to use (default "yes").

  • stickyComment is stickied if True, placing it at the top of the comment page regardless of score. If thing is not a top-level comment, this parameter is silently ignored (default False).

Example usage:

# distinguish and sticky a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.distinguish(sticky=True)
# undistinguish a submission:
submission = reddit.submission("5or86n")
submission.mod.distinguish(how="no")

See also

undistinguish()

flair(*, css_class: str = '', flair_template_id: Optional[str] = None, text: str = '')

Set flair for the submission.

Parameters
  • css_class – The css class to associate with the flair html (default: "").

  • flair_template_id – The flair template ID to use when flairing.

  • text – The flair text to associate with the Submission (default: "").

This method can only be used by an authenticated user who is a moderator of the submission’s Subreddit.

Example usage:

submission = reddit.submission("5or86n")
submission.mod.flair(text="PRAW", css_class="bot")
ignore_reports()

Ignore future reports on a Comment or Submission.

Calling this method will prevent future reports on this Comment or Submission from both triggering notifications and appearing in the various moderation listings. The report count will still increment on the Comment or Submission.

Example usage:

# ignore future reports on a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.ignore_reports()
# ignore future reports on a submission:
submission = reddit.submission("5or86n")
submission.mod.ignore_reports()
lock()

Lock a Comment or Submission.

Example usage:

# lock a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.lock()
# lock a submission:
submission = reddit.submission("5or86n")
submission.mod.lock()

See also

unlock()

nsfw()

Mark as not safe for work.

This method can be used both by the submission author and moderators of the subreddit that the submission belongs to.

Example usage:

submission = reddit.subreddit("test").submit("nsfw test", selftext="nsfw")
submission.mod.nsfw()

See also

sfw()

remove(*, mod_note: str = '', spam: bool = False, reason_id: Optional[str] = None)

Remove a Comment or Submission.

Parameters
  • mod_note – A message for the other moderators.

  • spam – When True, use the removal to help train the Subreddit’s spam filter (default: False).

  • reason_id – The removal reason ID.

If either reason_id or mod_note are provided, a second API call is made to add the removal reason.

Example usage:

# remove a comment and mark as spam:
comment = reddit.comment("dkk4qjd")
comment.mod.remove(spam=True)
# remove a submission
submission = reddit.submission("5or86n")
submission.mod.remove()
# remove a submission with a removal reason
reason = reddit.subreddit.mod.removal_reasons["110ni21zo23ql"]
submission = reddit.submission("5or86n")
submission.mod.remove(reason_id=reason.id)
send_removal_message(*, message: str, title: str = 'ignored', type: str = 'public') Optional[praw.models.Comment]

Send a removal message for a Comment or Submission.

Warning

The object has to be removed before giving it a removal reason. Remove the object with remove(). Trying to add a removal reason without removing the object will result in RedditAPIException being thrown with an INVALID_ID error_type.

Reddit adds human-readable information about the object to the message.

Parameters
  • type – One of "public", "private", or "private_exposed". "public" leaves a stickied comment on the post. "private" sends a modmail message with hidden username. "private_exposed" sends a modmail message without hidden username (default: "public").

  • title – The short reason given in the message. Ignored if type is "public".

  • message – The body of the message.

Returns

The new Comment if type is "public".

set_original_content()

Mark as original content.

This method can be used by moderators of the subreddit that the submission belongs to. If the subreddit has enabled the Original Content beta feature in settings, then the submission’s author can use it as well.

Example usage:

submission = reddit.subreddit("test").submit("oc test", selftext="original")
submission.mod.set_original_content()
sfw()

Mark as safe for work.

This method can be used both by the submission author and moderators of the subreddit that the submission belongs to.

Example usage:

submission = reddit.submission("5or86n")
submission.mod.sfw()

See also

nsfw()

spoiler()

Indicate that the submission contains spoilers.

This method can be used both by the submission author and moderators of the subreddit that the submission belongs to.

Example usage:

submission = reddit.submission("5or86n")
submission.mod.spoiler()

See also

unspoiler()

sticky(*, bottom: bool = True, state: bool = True)

Set the submission’s sticky state in its subreddit.

Parameters
  • bottom – When True, set the submission as the bottom sticky. If no top sticky exists, this submission will become the top sticky regardless (default: True).

  • stateTrue sets the sticky for the submission and False unsets (default: True).

Note

When a submission is stickied two or more times, the Reddit API responds with a 409 error that is raised as a Conflict by prawcore. This method suppresses these Conflict errors.

This submission will replace the second stickied submission if one exists.

For example:

submission = reddit.submission("5or86n")
submission.mod.sticky()
suggested_sort(*, sort: str = 'blank')

Set the suggested sort for the comments of the submission.

Parameters

sort – Can be one of: "confidence", "top", "new", "controversial", "old", "random", "qa", or "blank" (default: "blank").

undistinguish()

Remove mod, admin, or special distinguishing from an object.

Also unstickies the object if applicable.

Example usage:

# undistinguish a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.undistinguish()
# undistinguish a submission:
submission = reddit.submission("5or86n")
submission.mod.undistinguish()

See also

distinguish()

unignore_reports()

Resume receiving future reports on a Comment or Submission.

Future reports on this Comment or Submission will cause notifications, and appear in the various moderation listings.

Example usage:

# accept future reports on a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.unignore_reports()
# accept future reports on a submission:
submission = reddit.submission("5or86n")
submission.mod.unignore_reports()

See also

ignore_reports()

unlock()

Unlock a Comment or Submission.

Example usage:

# unlock a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.unlock()
# unlock a submission:
submission = reddit.submission("5or86n")
submission.mod.unlock()

See also

lock()

unset_original_content()

Indicate that the submission is not original content.

This method can be used by moderators of the subreddit that the submission belongs to. If the subreddit has enabled the Original Content beta feature in settings, then the submission’s author can use it as well.

Example usage:

submission = reddit.subreddit("test").submit("oc test", selftext="original")
submission.mod.unset_original_content()
unspoiler()

Indicate that the submission does not contain spoilers.

This method can be used both by the submission author and moderators of the subreddit that the submission belongs to.

For example:

submission = reddit.subreddit("test").submit("not spoiler", selftext="spoiler")
submission.mod.unspoiler()

See also

spoiler()

update_crowd_control_level(level: int)

Change the Crowd Control level of the submission.

Parameters

level – An integer between 0 and 3.

Level Descriptions

Level

Name

Description

0

Off

Crowd Control will not action any of the submission’s comments.

1

Lenient

Comments from users who have negative karma in the subreddit are automatically collapsed.

2

Moderate

Comments from new users and users with negative karma in the subreddit are automatically collapsed.

3

Strict

Comments from users who haven’t joined the subreddit, new users, and users with negative karma in the subreddit are automatically collapsed.

Example usage:

submission = reddit.submission("745ryj")
submission.mod.update_crowd_control_level(2)

See also

show()

SubredditModeration

class praw.models.reddit.subreddit.SubredditModeration(subreddit: praw.models.Subreddit)

Provides a set of moderation functions to a Subreddit.

For example, to accept a moderation invite from r/test:

reddit.subreddit("test").mod.accept_invite()
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditModeration instance.

Parameters

subreddit – The subreddit to moderate.

accept_invite()

Accept an invitation as a moderator of the community.

edited(*, only: Optional[str] = None, **generator_kwargs: Any) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for edited comments and submissions.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print all items in the edited queue try:

for item in reddit.subreddit("mod").mod.edited(limit=None):
    print(item)
inbox(**generator_kwargs: Any) Iterator[praw.models.SubredditMessage]

Return a ListingGenerator for moderator messages.

Warning

Legacy modmail is being deprecated in June 2021. Please see https://www.reddit.com/r/modnews/comments/mar9ha/even_more_modmail_improvements/ for more info.

Additional keyword arguments are passed in the initialization of ListingGenerator.

See also

unread() for unread moderator messages.

To print the last 5 moderator mail messages and their replies, try:

for message in reddit.subreddit("mod").mod.inbox(limit=5):
    print(f"From: {message.author}, Body: {message.body}")
    for reply in message.replies:
        print(f"From: {reply.author}, Body: {reply.body}")
log(*, action: Optional[str] = None, mod: Optional[Union[praw.models.Redditor, str]] = None, **generator_kwargs: Any) Iterator[praw.models.ModAction]

Return a ListingGenerator for moderator log entries.

Parameters
  • action – If given, only return log entries for the specified action.

  • mod – If given, only return log entries for actions made by the passed in redditor.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print the moderator and subreddit of the last 5 modlog entries try:

for log in reddit.subreddit("mod").mod.log(limit=5):
    print(f"Mod: {log.mod}, Subreddit: {log.subreddit}")
modqueue(*, only: Optional[str] = None, **generator_kwargs: Any) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for modqueue items.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print all modqueue items try:

for item in reddit.subreddit("mod").mod.modqueue(limit=None):
    print(item)
notes() praw.models.SubredditModNotes

Provide an instance of SubredditModNotes.

This provides an interface for managing moderator notes for this subreddit.

For example, all the notes for u/spez in r/test can be iterated through like so:

subreddit = reddit.subreddit("test")

for note in subreddit.mod.notes.redditors("spez"):
    print(f"{note.label}: {note.note}")
removal_reasons() SubredditRemovalReasons

Provide an instance of SubredditRemovalReasons.

Use this attribute for interacting with a Subreddit’s removal reasons. For example to list all the removal reasons for a subreddit which you have the posts moderator permission on, try:

for removal_reason in reddit.subreddit("test").mod.removal_reasons:
    print(removal_reason)

A single removal reason can be lazily retrieved via:

reddit.subreddit("test").mod.removal_reasons["reason_id"]

Note

Attempting to access attributes of an nonexistent removal reason will result in a ClientException.

reports(*, only: Optional[str] = None, **generator_kwargs: Any) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for reported comments and submissions.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print the user and mod report reasons in the report queue try:

for reported_item in reddit.subreddit("mod").mod.reports():
    print(f"User Reports: {reported_item.user_reports}")
    print(f"Mod Reports: {reported_item.mod_reports}")
settings() Dict[str, Union[str, int, bool]]

Return a dictionary of the Subreddit’s current settings.

spam(*, only: Optional[str] = None, **generator_kwargs: Any) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for spam comments and submissions.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print the items in the spam queue try:

for item in reddit.subreddit("mod").mod.spam():
    print(item)
stream() praw.models.reddit.subreddit.SubredditModerationStream

Provide an instance of SubredditModerationStream.

Streams can be used to indefinitely retrieve Moderator only items from SubredditModeration made to moderated subreddits, like:

for log in reddit.subreddit("mod").mod.stream.log():
    print(f"Mod: {log.mod}, Subreddit: {log.subreddit}")
unmoderated(**generator_kwargs: Any) Iterator[praw.models.Submission]

Return a ListingGenerator for unmoderated submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print the items in the unmoderated queue try:

for item in reddit.subreddit("mod").mod.unmoderated():
    print(item)
unread(**generator_kwargs: Any) Iterator[praw.models.SubredditMessage]

Return a ListingGenerator for unread moderator messages.

Warning

Legacy modmail is being deprecated in June 2021. Please see https://www.reddit.com/r/modnews/comments/mar9ha/even_more_modmail_improvements/ for more info.

Additional keyword arguments are passed in the initialization of ListingGenerator.

See also

inbox() for all messages.

To print the mail in the unread modmail queue try:

for message in reddit.subreddit("mod").mod.unread():
    print(f"From: {message.author}, To: {message.dest}")
update(**settings: Union[str, int, bool]) Dict[str, Union[str, int, bool]]

Update the Subreddit’s settings.

See https://www.reddit.com/dev/api#POST_api_site_admin for the full list.

Parameters
  • all_original_content – Mandate all submissions to be original content only.

  • allow_chat_post_creation – Allow users to create chat submissions.

  • allow_images – Allow users to upload images using the native image hosting.

  • allow_polls – Allow users to post polls to the subreddit.

  • allow_post_crossposts – Allow users to crosspost submissions from other subreddits.

  • allow_videos – Allow users to upload videos using the native image hosting.

  • collapse_deleted_comments – Collapse deleted and removed comments on comments pages by default.

  • comment_score_hide_mins – The number of minutes to hide comment scores.

  • content_options – The types of submissions users can make. One of "any", "link", or "self".

  • crowd_control_chat_level – Controls the crowd control level for chat rooms. Goes from 0-3.

  • crowd_control_level – Controls the crowd control level for submissions. Goes from 0-3.

  • crowd_control_mode – Enables/disables crowd control.

  • default_set – Allow the subreddit to appear on r/all as well as the default and trending lists.

  • disable_contributor_requests – Specifies whether redditors may send automated modmail messages requesting approval as a submitter.

  • exclude_banned_modqueue – Exclude posts by site-wide banned users from modqueue/unmoderated.

  • free_form_reports – Allow users to specify custom reasons in the report menu.

  • header_hover_text – The text seen when hovering over the snoo.

  • hide_ads – Don’t show ads within this subreddit. Only applies to Premium-user only subreddits.

  • key_color – A 6-digit rgb hex color (e.g., "#AABBCC"), used as a thematic color for your subreddit on mobile.

  • language – A valid IETF language tag (underscore separated).

  • original_content_tag_enabled – Enables the use of the original content label for submissions.

  • over_18 – Viewers must be over 18 years old (i.e., NSFW).

  • public_description – Public description blurb. Appears in search results and on the landing page for private subreddits.

  • restrict_commenting – Specifies whether approved users have the ability to comment.

  • restrict_posting – Specifies whether approved users have the ability to submit posts.

  • show_media – Show thumbnails on submissions.

  • show_media_preview – Expand media previews on comments pages.

  • spam_comments – Spam filter strength for comments. One of "all", "low", or "high".

  • spam_links – Spam filter strength for links. One of "all", "low", or "high".

  • spam_selfposts – Spam filter strength for selfposts. One of "all", "low", or "high".

  • spoilers_enabled – Enable marking posts as containing spoilers.

  • submit_link_label – Custom label for submit link button (None for default).

  • submit_text – Text to show on submission page.

  • submit_text_label – Custom label for submit text post button (None for default).

  • subreddit_type – One of "archived", "employees_only", "gold_only", gold_restricted, "private", "public", or "restricted".

  • suggested_comment_sort – All comment threads will use this sorting method by default. Leave None, or choose one of "confidence", "controversial", "live", "new", "old", "qa", "random", or "top".

  • title – The title of the subreddit.

  • welcome_message_enabled – Enables the subreddit welcome message.

  • welcome_message_text – The text to be used as a welcome message. A welcome message is sent to all new subscribers by a Reddit bot.

  • wiki_edit_age – Account age, in days, required to edit and create wiki pages.

  • wiki_edit_karma – Subreddit karma required to edit and create wiki pages.

  • wikimode – One of "anyone", "disabled", or "modonly".

Note

Updating the subreddit sidebar on old reddit (description) is no longer supported using this method. You can update the sidebar by editing the "config/sidebar" wiki page. For example:

sidebar = reddit.subreddit("test").wiki["config/sidebar"]
sidebar.edit(content="new sidebar content")

Additional keyword arguments can be provided to handle new settings as Reddit introduces them.

Settings that are documented here and aren’t explicitly set by you in a call to SubredditModeration.update() should retain their current value. If they do not, please file a bug.

SubredditRulesModeration

class praw.models.reddit.rules.SubredditRulesModeration(subreddit_rules: SubredditRules)

Contain methods to moderate subreddit rules as a whole.

To add rule "No spam" to r/test try:

reddit.subreddit("test").rules.mod.add(
    short_name="No spam", kind="all", description="Do not spam. Spam bad"
)

To move the fourth rule to the first position, and then to move the prior first rule to where the third rule originally was in r/test:

subreddit = reddit.subreddit("test")
rules = list(subreddit.rules)
new_rules = rules[3:4] + rules[1:3] + rules[0:1] + rules[4:]
# Alternate: [rules[3]] + rules[1:3] + [rules[0]] + rules[4:]
new_rule_list = subreddit.rules.mod.reorder(new_rules)
__init__(subreddit_rules: SubredditRules)

Initialize a SubredditRulesModeration instance.

add(*, description: str = '', kind: str, short_name: str, violation_reason: Optional[str] = None) praw.models.Rule

Add a removal reason to this subreddit.

Parameters
  • description – The description for the rule.

  • kind – The kind of item that the rule applies to. One of "link", "comment", or "all".

  • short_name – The name of the rule.

  • violation_reason – The reason that is shown on the report menu. If a violation reason is not specified, the short name will be used as the violation reason.

Returns

The added Rule.

To add rule "No spam" to r/test try:

reddit.subreddit("test").rules.mod.add(
    short_name="No spam", kind="all", description="Do not spam. Spam bad"
)
reorder(rule_list: List[praw.models.Rule]) List[praw.models.Rule]

Reorder the rules of a subreddit.

Parameters

rule_list – The list of rules, in the wanted order. Each index of the list indicates the position of the rule.

Returns

A list containing the rules in the specified order.

For example, to move the fourth rule to the first position, and then to move the prior first rule to where the third rule originally was in r/test:

subreddit = reddit.subreddit("test")
rules = list(subreddit.rules)
new_rules = rules[3:4] + rules[1:3] + rules[0:1] + rules[4:]
# Alternate: [rules[3]] + rules[1:3] + [rules[0]] + rules[4:]
new_rule_list = subreddit.rules.mod.reorder(new_rules)

SubredditWidgetsModeration

class praw.models.SubredditWidgetsModeration(subreddit: praw.models.Subreddit, reddit: praw.Reddit)

Class for moderating a Subreddit’s widgets.

Get an instance of this class from SubredditWidgets.mod.

Example usage:

styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
reddit.subreddit("test").widgets.mod.add_text_area(
    short_name="My title", text="**bold text**", styles=styles
)

Note

To use this class’s methods, the authenticated user must be a moderator with appropriate permissions.

__init__(subreddit: praw.models.Subreddit, reddit: praw.Reddit)

Initialize a SubredditWidgetsModeration instance.

add_button_widget(*, buttons: List[Dict[str, Union[Dict[str, str], str, int, Dict[str, Union[str, int]]]]], description: str, short_name: str, styles: Dict[str, str], **other_settings) praw.models.ButtonWidget

Add and return a ButtonWidget.

Parameters
  • buttons

    A list of dictionaries describing buttons, as specified in Reddit docs. As of this writing, the format is:

    Each button is either a text button or an image button. A text button looks like this:

    {
        "kind": "text",
        "text": a string no longer than 30 characters,
        "url": a valid URL,
        "color": a 6-digit rgb hex color, e.g., `#AABBCC`,
        "textColor": a 6-digit rgb hex color, e.g., `#AABBCC`,
        "fillColor": a 6-digit rgb hex color, e.g., `#AABBCC`,
        "hoverState": {...}
    }
    

    An image button looks like this:

    {
        "kind": "image",
        "text": a string no longer than 30 characters,
        "linkUrl": a valid URL,
        "url": a valid URL of a Reddit-hosted image,
        "height": an integer,
        "width": an integer,
        "hoverState": {...}
    }
    

    Both types of buttons have the field hoverState. The field does not have to be included (it is optional). If it is included, it can be one of two types: "text" or "image". A text hoverState looks like this:

    {
        "kind": "text",
        "text": a string no longer than 30 characters,
        "color": a 6-digit rgb hex color, e.g., `#AABBCC`,
        "textColor": a 6-digit rgb hex color, e.g., `#AABBCC`,
        "fillColor": a 6-digit rgb hex color, e.g., `#AABBCC`
    }
    

    An image hoverState looks like this:

    {
        "kind": "image",
        "url": a valid URL of a Reddit-hosted image,
        "height": an integer,
        "width": an integer
    }
    

    Note

    The method upload_image() can be used to upload images to Reddit for a url field that holds a Reddit-hosted image.

    Note

    An image hoverState may be paired with a text widget, and a text hoverState may be paired with an image widget.

  • description – Markdown text to describe the widget.

  • short_name – A name for the widget, no longer than 30 characters.

  • styles – A dictionary with keys "backgroundColor" and "headerColor", and values of hex colors. For example, {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}.

Returns

The created ButtonWidget.

Example usage:

widget_moderation = reddit.subreddit("test").widgets.mod
my_image = widget_moderation.upload_image("/path/to/pic.jpg")
buttons = [
    {
        "kind": "text",
        "text": "View source",
        "url": "https://github.com/praw-dev/praw",
        "color": "#FF0000",
        "textColor": "#00FF00",
        "fillColor": "#0000FF",
        "hoverState": {
            "kind": "text",
            "text": "ecruos weiV",
            "color": "#FFFFFF",
            "textColor": "#000000",
            "fillColor": "#0000FF",
        },
    },
    {
        "kind": "image",
        "text": "View documentation",
        "linkUrl": "https://praw.readthedocs.io",
        "url": my_image,
        "height": 200,
        "width": 200,
        "hoverState": {"kind": "image", "url": my_image, "height": 200, "width": 200},
    },
]
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
new_widget = widget_moderation.add_button_widget(
    short_name="Things to click",
    description="Click some of these *cool* links!",
    buttons=buttons,
    styles=styles,
)
add_calendar(*, configuration: Dict[str, Union[bool, int]], google_calendar_id: str, requires_sync: bool, short_name: str, styles: Dict[str, str], **other_settings) praw.models.Calendar

Add and return a Calendar widget.

Parameters
  • configuration

    A dictionary as specified in Reddit docs. For example:

    {
        "numEvents": 10,
        "showDate": True,
        "showDescription": False,
        "showLocation": False,
        "showTime": True,
        "showTitle": True,
    }
    

  • google_calendar_id – An email-style calendar ID. To share a Google Calendar, make it public, then find the “Calendar ID”.

  • requires_sync – Whether the calendar needs synchronization.

  • short_name – A name for the widget, no longer than 30 characters.

  • styles – A dictionary with keys "backgroundColor" and "headerColor", and values of hex colors. For example, {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}.

Returns

The created Calendar.

Example usage:

widget_moderation = reddit.subreddit("test").widgets.mod
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
config = {
    "numEvents": 10,
    "showDate": True,
    "showDescription": False,
    "showLocation": False,
    "showTime": True,
    "showTitle": True,
}
calendar_id = "y6nm89jy427drk8l71w75w9wjn@group.calendar.google.com"
new_widget = widget_moderation.add_calendar(
    short_name="Upcoming Events",
    google_calendar_id=calendar_id,
    requires_sync=True,
    configuration=config,
    styles=styles,
)
add_community_list(*, data: List[Union[str, praw.models.Subreddit]], description: str = '', short_name: str, styles: Dict[str, str], **other_settings) praw.models.CommunityList

Add and return a CommunityList widget.

Parameters
  • data – A list of subreddits. Subreddits can be represented as str or as Subreddit. These types may be mixed within the list.

  • description – A string containing Markdown (default: "").

  • short_name – A name for the widget, no longer than 30 characters.

  • styles – A dictionary with keys "backgroundColor" and "headerColor", and values of hex colors. For example, {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}.

Returns

The created CommunityList.

Example usage:

widget_moderation = reddit.subreddit("test").widgets.mod
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
subreddits = ["learnpython", reddit.subreddit("redditdev")]
new_widget = widget_moderation.add_community_list(
    short_name="My fav subs", data=subreddits, styles=styles, description="description"
)
add_custom_widget(*, css: str, height: int, image_data: List[Dict[str, Union[str, int]]], short_name: str, styles: Dict[str, str], text: str, **other_settings) praw.models.CustomWidget

Add and return a CustomWidget.

Parameters
  • css

    The CSS for the widget, no longer than 100000 characters.

    Note

    As of this writing, Reddit will not accept empty CSS. If you wish to create a custom widget without CSS, consider using "/**/" (an empty comment) as your CSS.

  • height – The height of the widget, between 50 and 500.

  • image_data

    A list of dictionaries as specified in Reddit docs. Each dictionary represents an image and has the key "url" which maps to the URL of an image hosted on Reddit’s servers. Images should be uploaded using upload_image().

    For example:

    [
        {
            "url": "https://some.link",  # from upload_image()
            "width": 600,
            "height": 450,
            "name": "logo",
        },
        {
            "url": "https://other.link",  # from upload_image()
            "width": 450,
            "height": 600,
            "name": "icon",
        },
    ]
    

  • short_name – A name for the widget, no longer than 30 characters.

  • styles – A dictionary with keys "backgroundColor" and "headerColor", and values of hex colors. For example, {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}.

  • text – The Markdown text displayed in the widget.

Returns

The created CustomWidget.

Example usage:

widget_moderation = reddit.subreddit("test").widgets.mod
image_paths = ["/path/to/image1.jpg", "/path/to/image2.png"]
image_urls = [widget_moderation.upload_image(img_path) for img_path in image_paths]
image_data = [
    {"width": 600, "height": 450, "name": "logo", "url": image_urls[0]},
    {"width": 450, "height": 600, "name": "icon", "url": image_urls[1]},
]
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
new_widget = widget_moderation.add_custom_widget(
    image_short_name="My widget",
    text="# Hello world!",
    css="/**/",
    height=200,
    image_data=image_data,
    styles=styles,
)
add_image_widget(*, data: List[Dict[str, Union[str, int]]], short_name: str, styles: Dict[str, str], **other_settings) praw.models.ImageWidget

Add and return an ImageWidget.

Parameters
  • data

    A list of dictionaries as specified in Reddit docs. Each dictionary has the key "url" which maps to the URL of an image hosted on Reddit’s servers. Images should be uploaded using upload_image().

    For example:

    [
        {
            "url": "https://some.link",  # from upload_image()
            "width": 600,
            "height": 450,
            "linkUrl": "https://github.com/praw-dev/praw",
        },
        {
            "url": "https://other.link",  # from upload_image()
            "width": 450,
            "height": 600,
            "linkUrl": "https://praw.readthedocs.io",
        },
    ]
    

  • short_name – A name for the widget, no longer than 30 characters.

  • styles – A dictionary with keys "backgroundColor" and "headerColor", and values of hex colors. For example, {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}.

Returns

The created ImageWidget.

Example usage:

widget_moderation = reddit.subreddit("test").widgets.mod
image_paths = ["/path/to/image1.jpg", "/path/to/image2.png"]
image_data = [
    {
        "width": 600,
        "height": 450,
        "linkUrl": "",
        "url": widget_moderation.upload_image(img_path),
    }
    for img_path in image_paths
]
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
new_widget = widget_moderation.add_image_widget(
    short_name="My cool pictures", data=image_data, styles=styles
)
add_menu(*, data: List[Dict[str, Union[List[Dict[str, str]], str]]], **other_settings) praw.models.Menu

Add and return a Menu widget.

Parameters

data

A list of dictionaries describing menu contents, as specified in Reddit docs. As of this writing, the format is:

[
    {
        "text": a string no longer than 20 characters,
        "url": a valid URL
    },

    OR

    {
        "children": [
            {
                "text": a string no longer than 20 characters,
                "url": a valid URL,
            },
            ...
        ],
        "text": a string no longer than 20 characters,
    },
    ...
]

Returns

The created Menu.

Example usage:

widget_moderation = reddit.subreddit("test").widgets.mod
menu_contents = [
    {"text": "My homepage", "url": "https://example.com"},
    {
        "text": "Python packages",
        "children": [
            {"text": "PRAW", "url": "https://praw.readthedocs.io/"},
            {"text": "requests", "url": "https://docs.python-requests.org/"},
        ],
    },
    {"text": "Reddit homepage", "url": "https://reddit.com"},
]
new_widget = widget_moderation.add_menu(data=menu_contents)
add_post_flair_widget(*, display: str, order: List[str], short_name: str, styles: Dict[str, str], **other_settings) praw.models.PostFlairWidget

Add and return a PostFlairWidget.

Parameters
  • display – Display style. Either "cloud" or "list".

  • order

    A list of flair template IDs. You can get all flair template IDs in a subreddit with:

    flairs = [f["id"] for f in subreddit.flair.link_templates]
    

  • short_name – A name for the widget, no longer than 30 characters.

  • styles – A dictionary with keys "backgroundColor" and "headerColor", and values of hex colors. For example, {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}.

Returns

The created PostFlairWidget.

Example usage:

subreddit = reddit.subreddit("test")
widget_moderation = subreddit.widgets.mod
flairs = [f["id"] for f in subreddit.flair.link_templates]
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
new_widget = widget_moderation.add_post_flair_widget(
    short_name="Some flairs", display="list", order=flairs, styles=styles
)
add_text_area(*, short_name: str, styles: Dict[str, str], text: str, **other_settings) praw.models.TextArea

Add and return a TextArea widget.

Parameters
  • short_name – A name for the widget, no longer than 30 characters.

  • styles – A dictionary with keys "backgroundColor" and "headerColor", and values of hex colors. For example, {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}.

  • text – The Markdown text displayed in the widget.

Returns

The created TextArea.

Example usage:

widget_moderation = reddit.subreddit("test").widgets.mod
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
new_widget = widget_moderation.add_text_area(
    short_name="My cool title", text="*Hello* **world**!", styles=styles
)
reorder(new_order: List[Union[praw.models.ButtonWidget, praw.models.Calendar, praw.models.CommunityList, praw.models.CustomWidget, praw.models.IDCard, praw.models.ImageWidget, praw.models.Menu, praw.models.ModeratorsWidget, praw.models.PostFlairWidget, praw.models.RulesWidget, praw.models.TextArea, praw.models.Widget, str]], *, section: str = 'sidebar')

Reorder the widgets.

Parameters
  • new_order – A list of widgets. Represented as a list that contains Widget objects, or widget IDs as strings. These types may be mixed.

  • section – The section to reorder (default: "sidebar").

Example usage:

widgets = reddit.subreddit("test").widgets
order = list(widgets.sidebar)
order.reverse()
widgets.mod.reorder(order)
upload_image(file_path: str) str

Upload an image to Reddit and get the URL.

Parameters

file_path – The path to the local file.

Returns

The URL of the uploaded image as a str.

This method is used to upload images for widgets. For example, it can be used in conjunction with add_image_widget(), add_custom_widget(), and add_button_widget().

Example usage:

my_sub = reddit.subreddit("test")
image_url = my_sub.widgets.mod.upload_image("/path/to/image.jpg")
image_data = [{"width": 300, "height": 300, "url": image_url, "linkUrl": ""}]
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
my_sub.widgets.mod.add_image_widget(
    short_name="My cool pictures", data=image_data, styles=styles
)

ThingModerationMixin

class praw.models.reddit.mixins.ThingModerationMixin

Provides moderation methods for Comments and Submissions.

__init__()
approve()

Approve a Comment or Submission.

Approving a comment or submission reverts a removal, resets the report counter, adds a green check mark indicator (only visible to other moderators) on the website view, and sets the approved_by attribute to the authenticated user.

Example usage:

# approve a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.approve()
# approve a submission:
submission = reddit.submission("5or86n")
submission.mod.approve()
author_notes(**generator_kwargs) Generator[praw.models.ModNote, None, None]

Get the moderator notes for the author of this object in the subreddit it’s posted in.

Parameters

generator_kwargs – Additional keyword arguments are passed in the initialization of the moderator note generator.

Returns

A generator of ModNote.

For example, to list all notes the author of a submission, try:

for note in reddit.submission("92dd8").mod.author_notes():
    print(f"{note.label}: {note.note}")
create_note(*, label: Optional[str] = None, note: str, **other_settings) praw.models.ModNote

Create a moderator note on the author of this object in the subreddit it’s posted in.

Parameters
  • label – The label for the note. As of this writing, this can be one of the following: "ABUSE_WARNING", "BAN", "BOT_BAN", "HELPFUL_USER", "PERMA_BAN", "SOLID_CONTRIBUTOR", "SPAM_WARNING", "SPAM_WATCH", or None (default: None).

  • note – The content of the note. As of this writing, this is limited to 250 characters.

  • other_settings – Additional keyword arguments are passed to create().

Returns

The new ModNote object.

For example, to create a note on a Submission, try:

reddit.submission("92dd8").mod.create_note(label="HELPFUL_USER", note="Test note")
distinguish(*, how: str = 'yes', sticky: bool = False)

Distinguish a Comment or Submission.

Parameters
  • how – One of "yes", "no", "admin", or "special". "yes" adds a moderator level distinguish. "no" removes any distinction. "admin" and "special" require special user privileges to use (default "yes").

  • stickyComment is stickied if True, placing it at the top of the comment page regardless of score. If thing is not a top-level comment, this parameter is silently ignored (default False).

Example usage:

# distinguish and sticky a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.distinguish(sticky=True)
# undistinguish a submission:
submission = reddit.submission("5or86n")
submission.mod.distinguish(how="no")

See also

undistinguish()

ignore_reports()

Ignore future reports on a Comment or Submission.

Calling this method will prevent future reports on this Comment or Submission from both triggering notifications and appearing in the various moderation listings. The report count will still increment on the Comment or Submission.

Example usage:

# ignore future reports on a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.ignore_reports()
# ignore future reports on a submission:
submission = reddit.submission("5or86n")
submission.mod.ignore_reports()
lock()

Lock a Comment or Submission.

Example usage:

# lock a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.lock()
# lock a submission:
submission = reddit.submission("5or86n")
submission.mod.lock()

See also

unlock()

remove(*, mod_note: str = '', spam: bool = False, reason_id: Optional[str] = None)

Remove a Comment or Submission.

Parameters
  • mod_note – A message for the other moderators.

  • spam – When True, use the removal to help train the Subreddit’s spam filter (default: False).

  • reason_id – The removal reason ID.

If either reason_id or mod_note are provided, a second API call is made to add the removal reason.

Example usage:

# remove a comment and mark as spam:
comment = reddit.comment("dkk4qjd")
comment.mod.remove(spam=True)
# remove a submission
submission = reddit.submission("5or86n")
submission.mod.remove()
# remove a submission with a removal reason
reason = reddit.subreddit.mod.removal_reasons["110ni21zo23ql"]
submission = reddit.submission("5or86n")
submission.mod.remove(reason_id=reason.id)
send_removal_message(*, message: str, title: str = 'ignored', type: str = 'public') Optional[praw.models.Comment]

Send a removal message for a Comment or Submission.

Warning

The object has to be removed before giving it a removal reason. Remove the object with remove(). Trying to add a removal reason without removing the object will result in RedditAPIException being thrown with an INVALID_ID error_type.

Reddit adds human-readable information about the object to the message.

Parameters
  • type – One of "public", "private", or "private_exposed". "public" leaves a stickied comment on the post. "private" sends a modmail message with hidden username. "private_exposed" sends a modmail message without hidden username (default: "public").

  • title – The short reason given in the message. Ignored if type is "public".

  • message – The body of the message.

Returns

The new Comment if type is "public".

undistinguish()

Remove mod, admin, or special distinguishing from an object.

Also unstickies the object if applicable.

Example usage:

# undistinguish a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.undistinguish()
# undistinguish a submission:
submission = reddit.submission("5or86n")
submission.mod.undistinguish()

See also

distinguish()

unignore_reports()

Resume receiving future reports on a Comment or Submission.

Future reports on this Comment or Submission will cause notifications, and appear in the various moderation listings.

Example usage:

# accept future reports on a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.unignore_reports()
# accept future reports on a submission:
submission = reddit.submission("5or86n")
submission.mod.unignore_reports()

See also

ignore_reports()

unlock()

Unlock a Comment or Submission.

Example usage:

# unlock a comment:
comment = reddit.comment("dkk4qjd")
comment.mod.unlock()
# unlock a submission:
submission = reddit.submission("5or86n")
submission.mod.unlock()

See also

lock()

UserSubredditModeration

class praw.models.reddit.user_subreddit.UserSubredditModeration(subreddit: praw.models.Subreddit)

Provides a set of moderation functions to a UserSubreddit.

For example, to accept a moderation invite from the user subreddit of u/spez:

reddit.subreddit("test").mod.accept_invite()
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditModeration instance.

Parameters

subreddit – The subreddit to moderate.

accept_invite()

Accept an invitation as a moderator of the community.

edited(*, only: Optional[str] = None, **generator_kwargs: Any) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for edited comments and submissions.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print all items in the edited queue try:

for item in reddit.subreddit("mod").mod.edited(limit=None):
    print(item)
inbox(**generator_kwargs: Any) Iterator[praw.models.SubredditMessage]

Return a ListingGenerator for moderator messages.

Warning

Legacy modmail is being deprecated in June 2021. Please see https://www.reddit.com/r/modnews/comments/mar9ha/even_more_modmail_improvements/ for more info.

Additional keyword arguments are passed in the initialization of ListingGenerator.

See also

unread() for unread moderator messages.

To print the last 5 moderator mail messages and their replies, try:

for message in reddit.subreddit("mod").mod.inbox(limit=5):
    print(f"From: {message.author}, Body: {message.body}")
    for reply in message.replies:
        print(f"From: {reply.author}, Body: {reply.body}")
log(*, action: Optional[str] = None, mod: Optional[Union[praw.models.Redditor, str]] = None, **generator_kwargs: Any) Iterator[praw.models.ModAction]

Return a ListingGenerator for moderator log entries.

Parameters
  • action – If given, only return log entries for the specified action.

  • mod – If given, only return log entries for actions made by the passed in redditor.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print the moderator and subreddit of the last 5 modlog entries try:

for log in reddit.subreddit("mod").mod.log(limit=5):
    print(f"Mod: {log.mod}, Subreddit: {log.subreddit}")
modqueue(*, only: Optional[str] = None, **generator_kwargs: Any) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for modqueue items.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print all modqueue items try:

for item in reddit.subreddit("mod").mod.modqueue(limit=None):
    print(item)
notes() praw.models.SubredditModNotes

Provide an instance of SubredditModNotes.

This provides an interface for managing moderator notes for this subreddit.

For example, all the notes for u/spez in r/test can be iterated through like so:

subreddit = reddit.subreddit("test")

for note in subreddit.mod.notes.redditors("spez"):
    print(f"{note.label}: {note.note}")
removal_reasons() SubredditRemovalReasons

Provide an instance of SubredditRemovalReasons.

Use this attribute for interacting with a Subreddit’s removal reasons. For example to list all the removal reasons for a subreddit which you have the posts moderator permission on, try:

for removal_reason in reddit.subreddit("test").mod.removal_reasons:
    print(removal_reason)

A single removal reason can be lazily retrieved via:

reddit.subreddit("test").mod.removal_reasons["reason_id"]

Note

Attempting to access attributes of an nonexistent removal reason will result in a ClientException.

reports(*, only: Optional[str] = None, **generator_kwargs: Any) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for reported comments and submissions.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print the user and mod report reasons in the report queue try:

for reported_item in reddit.subreddit("mod").mod.reports():
    print(f"User Reports: {reported_item.user_reports}")
    print(f"Mod Reports: {reported_item.mod_reports}")
settings() Dict[str, Union[str, int, bool]]

Return a dictionary of the Subreddit’s current settings.

spam(*, only: Optional[str] = None, **generator_kwargs: Any) Iterator[Union[praw.models.Comment, praw.models.Submission]]

Return a ListingGenerator for spam comments and submissions.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print the items in the spam queue try:

for item in reddit.subreddit("mod").mod.spam():
    print(item)
stream() praw.models.reddit.subreddit.SubredditModerationStream

Provide an instance of SubredditModerationStream.

Streams can be used to indefinitely retrieve Moderator only items from SubredditModeration made to moderated subreddits, like:

for log in reddit.subreddit("mod").mod.stream.log():
    print(f"Mod: {log.mod}, Subreddit: {log.subreddit}")
unmoderated(**generator_kwargs: Any) Iterator[praw.models.Submission]

Return a ListingGenerator for unmoderated submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To print the items in the unmoderated queue try:

for item in reddit.subreddit("mod").mod.unmoderated():
    print(item)
unread(**generator_kwargs: Any) Iterator[praw.models.SubredditMessage]

Return a ListingGenerator for unread moderator messages.

Warning

Legacy modmail is being deprecated in June 2021. Please see https://www.reddit.com/r/modnews/comments/mar9ha/even_more_modmail_improvements/ for more info.

Additional keyword arguments are passed in the initialization of ListingGenerator.

See also

inbox() for all messages.

To print the mail in the unread modmail queue try:

for message in reddit.subreddit("mod").mod.unread():
    print(f"From: {message.author}, To: {message.dest}")
update(**settings: Union[str, int, bool]) Dict[str, Union[str, int, bool]]

Update the Subreddit’s settings.

Parameters
  • all_original_content – Mandate all submissions to be original content only.

  • allow_chat_post_creation – Allow users to create chat submissions.

  • allow_images – Allow users to upload images using the native image hosting.

  • allow_polls – Allow users to post polls to the subreddit.

  • allow_post_crossposts – Allow users to crosspost submissions from other subreddits.

  • allow_top – Allow the subreddit to appear on r/all as well as the default and trending lists.

  • allow_videos – Allow users to upload videos using the native image hosting.

  • collapse_deleted_comments – Collapse deleted and removed comments on comments pages by default.

  • crowd_control_chat_level – Controls the crowd control level for chat rooms. Goes from 0-3.

  • crowd_control_level – Controls the crowd control level for submissions. Goes from 0-3.

  • crowd_control_mode – Enables/disables crowd control.

  • comment_score_hide_mins – The number of minutes to hide comment scores.

  • description – Shown in the sidebar of your subreddit.

  • disable_contributor_requests – Specifies whether redditors may send automated modmail messages requesting approval as a submitter.

  • exclude_banned_modqueue – Exclude posts by site-wide banned users from modqueue/unmoderated.

  • free_form_reports – Allow users to specify custom reasons in the report menu.

  • header_hover_text – The text seen when hovering over the snoo.

  • hide_ads – Don’t show ads within this subreddit. Only applies to Premium-user only subreddits.

  • key_color – A 6-digit rgb hex color (e.g., "#AABBCC"), used as a thematic color for your subreddit on mobile.

  • lang – A valid IETF language tag (underscore separated).

  • link_type – The types of submissions users can make. One of "any", "link", or "self".

  • original_content_tag_enabled – Enables the use of the original content label for submissions.

  • over_18 – Viewers must be over 18 years old (i.e., NSFW).

  • public_description – Public description blurb. Appears in search results and on the landing page for private subreddits.

  • public_traffic – Make the traffic stats page public.

  • restrict_commenting – Specifies whether approved users have the ability to comment.

  • restrict_posting – Specifies whether approved users have the ability to submit posts.

  • show_media – Show thumbnails on submissions.

  • show_media_preview – Expand media previews on comments pages.

  • spam_comments – Spam filter strength for comments. One of "all", "low", or "high".

  • spam_links – Spam filter strength for links. One of "all", "low", or "high".

  • spam_selfposts – Spam filter strength for selfposts. One of "all", "low", or "high".

  • spoilers_enabled – Enable marking posts as containing spoilers.

  • submit_link_label – Custom label for submit link button (None for default).

  • submit_text – Text to show on submission page.

  • submit_text_label – Custom label for submit text post button (None for default).

  • subreddit_type – The string "user".

  • suggested_comment_sort – All comment threads will use this sorting method by default. Leave None, or choose one of confidence, "controversial", "live", "new", "old", "qa", "random", or "top".

  • title – The title of the subreddit.

  • welcome_message_enabled – Enables the subreddit welcome message.

  • welcome_message_text – The text to be used as a welcome message. A welcome message is sent to all new subscribers by a Reddit bot.

  • wiki_edit_age – Account age, in days, required to edit and create wiki pages.

  • wiki_edit_karma – Subreddit karma required to edit and create wiki pages.

  • wikimode – One of "anyone", "disabled", or "modonly".

Additional keyword arguments can be provided to handle new settings as Reddit introduces them.

Settings that are documented here and aren’t explicitly set by you in a call to SubredditModeration.update() should retain their current value. If they do not please file a bug.

Warning

Undocumented settings, or settings that were very recently documented, may not retain their current value when updating. This often occurs when Reddit adds a new setting but forgets to add that setting to the API endpoint that is used to fetch the current settings.

WidgetModeration

class praw.models.WidgetModeration(widget: praw.models.Widget, subreddit: Union[praw.models.Subreddit, str], reddit: praw.Reddit)

Class for moderating a particular widget.

Example usage:

widget = reddit.subreddit("test").widgets.sidebar[0]
widget.mod.update(shortName="My new title")
widget.mod.delete()
__init__(widget: praw.models.Widget, subreddit: Union[praw.models.Subreddit, str], reddit: praw.Reddit)

Initialize a WidgetModeration instance.

delete()

Delete the widget.

Example usage:

widget.mod.delete()
update(**kwargs) Union[praw.models.ButtonWidget, praw.models.Calendar, praw.models.CommunityList, praw.models.CustomWidget, praw.models.IDCard, praw.models.ImageWidget, praw.models.Menu, praw.models.ModeratorsWidget, praw.models.PostFlairWidget, praw.models.RulesWidget, praw.models.TextArea, praw.models.Widget]

Update the widget. Returns the updated widget.

Parameters differ based on the type of widget. See Reddit documentation or the document of the particular type of widget.

Returns

The updated Widget.

For example, update a text widget like so:

text_widget.mod.update(shortName="New text area", text="Hello!")

Note

Most parameters follow the lowerCamelCase convention. When in doubt, check the Reddit documentation linked above.

WikiPageModeration

class praw.models.reddit.wikipage.WikiPageModeration(wikipage: WikiPage)

Provides a set of moderation functions for a WikiPage.

For example, to add u/spez as an editor on the wikipage "praw_test" try:

reddit.subreddit("test").wiki["praw_test"].mod.add("spez")
__init__(wikipage: WikiPage)

Initialize a WikiPageModeration instance.

Parameters

wikipage – The wikipage to moderate.

add(redditor: praw.models.Redditor)

Add an editor to this WikiPage.

Parameters

redditor – A redditor name or Redditor instance.

To add u/spez as an editor on the wikipage "praw_test" try:

reddit.subreddit("test").wiki["praw_test"].mod.add("spez")
remove(redditor: praw.models.Redditor)

Remove an editor from this WikiPage.

Parameters

redditor – A redditor name or Redditor instance.

To remove u/spez as an editor on the wikipage "praw_test" try:

reddit.subreddit("test").wiki["praw_test"].mod.remove("spez")
revert()

Revert a wikipage back to a specific revision.

To revert the page "praw_test" in r/test to revision "1234abc", try

reddit.subreddit("test").wiki["praw_test"].revision("1234abc").mod.revert()

Note

When you attempt to revert the page config/stylesheet, Reddit checks to see if the revision being reverted to passes the CSS filter. If the check fails, then the revision attempt will also fail, and a prawcore.Forbidden exception will be raised. For example, you can’t revert to a revision that contains a link to url(%%PRAW%%) if there is no image named PRAW on the current stylesheet.

Here is an example of how to look for this type of error:

from prawcore.exceptions import Forbidden

try:
    reddit.subreddit("test").wiki["config/stylesheet"].revision("1234abc").mod.revert()
except Forbidden as exception:
    try:
        exception.response.json()
    except ValueError:
        exception.response.text

If the error occurs, the output will look something like

{"reason": "INVALID_CSS", "message": "Forbidden", "explanation": "%(css_error)s"}
settings() Dict[str, Any]

Return the settings for this WikiPage.

update(*, listed: bool, permlevel: int, **other_settings: Any) Dict[str, Any]

Update the settings for this WikiPage.

Parameters
  • listed – Show this page on page list.

  • permlevel – Who can edit this page? 0 use subreddit wiki permissions, 1 only approved wiki contributors for this page may edit (see WikiPageModeration.add()), 2 only mods may edit and view.

  • other_settings – Additional keyword arguments to pass.

Returns

The updated WikiPage settings.

To set the wikipage "praw_test" in r/test to mod only and disable it from showing in the page list, try:

reddit.subreddit("test").wiki["praw_test"].mod.update(listed=False, permlevel=2)

LiveContributorRelationship

class praw.models.reddit.live.LiveContributorRelationship(thread: praw.models.LiveThread)

Provide methods to interact with live threads’ contributors.

__call__() List[praw.models.Redditor]

Return a RedditorList for live threads’ contributors.

Usage:

thread = reddit.live("ukaeu1ik4sw5")
for contributor in thread.contributor():
    print(contributor)
__init__(thread: praw.models.LiveThread)

Initialize a LiveContributorRelationship instance.

Parameters

thread – An instance of LiveThread.

Note

This class should not be initialized directly. Instead, obtain an instance via: LiveThread.contributor().

accept_invite()

Accept an invite to contribute the live thread.

Usage:

thread = reddit.live("ydwwxneu7vsa")
thread.contributor.accept_invite()
invite(redditor: Union[str, praw.models.Redditor], *, permissions: Optional[List[str]] = None)

Invite a redditor to be a contributor of the live thread.

Parameters
  • redditor – A redditor name or Redditor instance.

  • permissions – When provided (not None), permissions should be a list of strings specifying which subset of permissions to grant. An empty list [] indicates no permissions, and when not provided (None), indicates full permissions.

Raises

RedditAPIException if the invitation already exists.

Usage:

thread = reddit.live("ukaeu1ik4sw5")
redditor = reddit.redditor("spez")

# "manage" and "settings" permissions
thread.contributor.invite(redditor, permissions=["manage", "settings"])

See also

LiveContributorRelationship.remove_invite() to remove the invite for redditor.

leave()

Abdicate the live thread contributor position (use with care).

Usage:

thread = reddit.live("ydwwxneu7vsa")
thread.contributor.leave()
remove(redditor: Union[str, praw.models.Redditor])

Remove the redditor from the live thread contributors.

Parameters

redditor – A redditor fullname (e.g., "t2_1w72") or Redditor instance.

Usage:

thread = reddit.live("ukaeu1ik4sw5")
redditor = reddit.redditor("spez")
thread.contributor.remove(redditor)
thread.contributor.remove("t2_1w72")  # with fullname
remove_invite(redditor: Union[str, praw.models.Redditor])

Remove the invite for redditor.

Parameters

redditor – A redditor fullname (e.g., "t2_1w72") or Redditor instance.

Usage:

thread = reddit.live("ukaeu1ik4sw5")
redditor = reddit.redditor("spez")
thread.contributor.remove_invite(redditor)
thread.contributor.remove_invite("t2_1w72")  # with fullname

See also

LiveContributorRelationship.invite() to invite a redditor to be a contributor of the live thread.

update(redditor: Union[str, praw.models.Redditor], *, permissions: Optional[List[str]] = None)

Update the contributor permissions for redditor.

Parameters
  • redditor – A redditor name or Redditor instance.

  • permissions – When provided (not None), permissions should be a list of strings specifying which subset of permissions to grant (other permissions are removed). An empty list [] indicates no permissions, and when not provided (None), indicates full permissions.

For example, to grant all permissions to the contributor, try:

thread = reddit.live("ukaeu1ik4sw5")
thread.contributor.update("spez")

To grant "access" and "edit" permissions (and to remove other permissions), try:

thread.contributor.update("spez", permissions=["access", "edit"])

To remove all permissions from the contributor, try:

subreddit.moderator.update("spez", permissions=[])
update_invite(redditor: Union[str, praw.models.Redditor], *, permissions: Optional[List[str]] = None)

Update the contributor invite permissions for redditor.

Parameters
  • redditor – A redditor name or Redditor instance.

  • permissions – When provided (not None), permissions should be a list of strings specifying which subset of permissions to grant (other permissions are removed). An empty list [] indicates no permissions, and when not provided (None), indicates full permissions.

For example, to set all permissions to the invitation, try:

thread = reddit.live("ukaeu1ik4sw5")
thread.contributor.update_invite("spez")

To set "access" and "edit" permissions (and to remove other permissions) to the invitation, try:

thread.contributor.update_invite("spez", permissions=["access", "edit"])

To remove all permissions from the invitation, try:

thread.contributor.update_invite("spez", permissions=[])

LiveThreadContribution

class praw.models.reddit.live.LiveThreadContribution(thread: praw.models.LiveThread)

Provides a set of contribution functions to a LiveThread.

__init__(thread: praw.models.LiveThread)

Initialize a LiveThreadContribution instance.

Parameters

thread – An instance of LiveThread.

This instance can be retrieved through thread.contrib where thread is a LiveThread instance. E.g.,

thread = reddit.live("ukaeu1ik4sw5")
thread.contrib.add("### update")
add(body: str)

Add an update to the live thread.

Parameters

body – The Markdown formatted content for the update.

Usage:

thread = reddit.live("ydwwxneu7vsa")
thread.contrib.add("test `LiveThreadContribution.add()`")
close()

Close the live thread permanently (cannot be undone).

Usage:

thread = reddit.live("ukaeu1ik4sw5")
thread.contrib.close()
update(*, description: Optional[str] = None, nsfw: Optional[bool] = None, resources: Optional[str] = None, title: Optional[str] = None, **other_settings: Optional[str])

Update settings of the live thread.

Parameters
  • description – The live thread’s description (default: None).

  • nsfw – Indicate whether this thread is not safe for work (default: None).

  • resources – Markdown formatted information that is useful for the live thread (default: None).

  • title – The title of the live thread (default: None).

Does nothing if no arguments are provided.

Each setting will maintain its current value if None is specified.

Additional keyword arguments can be provided to handle new settings as Reddit introduces them.

Usage:

thread = reddit.live("xyu8kmjvfrww")

# update 'title' and 'nsfw'
updated_thread = thread.contrib.update(title=new_title, nsfw=True)

If Reddit introduces new settings, you must specify None for the setting you want to maintain:

# update 'nsfw' and maintain new setting 'foo'
thread.contrib.update(nsfw=True, foo=None)

LiveThreadStream

class praw.models.reddit.live.LiveThreadStream(live_thread: praw.models.LiveThread)

Provides a LiveThread stream.

Usually used via:

for live_update in reddit.live("ta535s1hq2je").stream.updates():
    print(live_update.body)
__init__(live_thread: praw.models.LiveThread)

Initialize a LiveThreadStream instance.

Parameters

live_thread – The live thread associated with the stream.

updates(**stream_options: Dict[str, Any]) Iterator[praw.models.LiveUpdate]

Yield new updates to the live thread as they become available.

Parameters

skip_existing – Set to True to only fetch items created after the stream (default: False).

As with LiveThread.updates(), updates are yielded as LiveUpdate.

Updates are yielded oldest first. Up to 100 historical updates will initially be returned.

Keyword arguments are passed to stream_generator().

For example, to retrieve all new updates made to the "ta535s1hq2je" live thread, try:

for live_update in reddit.live("ta535s1hq2je").stream.updates():
    print(live_update.body)

To only retrieve new updates starting from when the stream is created, pass skip_existing=True:

live_thread = reddit.live("ta535s1hq2je")
for live_update in live_thread.stream.updates(skip_existing=True):
    print(live_update.author)

LiveUpdateContribution

class praw.models.reddit.live.LiveUpdateContribution(update: praw.models.LiveUpdate)

Provides a set of contribution functions to LiveUpdate.

__init__(update: praw.models.LiveUpdate)

Initialize a LiveUpdateContribution instance.

Parameters

update – An instance of LiveUpdate.

This instance can be retrieved through update.contrib where update is a LiveUpdate instance. E.g.,

thread = reddit.live("ukaeu1ik4sw5")
update = thread["7827987a-c998-11e4-a0b9-22000b6a88d2"]
update.contrib  # LiveUpdateContribution instance
update.contrib.remove()
remove()

Remove a live update.

Usage:

thread = reddit.live("ydwwxneu7vsa")
update = thread["6854605a-efec-11e6-b0c7-0eafac4ff094"]
update.contrib.remove()
strike()

Strike a content of a live update.

thread = reddit.live("xyu8kmjvfrww")
update = thread["cb5fe532-dbee-11e6-9a91-0e6d74fabcc4"]
update.contrib.strike()

To check whether the update is stricken or not, use update.stricken attribute.

Note

Accessing lazy attributes on updates (includes update.stricken) may raise AttributeError. See LiveUpdate for details.

ContributorRelationship

class praw.models.reddit.subreddit.ContributorRelationship(subreddit: praw.models.Subreddit, relationship: str)

Provides methods to interact with a Subreddit’s contributors.

Contributors are also known as approved submitters.

Contributors of a subreddit can be iterated through like so:

for contributor in reddit.subreddit("test").contributor():
    print(contributor)
__call__(redditor: Optional[Union[praw.models.Redditor, str]] = None, **generator_kwargs) Iterator[praw.models.Redditor]

Return a ListingGenerator for Redditors in the relationship.

Parameters

redditor – When provided, yield at most a single Redditor instance. This is useful to confirm if a relationship exists, or to fetch the metadata associated with a particular relationship (default: None).

Additional keyword arguments are passed in the initialization of ListingGenerator.

__init__(subreddit: praw.models.Subreddit, relationship: str)

Initialize a SubredditRelationship instance.

Parameters
  • subreddit – The Subreddit for the relationship.

  • relationship – The name of the relationship.

add(redditor: Union[str, praw.models.Redditor], **other_settings: Any)

Add redditor to this relationship.

Parameters

redditor – A redditor name or Redditor instance.

leave()

Abdicate the contributor position.

remove(redditor: Union[str, praw.models.Redditor])

Remove redditor from this relationship.

Parameters

redditor – A redditor name or Redditor instance.

ModeratorRelationship

class praw.models.reddit.subreddit.ModeratorRelationship(subreddit: praw.models.Subreddit, relationship: str)

Provides methods to interact with a Subreddit’s moderators.

Moderators of a subreddit can be iterated through like so:

for moderator in reddit.subreddit("test").moderator():
    print(moderator)
__call__(redditor: Optional[Union[praw.models.Redditor, str]] = None) List[praw.models.Redditor]

Return a list of Redditors who are moderators.

Parameters

redditor – When provided, return a list containing at most one Redditor instance. This is useful to confirm if a relationship exists, or to fetch the metadata associated with a particular relationship (default: None).

Note

To help mitigate targeted moderator harassment, this call requires the Reddit instance to be authenticated i.e., read_only must return False. This call, however, only makes use of the read scope. For more information on why the moderator list is hidden can be found here: https://reddit.zendesk.com/hc/en-us/articles/360049499032-Why-is-the-moderator-list-hidden-

Note

Unlike other relationship callables, this relationship is not paginated. Thus it simply returns the full list, rather than an iterator for the results.

To be used like:

moderators = reddit.subreddit("test").moderator()

For example, to list the moderators along with their permissions try:

for moderator in reddit.subreddit("test").moderator():
    print(f"{moderator}: {moderator.mod_permissions}")
__init__(subreddit: praw.models.Subreddit, relationship: str)

Initialize a SubredditRelationship instance.

Parameters
  • subreddit – The Subreddit for the relationship.

  • relationship – The name of the relationship.

add(redditor: Union[str, praw.models.Redditor], *, permissions: Optional[List[str]] = None, **other_settings: Any)

Add or invite redditor to be a moderator of the Subreddit.

Parameters
  • redditor – A redditor name or Redditor instance.

  • permissions – When provided (not None), permissions should be a list of strings specifying which subset of permissions to grant. An empty list [] indicates no permissions, and when not provided None, indicates full permissions (default: None).

An invite will be sent unless the user making this call is an admin user.

For example, to invite u/spez with "posts" and "mail" permissions to r/test, try:

reddit.subreddit("test").moderator.add("spez", permissions=["posts", "mail"])
invite(redditor: Union[str, praw.models.Redditor], *, permissions: Optional[List[str]] = None, **other_settings: Any)

Invite redditor to be a moderator of the Subreddit.

Parameters
  • redditor – A redditor name or Redditor instance.

  • permissions – When provided (not None), permissions should be a list of strings specifying which subset of permissions to grant. An empty list [] indicates no permissions, and when not provided None, indicates full permissions (default: None).

For example, to invite u/spez with "posts" and "mail" permissions to r/test, try:

reddit.subreddit("test").moderator.invite("spez", permissions=["posts", "mail"])
invited(*, redditor: Optional[Union[praw.models.Redditor, str]] = None, **generator_kwargs: Any) Iterator[praw.models.Redditor]

Return a ListingGenerator for Redditors invited to be moderators.

Parameters

redditor – When provided, return a list containing at most one Redditor instance. This is useful to confirm if a relationship exists, or to fetch the metadata associated with a particular relationship (default: None).

Additional keyword arguments are passed in the initialization of ListingGenerator.

Note

Unlike other usages of ListingGenerator, limit has no effect in the quantity returned. This endpoint always returns moderators in batches of 25 at a time regardless of what limit is set to.

Usage:

for invited_mod in reddit.subreddit("test").moderator.invited():
    print(invited_mod)
leave()

Abdicate the moderator position (use with care).

For example:

reddit.subreddit("test").moderator.leave()
remove(redditor: Union[str, praw.models.Redditor])

Remove redditor from this relationship.

Parameters

redditor – A redditor name or Redditor instance.

remove_invite(redditor: Union[str, praw.models.Redditor])

Remove the moderator invite for redditor.

Parameters

redditor – A redditor name or Redditor instance.

For example:

reddit.subreddit("test").moderator.remove_invite("spez")
update(redditor: Union[str, praw.models.Redditor], *, permissions: Optional[List[str]] = None)

Update the moderator permissions for redditor.

Parameters
  • redditor – A redditor name or Redditor instance.

  • permissions – When provided (not None), permissions should be a list of strings specifying which subset of permissions to grant. An empty list [] indicates no permissions, and when not provided, None, indicates full permissions (default: None).

For example, to add all permissions to the moderator, try:

subreddit.moderator.update("spez")

To remove all permissions from the moderator, try:

subreddit.moderator.update("spez", permissions=[])
update_invite(redditor: Union[str, praw.models.Redditor], *, permissions: Optional[List[str]] = None)

Update the moderator invite permissions for redditor.

Parameters
  • redditor – A redditor name or Redditor instance.

  • permissions – When provided (not None), permissions should be a list of strings specifying which subset of permissions to grant. An empty list [] indicates no permissions, and when not provided, None, indicates full permissions (default: None).

For example, to grant the "flair" and "mail" permissions to the moderator invite, try:

subreddit.moderator.update_invite("spez", permissions=["flair", "mail"])

SubredditRelationship

class praw.models.reddit.subreddit.SubredditRelationship(subreddit: praw.models.Subreddit, relationship: str)

Represents a relationship between a Redditor and Subreddit.

Instances of this class can be iterated through in order to discover the Redditors that make up the relationship.

For example, banned users of a subreddit can be iterated through like so:

for ban in reddit.subreddit("test").banned():
    print(f"{ban}: {ban.note}")
__call__(redditor: Optional[Union[praw.models.Redditor, str]] = None, **generator_kwargs) Iterator[praw.models.Redditor]

Return a ListingGenerator for Redditors in the relationship.

Parameters

redditor – When provided, yield at most a single Redditor instance. This is useful to confirm if a relationship exists, or to fetch the metadata associated with a particular relationship (default: None).

Additional keyword arguments are passed in the initialization of ListingGenerator.

__init__(subreddit: praw.models.Subreddit, relationship: str)

Initialize a SubredditRelationship instance.

Parameters
  • subreddit – The Subreddit for the relationship.

  • relationship – The name of the relationship.

add(redditor: Union[str, praw.models.Redditor], **other_settings: Any)

Add redditor to this relationship.

Parameters

redditor – A redditor name or Redditor instance.

remove(redditor: Union[str, praw.models.Redditor])

Remove redditor from this relationship.

Parameters

redditor – A redditor name or Redditor instance.

SubredditEmoji

class praw.models.reddit.emoji.SubredditEmoji(subreddit: praw.models.Subreddit)

Provides a set of functions to a Subreddit for emoji.

__getitem__(name: str) Emoji

Lazily return the Emoji for the subreddit named name.

Parameters

name – The name of the emoji.

This method is to be used to fetch a specific emoji url, like so:

emoji = reddit.subreddit("test").emoji["emoji"]
print(emoji)
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditEmoji instance.

Parameters

subreddit – The subreddit whose emoji are affected.

__iter__() List[Emoji]

Return a list of Emoji for the subreddit.

This method is to be used to discover all emoji for a subreddit:

for emoji in reddit.subreddit("test").emoji:
    print(emoji)
add(*, image_path: str, mod_flair_only: Optional[bool] = None, name: str, post_flair_allowed: Optional[bool] = None, user_flair_allowed: Optional[bool] = None) Emoji

Add an emoji to this subreddit.

Parameters
  • image_path – A path to a jpeg or png image.

  • mod_flair_only – When provided, indicate whether the emoji is restricted to mod use only (default: None).

  • name – The name of the emoji.

  • post_flair_allowed – When provided, indicate whether the emoji may appear in post flair (default: None).

  • user_flair_allowed – When provided, indicate whether the emoji may appear in user flair (default: None).

Returns

The Emoji added.

To add "emoji" to r/test try:

reddit.subreddit("test").emoji.add(name="emoji", image_path="emoji.png")

SubredditFilters

class praw.models.reddit.subreddit.SubredditFilters(subreddit: praw.models.Subreddit)

Provide functions to interact with the special Subreddit’s filters.

Members of this class should be utilized via Subreddit.filters(). For example, to add a filter, run:

reddit.subreddit("all").filters.add("test")
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditFilters instance.

Parameters

subreddit – The special subreddit whose filters to work with.

As of this writing filters can only be used with the special subreddits all and mod.

__iter__() Generator[praw.models.Subreddit, None, None]

Iterate through the special Subreddit’s filters.

This method should be invoked as:

for subreddit in reddit.subreddit("test").filters:
    ...
add(subreddit: Union[praw.models.Subreddit, str])

Add subreddit to the list of filtered subreddits.

Parameters

subreddit – The subreddit to add to the filter list.

Items from subreddits added to the filtered list will no longer be included when obtaining listings for r/all.

Alternatively, you can filter a subreddit temporarily from a special listing in a manner like so:

reddit.subreddit("all-redditdev-learnpython")
Raises

prawcore.NotFound when calling on a non-special subreddit.

remove(subreddit: Union[praw.models.Subreddit, str])

Remove subreddit from the list of filtered subreddits.

Parameters

subreddit – The subreddit to remove from the filter list.

Raises

prawcore.NotFound when calling on a non-special subreddit.

SubredditModerationStream

class praw.models.reddit.subreddit.SubredditModerationStream(subreddit: praw.models.Subreddit)

Provides moderator streams.

__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditModerationStream instance.

Parameters

subreddit – The moderated subreddit associated with the streams.

edited(*, only: Optional[str] = None, **stream_options: Any) Generator[Union[praw.models.Comment, praw.models.Submission], None, None]

Yield edited comments and submissions as they become available.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Keyword arguments are passed to stream_generator().

For example, to retrieve all new edited submissions/comments made to all moderated subreddits, try:

for item in reddit.subreddit("mod").mod.stream.edited():
    print(item)
log(*, action: Optional[str] = None, mod: Optional[Union[praw.models.Redditor, str]] = None, **stream_options: Any) Generator[praw.models.ModAction, None, None]

Yield moderator log entries as they become available.

Parameters
  • action – If given, only return log entries for the specified action.

  • mod – If given, only return log entries for actions made by the passed in redditor.

For example, to retrieve all new mod actions made to all moderated subreddits, try:

for log in reddit.subreddit("mod").mod.stream.log():
    print(f"Mod: {log.mod}, Subreddit: {log.subreddit}")
modmail_conversations(*, other_subreddits: Optional[List[praw.models.Subreddit]] = None, sort: Optional[str] = None, state: Optional[str] = None, **stream_options: Any) Generator[ModmailConversation, None, None]

Yield new-modmail conversations as they become available.

Parameters
  • other_subreddits – A list of Subreddit instances for which to fetch conversations (default: None).

  • sort – Can be one of: "mod", "recent", "unread", or "user" (default: "recent").

  • state – Can be one of: "all", "appeals", "archived", "default", "highlighted", "inbox", "inprogress", "join_requests", "mod", "new", or "notifications" (default: "all"). "all" does not include mod or archived conversations. "inbox" does not include appeals conversations.

Keyword arguments are passed to stream_generator().

To print new mail in the unread modmail queue try:

subreddit = reddit.subreddit("all")
for message in subreddit.mod.stream.modmail_conversations():
    print(f"From: {message.owner}, To: {message.participant}")
modqueue(*, only: Optional[str] = None, **stream_options: Any) Generator[Union[praw.models.Comment, praw.models.Submission], None, None]

Yield Comments and Submissions in the modqueue as they become available.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Keyword arguments are passed to stream_generator().

To print all new modqueue items try:

for item in reddit.subreddit("mod").mod.stream.modqueue():
    print(item)
reports(*, only: Optional[str] = None, **stream_options: Any) Generator[Union[praw.models.Comment, praw.models.Submission], None, None]

Yield reported Comments and Submissions as they become available.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Keyword arguments are passed to stream_generator().

To print new user and mod report reasons in the report queue try:

for item in reddit.subreddit("mod").mod.stream.reports():
    print(item)
spam(*, only: Optional[str] = None, **stream_options: Any) Generator[Union[praw.models.Comment, praw.models.Submission], None, None]

Yield spam Comments and Submissions as they become available.

Parameters

only – If specified, one of "comments" or "submissions" to yield only results of that type.

Keyword arguments are passed to stream_generator().

To print new items in the spam queue try:

for item in reddit.subreddit("mod").mod.stream.spam():
    print(item)
unmoderated(**stream_options: Any) Generator[praw.models.Submission, None, None]

Yield unmoderated Submissions as they become available.

Keyword arguments are passed to stream_generator().

To print new items in the unmoderated queue try:

for item in reddit.subreddit("mod").mod.stream.unmoderated():
    print(item)
unread(**stream_options: Any) Generator[praw.models.SubredditMessage, None, None]

Yield unread old modmail messages as they become available.

Keyword arguments are passed to stream_generator().

See also

SubredditModeration.inbox() for all messages.

To print new mail in the unread modmail queue try:

for message in reddit.subreddit("mod").mod.stream.unread():
    print(f"From: {message.author}, To: {message.dest}")

SubredditQuarantine

class praw.models.reddit.subreddit.SubredditQuarantine(subreddit: praw.models.Subreddit)

Provides subreddit quarantine related methods.

To opt-in into a quarantined subreddit:

reddit.subreddit("test").quaran.opt_in()
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditQuarantine instance.

Parameters

subreddit – The Subreddit associated with the quarantine.

opt_in()

Permit your user access to the quarantined subreddit.

Usage:

subreddit = reddit.subreddit("QUESTIONABLE")
next(subreddit.hot())  # Raises prawcore.Forbidden

subreddit.quaran.opt_in()
next(subreddit.hot())  # Returns Submission
opt_out()

Remove access to the quarantined subreddit.

Usage:

subreddit = reddit.subreddit("QUESTIONABLE")
next(subreddit.hot())  # Returns Submission

subreddit.quaran.opt_out()
next(subreddit.hot())  # Raises prawcore.Forbidden

SubredditRemovalReasons

class praw.models.reddit.removal_reasons.SubredditRemovalReasons(subreddit: praw.models.Subreddit)

Provide a set of functions to a Subreddit’s removal reasons.

__getitem__(reason_id: Union[str, int, slice]) RemovalReason

Return the Removal Reason with the ID/number/slice reason_id.

Parameters

reason_id – The ID or index of the removal reason

Note

Removal reasons fetched using a specific rule name are lazily loaded, so you might have to access an attribute to get all the expected attributes.

This method is to be used to fetch a specific removal reason, like so:

reason_id = "141vv5c16py7d"
reason = reddit.subreddit("test").mod.removal_reasons[reason_id]
print(reason)

You can also use indices to get a numbered removal reason. Since Python uses 0-indexing, the first removal reason is index 0, and so on.

Note

Both negative indices and slices can be used to interact with the removal reasons.

Raises

IndexError if a removal reason of a specific number does not exist.

For example, to get the second removal reason of r/test:

reason = reddit.subreddit("test").mod.removal_reasons[1]

To get the last three removal reasons in a subreddit:

reasons = reddit.subreddit("test").mod.removal_reasons[-3:]
for reason in reasons:
    print(reason)
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditRemovalReasons instance.

Parameters

subreddit – The subreddit whose removal reasons to work with.

__iter__() Iterator[RemovalReason]

Return a list of Removal Reasons for the subreddit.

This method is used to discover all removal reasons for a subreddit:

for removal_reason in reddit.subreddit("test").mod.removal_reasons:
    print(removal_reason)
add(*, message: str, title: str) RemovalReason

Add a removal reason to this subreddit.

Parameters
  • message – The message associated with the removal reason.

  • title – The title of the removal reason.

Returns

The RemovalReason added.

The message will be prepended with Hi u/username, automatically.

To add "Test" to r/test try:

reddit.subreddit("test").mod.removal_reasons.add(title="Test", message="Foobar")

SubredditRules

class praw.models.reddit.rules.SubredditRules(subreddit: praw.models.Subreddit)

Provide a set of functions to access a Subreddit’s rules.

For example, to list all the rules for a subreddit:

for rule in reddit.subreddit("test").rules:
    print(rule)

Moderators can also add rules to the subreddit. For example, to make a rule called "No spam" in r/test:

reddit.subreddit("test").rules.mod.add(
    short_name="No spam", kind="all", description="Do not spam. Spam bad"
)
__call__() List[praw.models.Rule]

Return a list of Rules (Deprecated).

Returns

A list of instances of Rule.

Deprecated since version 7.1: Use the iterator by removing the call to SubredditRules. For example, in order to use the iterator:

for rule in reddit.subreddit("test").rules:
    print(rule)
__getitem__(short_name: Union[str, int, slice]) praw.models.Rule

Return the Rule for the subreddit with short_name short_name.

Parameters

short_name – The short_name of the rule, or the rule number.

Note

Rules fetched using a specific rule name are lazily loaded, so you might have to access an attribute to get all the expected attributes.

This method is to be used to fetch a specific rule, like so:

rule_name = "No spam"
rule = reddit.subreddit("test").rules[rule_name]
print(rule)

You can also fetch a numbered rule of a subreddit.

Rule numbers start at 0, so the first rule is at index 0, and the second rule is at index 1, and so on.

Raises

IndexError if a rule of a specific number does not exist.

Note

You can use negative indexes, such as -1, to get the last rule. You can also use slices, to get a subset of rules, such as the last three rules with rules[-3:].

For example, to fetch the second rule of r/test:

rule = reddit.subreddit("test").rules[1]
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditRules instance.

Parameters

subreddit – The subreddit whose rules to work with.

__iter__() Iterator[praw.models.Rule]

Iterate through the rules of the subreddit.

Returns

An iterator containing all the rules of a subreddit.

This method is used to discover all rules for a subreddit.

For example, to get the rules for r/test:

for rule in reddit.subreddit("test").rules:
    print(rule)
mod() SubredditRulesModeration

Contain methods to moderate subreddit rules as a whole.

To add rule "No spam" to r/test try:

reddit.subreddit("test").rules.mod.add(
    short_name="No spam", kind="all", description="Do not spam. Spam bad"
)

To move the fourth rule to the first position, and then to move the prior first rule to where the third rule originally was in r/test:

subreddit = reddit.subreddit("test")
rules = list(subreddit.rules)
new_rules = rules[3:4] + rules[1:3] + rules[0:1] + rules[4:]
# Alternate: [rules[3]] + rules[1:3] + [rules[0]] + rules[4:]
new_rule_list = subreddit.rules.mod.reorder(new_rules)

SubredditStream

class praw.models.reddit.subreddit.SubredditStream(subreddit: praw.models.Subreddit)

Provides submission and comment streams.

__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditStream instance.

Parameters

subreddit – The subreddit associated with the streams.

comments(**stream_options: Any) Generator[praw.models.Comment, None, None]

Yield new comments as they become available.

Comments are yielded oldest first. Up to 100 historical comments will initially be returned.

Keyword arguments are passed to stream_generator().

Note

While PRAW tries to catch all new comments, some high-volume streams, especially the r/all stream, may drop some comments.

For example, to retrieve all new comments made to r/test, try:

for comment in reddit.subreddit("test").stream.comments():
    print(comment)

To only retrieve new submissions starting when the stream is created, pass skip_existing=True:

subreddit = reddit.subreddit("test")
for comment in subreddit.stream.comments(skip_existing=True):
    print(comment)
submissions(**stream_options: Any) Generator[praw.models.Submission, None, None]

Yield new Submissions as they become available.

Submissions are yielded oldest first. Up to 100 historical submissions will initially be returned.

Keyword arguments are passed to stream_generator().

Note

While PRAW tries to catch all new submissions, some high-volume streams, especially the r/all stream, may drop some submissions.

For example, to retrieve all new submissions made to all of Reddit, try:

for submission in reddit.subreddit("all").stream.submissions():
    print(submission)

SubredditStylesheet

class praw.models.reddit.subreddit.SubredditStylesheet(subreddit: praw.models.Subreddit)

Provides a set of stylesheet functions to a Subreddit.

For example, to add the css data .test{color:blue} to the existing stylesheet:

subreddit = reddit.subreddit("test")
stylesheet = subreddit.stylesheet()
stylesheet.stylesheet += ".test{color:blue}"
subreddit.stylesheet.update(stylesheet.stylesheet)
__call__() praw.models.Stylesheet

Return the Subreddit’s stylesheet.

To be used as:

stylesheet = reddit.subreddit("test").stylesheet()
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditStylesheet instance.

Parameters

subreddit – The Subreddit associated with the stylesheet.

An instance of this class is provided as:

reddit.subreddit("test").stylesheet
delete_banner()

Remove the current Subreddit (redesign) banner image.

Succeeds even if there is no banner image.

For example:

reddit.subreddit("test").stylesheet.delete_banner()
delete_banner_additional_image()

Remove the current Subreddit (redesign) banner additional image.

Succeeds even if there is no additional image. Will also delete any configured hover image.

For example:

reddit.subreddit("test").stylesheet.delete_banner_additional_image()
delete_banner_hover_image()

Remove the current Subreddit (redesign) banner hover image.

Succeeds even if there is no hover image.

For example:

reddit.subreddit("test").stylesheet.delete_banner_hover_image()
delete_header()

Remove the current Subreddit header image.

Succeeds even if there is no header image.

For example:

reddit.subreddit("test").stylesheet.delete_header()
delete_image(name: str)

Remove the named image from the Subreddit.

Succeeds even if the named image does not exist.

For example:

reddit.subreddit("test").stylesheet.delete_image("smile")
delete_mobile_header()

Remove the current Subreddit mobile header.

Succeeds even if there is no mobile header.

For example:

reddit.subreddit("test").stylesheet.delete_mobile_header()
delete_mobile_icon()

Remove the current Subreddit mobile icon.

Succeeds even if there is no mobile icon.

For example:

reddit.subreddit("test").stylesheet.delete_mobile_icon()
update(stylesheet: str, *, reason: Optional[str] = None)

Update the Subreddit’s stylesheet.

Parameters
  • stylesheet – The CSS for the new stylesheet.

  • reason – The reason for updating the stylesheet.

For example:

reddit.subreddit("test").stylesheet.update(
    "p { color: green; }", reason="color text green"
)
upload(*, image_path: str, name: str) Dict[str, str]

Upload an image to the Subreddit.

Parameters
  • image_path – A path to a jpeg or png image.

  • name – The name to use for the image. If an image already exists with the same name, it will be replaced.

Returns

A dictionary containing a link to the uploaded image under the key img_src.

Raises

prawcore.TooLarge if the overall request body is too large.

Raises

RedditAPIException if there are other issues with the uploaded image. Unfortunately the exception info might not be very specific, so try through the website with the same image to see what the problem actually might be.

For example:

reddit.subreddit("test").stylesheet.upload(name="smile", image_path="img.png")
upload_banner(image_path: str)

Upload an image for the Subreddit’s (redesign) banner image.

Parameters

image_path – A path to a jpeg or png image.

Raises

prawcore.TooLarge if the overall request body is too large.

Raises

RedditAPIException if there are other issues with the uploaded image. Unfortunately the exception info might not be very specific, so try through the website with the same image to see what the problem actually might be.

For example:

reddit.subreddit("test").stylesheet.upload_banner("banner.png")
upload_banner_additional_image(image_path: str, *, align: Optional[str] = None)

Upload an image for the Subreddit’s (redesign) additional image.

Parameters
  • image_path – A path to a jpeg or png image.

  • align – Either "left", "centered", or "right". (default: "left").

Raises

prawcore.TooLarge if the overall request body is too large.

Raises

RedditAPIException if there are other issues with the uploaded image. Unfortunately the exception info might not be very specific, so try through the website with the same image to see what the problem actually might be.

For example:

subreddit = reddit.subreddit("test")
subreddit.stylesheet.upload_banner_additional_image("banner.png")
upload_banner_hover_image(image_path: str)

Upload an image for the Subreddit’s (redesign) additional image.

Parameters

image_path – A path to a jpeg or png image.

Fails if the Subreddit does not have an additional image defined.

Raises

prawcore.TooLarge if the overall request body is too large.

Raises

RedditAPIException if there are other issues with the uploaded image. Unfortunately the exception info might not be very specific, so try through the website with the same image to see what the problem actually might be.

For example:

subreddit = reddit.subreddit("test")
subreddit.stylesheet.upload_banner_hover_image("banner.png")
upload_header(image_path: str) Dict[str, str]

Upload an image to be used as the Subreddit’s header image.

Parameters

image_path – A path to a jpeg or png image.

Returns

A dictionary containing a link to the uploaded image under the key img_src.

Raises

prawcore.TooLarge if the overall request body is too large.

Raises

RedditAPIException if there are other issues with the uploaded image. Unfortunately the exception info might not be very specific, so try through the website with the same image to see what the problem actually might be.

For example:

reddit.subreddit("test").stylesheet.upload_header("header.png")
upload_mobile_header(image_path: str) Dict[str, str]

Upload an image to be used as the Subreddit’s mobile header.

Parameters

image_path – A path to a jpeg or png image.

Returns

A dictionary containing a link to the uploaded image under the key img_src.

Raises

prawcore.TooLarge if the overall request body is too large.

Raises

RedditAPIException if there are other issues with the uploaded image. Unfortunately the exception info might not be very specific, so try through the website with the same image to see what the problem actually might be.

For example:

reddit.subreddit("test").stylesheet.upload_mobile_header("header.png")
upload_mobile_icon(image_path: str) Dict[str, str]

Upload an image to be used as the Subreddit’s mobile icon.

Parameters

image_path – A path to a jpeg or png image.

Returns

A dictionary containing a link to the uploaded image under the key img_src.

Raises

prawcore.TooLarge if the overall request body is too large.

Raises

RedditAPIException if there are other issues with the uploaded image. Unfortunately the exception info might not be very specific, so try through the website with the same image to see what the problem actually might be.

For example:

reddit.subreddit("test").stylesheet.upload_mobile_icon("icon.png")

SubredditWidgets

class praw.models.SubredditWidgets(subreddit: praw.models.Subreddit)

Class to represent a Subreddit’s widgets.

Create an instance like so:

widgets = reddit.subreddit("test").widgets

Data will be lazy-loaded. By default, PRAW will not request progressively loading images from Reddit. To enable this, instantiate a SubredditWidgets object via widgets(), then set the attribute progressive_images to True before performing any action that would result in a network request.

widgets = reddit.subreddit("test").widgets
widgets.progressive_images = True
for widget in widgets.sidebar:
    # do something
    ...

Access a Subreddit’s widgets with the following attributes:

print(widgets.id_card)
print(widgets.moderators_widget)
print(widgets.sidebar)
print(widgets.topbar)

The attribute id_card contains the Subreddit’s ID card, which displays information like the number of subscribers.

The attribute moderators_widget contains the Subreddit’s moderators widget, which lists the moderators of the subreddit.

The attribute sidebar contains a list of widgets which make up the sidebar of the subreddit.

The attribute topbar contains a list of widgets which make up the top bar of the subreddit.

To edit a Subreddit’s widgets, use mod. For example:

widgets.mod.add_text_area(
    short_name="My title",
    text="**bold text**",
    styles={"backgroundColor": "#FFFF66", "headerColor": "#3333EE"},
)

For more information, see SubredditWidgetsModeration.

To edit a particular widget, use .mod on the widget. For example:

for widget in widgets.sidebar:
    widget.mod.update(shortName="Exciting new name")

For more information, see WidgetModeration.

Currently available widgets:

__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditWidgets instance.

Parameters

subreddit – The Subreddit the widgets belong to.

id_card() praw.models.IDCard

Get this Subreddit’s IDCard widget.

items() Dict[str, praw.models.Widget]

Get this Subreddit’s widgets as a dict from ID to widget.

mod() praw.models.SubredditWidgetsModeration

Get an instance of SubredditWidgetsModeration.

Note

Using any of the methods of SubredditWidgetsModeration will likely result in the data of this SubredditWidgets being outdated. To re-sync, call refresh().

moderators_widget() praw.models.ModeratorsWidget

Get this Subreddit’s ModeratorsWidget.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

refresh()

Refresh the Subreddit’s widgets.

By default, PRAW will not request progressively loading images from Reddit. To enable this, set the attribute progressive_images to True prior to calling refresh().

widgets = reddit.subreddit("test").widgets
widgets.progressive_images = True
widgets.refresh()
sidebar() List[praw.models.Widget]

Get a list of Widgets that make up the sidebar.

topbar() List[praw.models.Menu]

Get a list of Widgets that make up the top bar.

SubredditWiki

class praw.models.reddit.subreddit.SubredditWiki(subreddit: praw.models.Subreddit)

Provides a set of wiki functions to a Subreddit.

__getitem__(page_name: str) WikiPage

Lazily return the WikiPage for the Subreddit named page_name.

This method is to be used to fetch a specific wikipage, like so:

wikipage = reddit.subreddit("test").wiki["proof"]
print(wikipage.content_md)
__init__(subreddit: praw.models.Subreddit)

Initialize a SubredditWiki instance.

Parameters

subreddit – The subreddit whose wiki to work with.

__iter__() Generator[WikiPage, None, None]

Iterate through the pages of the wiki.

This method is to be used to discover all wikipages for a subreddit:

for wikipage in reddit.subreddit("test").wiki:
    print(wikipage)
create(*, content: str, name: str, reason: Optional[str] = None, **other_settings: Any)

Create a new WikiPage.

Parameters
  • name – The name of the new WikiPage. This name will be normalized.

  • content – The content of the new WikiPage.

  • reason – The reason for the creation.

  • other_settings – Additional keyword arguments to pass.

To create the wiki page "praw_test" in r/test try:

reddit.subreddit("test").wiki.create(
    name="praw_test", content="wiki body text", reason="PRAW Test Creation"
)
revisions(**generator_kwargs: Any) Generator[Dict[str, Optional[Union[praw.models.Redditor, WikiPage, str, int, bool]]], None, None]

Return a ListingGenerator for recent wiki revisions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

To view the wiki revisions for "praw_test" in r/test try:

for item in reddit.subreddit("test").wiki["praw_test"].revisions():
    print(item)

Button

class praw.models.Button(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Class to represent a single button inside a ButtonWidget.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

color

The hex color used to outline the button.

fillColor

The hex color for the background of the button.

height

Image height. Only present on image buttons.

hoverState

A dict describing the state of the button when hovered over. Optional.

kind

Either "text" or "image".

linkUrl

A link that can be visited by clicking the button. Only present on image buttons.

text

The text displayed on the button.

textColor

The hex color for the text of the button.

url

  • If the button is a text button, a link that can be visited by clicking the button.

  • If the button is an image button, the URL of a Reddit-hosted image.

width

Image width. Only present on image buttons.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

ButtonWidget

class praw.models.ButtonWidget(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent a widget containing one or more buttons.

Find an existing one:

button_widget = None
widgets = reddit.subreddit("test").widgets
for widget in widgets.sidebar:
    if isinstance(widget, praw.models.ButtonWidget):
        button_widget = widget
        break

for button in button_widget:
    print(button.text, button.url)

Create one:

widgets = reddit.subreddit("test").widgets
buttons = [
    {
        "kind": "text",
        "text": "View source",
        "url": "https://github.com/praw-dev/praw",
        "color": "#FF0000",
        "textColor": "#00FF00",
        "fillColor": "#0000FF",
        "hoverState": {
            "kind": "text",
            "text": "ecruos weiV",
            "color": "#000000",
            "textColor": "#FFFFFF",
            "fillColor": "#0000FF",
        },
    },
    {
        "kind": "text",
        "text": "View documentation",
        "url": "https://praw.readthedocs.io",
        "color": "#FFFFFF",
        "textColor": "#FFFF00",
        "fillColor": "#0000FF",
    },
]
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
button_widget = widgets.mod.add_button_widget(
    "Things to click", "Click some of these *cool* links!", buttons, styles
)

For more information on creation, see add_button_widget().

Update one:

new_styles = {"backgroundColor": "#FFFFFF", "headerColor": "#FF9900"}
button_widget = button_widget.mod.update(shortName="My fav buttons", styles=new_styles)

Delete one:

button_widget.mod.delete()

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

buttons

A list of Buttons. These can also be accessed just by iterating over the ButtonWidget (e.g., for button in button_widget).

description

The description, in Markdown.

description_html

The description, in HTML.

id

The widget ID.

kind

The widget kind (always "button").

shortName

The short name of the widget.

styles

A dict with the keys "backgroundColor" and "headerColor".

subreddit

The Subreddit the button widget belongs to.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Widget instance.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Calendar

class praw.models.Calendar(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent a calendar widget.

Find an existing one:

calendar = None
widgets = reddit.subreddit("test").widgets
for widget in widgets.sidebar:
    if isinstance(widget, praw.models.Calendar):
        calendar = widget
        break

print(calendar.googleCalendarId)

Create one:

widgets = reddit.subreddit("test").widgets
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
config = {
    "numEvents": 10,
    "showDate": True,
    "showDescription": False,
    "showLocation": False,
    "showTime": True,
    "showTitle": True,
}
cal_id = "y6nm89jy427drk8l71w75w9wjn@group.calendar.google.com"
calendar = widgets.mod.add_calendar(
    short_name="Upcoming Events",
    google_calendar_id=cal_id,
    requires_sync=True,
    configuration=config,
    styles=styles,
)

For more information on creation, see add_calendar().

Update one:

new_styles = {"backgroundColor": "#FFFFFF", "headerColor": "#FF9900"}
calendar = calendar.mod.update(shortName="My fav events", styles=new_styles)

Delete one:

calendar.mod.delete()

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

configuration

A dict describing the calendar configuration.

data

A list of dictionaries that represent events.

id

The widget ID.

kind

The widget kind (always "calendar").

requiresSync

A bool representing whether the calendar requires synchronization.

shortName

The short name of the widget.

styles

A dict with the keys "backgroundColor" and "headerColor".

subreddit

The Subreddit the button widget belongs to.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Widget instance.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

CalendarConfiguration

class praw.models.CalendarConfiguration(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Class to represent the configuration of a Calendar.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

numEvents

The number of events to display on the calendar.

showDate

Whether to show the dates of events.

showDescription

Whether to show the descriptions of events.

showLocation

Whether to show the locations of events.

showTime

Whether to show the times of events.

showTitle

Whether to show the titles of events.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

CommunityList

class praw.models.CommunityList(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent a Related Communities widget.

Find an existing one:

community_list = None
widgets = reddit.subreddit("test").widgets
for widget in widgets.sidebar:
    if isinstance(widget, praw.models.CommunityList):
        community_list = widget
        break

print(community_list)

Create one:

widgets = reddit.subreddit("test").widgets
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
subreddits = ["learnpython", reddit.subreddit("test")]
community_list = widgets.mod.add_community_list(
    short_name="Related subreddits",
    data=subreddits,
    styles=styles,
    description="description",
)

For more information on creation, see add_community_list().

Update one:

new_styles = {"backgroundColor": "#FFFFFF", "headerColor": "#FF9900"}
community_list = community_list.mod.update(shortName="My fav subs", styles=new_styles)

Delete one:

community_list.mod.delete()

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

data

A list of Subreddits. These can also be iterated over by iterating over the CommunityList (e.g., for sub in community_list).

id

The widget ID.

kind

The widget kind (always "community-list").

shortName

The short name of the widget.

styles

A dict with the keys "backgroundColor" and "headerColor".

subreddit

The Subreddit the button widget belongs to.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Widget instance.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

CustomWidget

class praw.models.CustomWidget(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent a custom widget.

Find an existing one:

custom = None
widgets = reddit.subreddit("test").widgets
for widget in widgets.sidebar:
    if isinstance(widget, praw.models.CustomWidget):
        custom = widget
        break

print(custom.text)
print(custom.css)

Create one:

widgets = reddit.subreddit("test").widgets
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
custom = widgets.mod.add_custom_widget(
    short_name="My custom widget",
    text="# Hello world!",
    css="/**/",
    height=200,
    image_data=[],
    styles=styles,
)

For more information on creation, see add_custom_widget().

Update one:

new_styles = {"backgroundColor": "#FFFFFF", "headerColor": "#FF9900"}
custom = custom.mod.update(shortName="My fav customization", styles=new_styles)

Delete one:

custom.mod.delete()

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

css

The CSS of the widget, as a str.

height

The height of the widget, as an int.

id

The widget ID.

imageData

A list of ImageData that belong to the widget.

kind

The widget kind (always "custom").

shortName

The short name of the widget.

styles

A dict with the keys "backgroundColor" and "headerColor".

stylesheetUrl

A link to the widget’s stylesheet.

subreddit

The Subreddit the button widget belongs to.

text

The text contents, as Markdown.

textHtml

The text contents, as HTML.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a CustomWidget instance.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Hover

class praw.models.Hover(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Class to represent the hover data for a ButtonWidget.

These values will take effect when the button is hovered over (the user moves their cursor so it’s on top of the button).

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

color

The hex color used to outline the button.

fillColor

The hex color for the background of the button.

textColor

The hex color for the text of the button.

height

Image height. Only present on image buttons.

kind

Either text or image.

text

The text displayed on the button.

url

  • If the button is a text button, a link that can be visited by clicking the button.

  • If the button is an image button, the URL of a Reddit-hosted image.

width

Image width. Only present on image buttons.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

IDCard

class praw.models.IDCard(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent an ID card widget.

widgets = reddit.subreddit("test").widgets
id_card = widgets.id_card
print(id_card.subscribersText)

Update one:

widgets.id_card.mod.update(currentlyViewingText="Bots")

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

currentlyViewingCount

The number of redditors viewing the subreddit.

currentlyViewingText

The text displayed next to the view count. For example, "users online".

description

The subreddit description.

id

The widget ID.

kind

The widget kind (always "id-card").

shortName

The short name of the widget.

styles

A dict with the keys "backgroundColor" and "headerColor".

subreddit

The Subreddit the button widget belongs to.

subscribersCount

The number of subscribers to the subreddit.

subscribersText

The text displayed next to the subscriber count. For example, “users subscribed”.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Widget instance.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Image

class praw.models.Image(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Class to represent an image that’s part of a ImageWidget.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

height

Image height.

linkUrl

A link that can be visited by clicking the image.

url

The URL of the (Reddit-hosted) image.

width

Image width.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

ImageData

class praw.models.ImageData(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Class for image data that’s part of a CustomWidget.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

height

The image height.

name

The image name.

url

The URL of the image on Reddit’s servers.

width

The image width.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

ImageWidget

class praw.models.ImageWidget(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent an image widget.

Find an existing one:

image_widget = None
widgets = reddit.subreddit("test").widgets
for widget in widgets.sidebar:
    if isinstance(widget, praw.models.ImageWidget):
        image_widget = widget
        break

for image in image_widget:
    print(image.url)

Create one:

widgets = reddit.subreddit("test").widgets
image_paths = ["/path/to/image1.jpg", "/path/to/image2.png"]
image_data = [
    {
        "width": 600,
        "height": 450,
        "linkUrl": "",
        "url": widgets.mod.upload_image(img_path),
    }
    for img_path in image_paths
]
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
image_widget = widgets.mod.add_image_widget(
    short_name="My cool pictures", data=image_data, styles=styles
)

For more information on creation, see add_image_widget().

Update one:

new_styles = {"backgroundColor": "#FFFFFF", "headerColor": "#FF9900"}
image_widget = image_widget.mod.update(shortName="My fav images", styles=new_styles)

Delete one:

image_widget.mod.delete()

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

data

A list of the Images in this widget. Can be iterated over by iterating over the ImageWidget (e.g., for img in image_widget).

id

The widget ID.

kind

The widget kind (always "image").

shortName

The short name of the widget.

styles

A dict with the keys "backgroundColor" and "headerColor".

subreddit

The Subreddit the button widget belongs to.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Widget instance.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

ModeratorsWidget

class praw.models.ModeratorsWidget(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent a moderators widget.

widgets = reddit.subreddit("test").widgets
print(widgets.moderators_widget)

Update one:

new_styles = {"backgroundColor": "#FFFFFF", "headerColor": "#FF9900"}
widgets.moderators_widget.mod.update(styles=new_styles)

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

id

The widget ID.

kind

The widget kind (always "moderators").

mods

A list of the Redditors that moderate the subreddit. Can be iterated over by iterating over the ModeratorsWidget (e.g., for mod in widgets.moderators_widget).

styles

A dict with the keys "backgroundColor" and "headerColor".

subreddit

The Subreddit the button widget belongs to.

totalMods

The total number of moderators in the subreddit.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a ModeratorsWidget instance.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

PostFlairWidget

class praw.models.PostFlairWidget(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent a post flair widget.

Find an existing one:

post_flair_widget = None
widgets = reddit.subreddit("test").widgets
for widget in widgets.sidebar:
    if isinstance(widget, praw.models.PostFlairWidget):
        post_flair_widget = widget
        break

for flair in post_flair_widget:
    print(flair)
    print(post_flair_widget.templates[flair])

Create one:

subreddit = reddit.subreddit("test")
widgets = subreddit.widgets
flairs = [f["id"] for f in subreddit.flair.link_templates]
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
post_flair = widgets.mod.add_post_flair_widget(
    short_name="Some flairs", display="list", order=flairs, styles=styles
)

For more information on creation, see add_post_flair_widget().

Update one:

new_styles = {"backgroundColor": "#FFFFFF", "headerColor": "#FF9900"}
post_flair = post_flair.mod.update(shortName="My fav flairs", styles=new_styles)

Delete one:

post_flair.mod.delete()

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

display

The display style of the widget, either "cloud" or "list".

id

The widget ID.

kind

The widget kind (always "post-flair").

order

A list of the flair IDs in this widget. Can be iterated over by iterating over the PostFlairWidget (e.g., for flair_id in post_flair).

shortName

The short name of the widget.

styles

A dict with the keys "backgroundColor" and "headerColor".

subreddit

The Subreddit the button widget belongs to.

templates

A dict that maps flair IDs to dictionaries that describe flairs.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Widget instance.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

RulesWidget

class praw.models.RulesWidget(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent a rules widget.

widgets = reddit.subreddit("test").widgets
rules_widget = None
for widget in widgets.sidebar:
    if isinstance(widget, praw.models.RulesWidget):
        rules_widget = widget
        break
from pprint import pprint

pprint(rules_widget.data)

Update one:

new_styles = {"backgroundColor": "#FFFFFF", "headerColor": "#FF9900"}
rules_widget.mod.update(display="compact", shortName="The LAWS", styles=new_styles)

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

data

A list of the subreddit rules. Can be iterated over by iterating over the RulesWidget (e.g., for rule in rules_widget).

display

The display style of the widget, either "full" or "compact".

id

The widget ID.

kind

The widget kind (always "subreddit-rules").

shortName

The short name of the widget.

styles

A dict with the keys "backgroundColor" and "headerColor".

subreddit

The Subreddit the button widget belongs to.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a RulesWidget instance.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Styles

class praw.models.Styles(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Class to represent the style information of a widget.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

backgroundColor

The background color of a widget, given as a hexadecimal (0x######).

headerColor

The header color of a widget, given as a hexadecimal (0x######).

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

TextArea

class praw.models.TextArea(reddit: praw.Reddit, _data: Dict[str, Any])

Class to represent a text area widget.

Find a text area in a subreddit:

widgets = reddit.subreddit("test").widgets
text_area = None
for widget in widgets.sidebar:
    if isinstance(widget, praw.models.TextArea):
        text_area = widget
        break
print(text_area.text)

Create one:

widgets = reddit.subreddit("test").widgets
styles = {"backgroundColor": "#FFFF66", "headerColor": "#3333EE"}
text_area = widgets.mod.add_text_area(
    short_name="My cool title", text="*Hello* **world**!", styles=styles
)

For more information on creation, see add_text_area().

Update one:

new_styles = {"backgroundColor": "#FFFFFF", "headerColor": "#FF9900"}
text_area = text_area.mod.update(shortName="My fav text", styles=new_styles)

Delete one:

text_area.mod.delete()

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

id

The widget ID.

kind

The widget kind (always "textarea").

shortName

The short name of the widget.

styles

A dict with the keys "backgroundColor" and "headerColor".

subreddit

The Subreddit the button widget belongs to.

text

The widget’s text, as Markdown.

textHtml

The widget’s text, as HTML.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Widget instance.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Widget

class praw.models.Widget(reddit: praw.Reddit, _data: Dict[str, Any])

Base class to represent a Widget.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Widget instance.

mod() praw.models.WidgetModeration

Get an instance of WidgetModeration for this widget.

Note

Using any of the methods of WidgetModeration will likely make the data in the SubredditWidgets that this widget belongs to outdated. To remedy this, call refresh().

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Auth

class praw.models.Auth(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Auth provides an interface to Reddit’s authorization.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

authorize(code: str) Optional[str]

Complete the web authorization flow and return the refresh token.

Parameters

code – The code obtained through the request to the redirect uri.

Returns

The obtained refresh token, if available, otherwise None.

The session’s active authorization will be updated upon success.

implicit(*, access_token: str, expires_in: int, scope: str) None

Set the active authorization to be an implicit authorization.

Parameters
  • access_token – The access_token obtained from Reddit’s callback.

  • expires_in – The number of seconds the access_token is valid for. The origin of this value was returned from Reddit’s callback. You may need to subtract an offset before passing in this number to account for a delay between when Reddit prepared the response, and when you make this function call.

  • scope – A space-delimited string of Reddit OAuth2 scope names as returned from Reddit’s callback.

Raises

InvalidImplicitAuth if Reddit was initialized for a non-installed application type.

property limits: Dict[str, Optional[Union[str, int]]]

Return a dictionary containing the rate limit info.

The keys are:

Remaining

The number of requests remaining to be made in the current rate limit window.

Reset_timestamp

A unix timestamp providing an upper bound on when the rate limit counters will reset.

Used

The number of requests made in the current rate limit window.

All values are initially None as these values are set in response to issued requests.

The reset_timestamp value is an upper bound as the real timestamp is computed on Reddit’s end in preparation for sending the response. This value may change slightly within a given window due to slight changes in response times and rounding.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

scopes() Set[str]

Return a set of scopes included in the current authorization.

For read-only authorizations this should return {"*"}.

url(*, duration: str = 'permanent', implicit: bool = False, scopes: List[str], state: str) str

Return the URL used out-of-band to grant access to your application.

Parameters
  • duration – Either "permanent" or "temporary" (default: "permanent"). "temporary" authorizations generate access tokens that last only 1 hour. "permanent" authorizations additionally generate a refresh token that expires 1 year after the last use and can be used indefinitely to generate new hour-long access tokens. This value is ignored when implicit=True.

  • implicit – For installed applications, this value can be set to use the implicit, rather than the code flow. When True, the duration argument has no effect as only temporary tokens can be retrieved.

  • scopes – A list of OAuth scopes to request authorization for.

  • state – A string that will be reflected in the callback to redirect_uri. This value should be temporarily unique to the client for whom the URL was generated for.

BaseList

class praw.models.list.base.BaseList(reddit: praw.Reddit, _data: Dict[str, Any])

An abstract class to coerce a list into a PRAWBase.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a BaseList instance.

Parameters

reddit – An instance of Reddit.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

CommentForest

class praw.models.comment_forest.CommentForest(submission: praw.models.Submission, comments: Optional[List[praw.models.Comment]] = None)

A forest of comments starts with multiple top-level comments.

Each of these comments can be a tree of replies.

__getitem__(index: int)

Return the comment at position index in the list.

This method is to be used like an array access, such as:

first_comment = submission.comments[0]

Alternatively, the presence of this method enables one to iterate over all top level comments, like so:

for comment in submission.comments:
    print(comment.body)
__init__(submission: praw.models.Submission, comments: Optional[List[praw.models.Comment]] = None)

Initialize a CommentForest instance.

Parameters
  • submission – An instance of Submission that is the parent of the comments.

  • comments – Initialize the forest with a list of comments (default: None).

__len__() int

Return the number of top-level comments in the forest.

list() List[Union[praw.models.Comment, praw.models.MoreComments]]

Return a flattened list of all comments.

This list may contain MoreComments instances if replace_more() was not called first.

replace_more(*, limit: int = 32, threshold: int = 0) List[praw.models.MoreComments]

Update the comment forest by resolving instances of MoreComments.

Parameters
  • limit – The maximum number of MoreComments instances to replace. Each replacement requires 1 API request. Set to None to have no limit, or to 0 to remove all MoreComments instances without additional requests (default: 32).

  • threshold – The minimum number of children comments a MoreComments instance must have in order to be replaced. MoreComments instances that represent “continue this thread” links unfortunately appear to have 0 children (default: 0).

Returns

A list of MoreComments instances that were not replaced.

Raises

prawcore.TooManyRequests when used concurrently.

For example, to replace up to 32 MoreComments instances of a submission try:

submission = reddit.submission("3hahrw")
submission.comments.replace_more()

Alternatively, to replace MoreComments instances within the replies of a single comment try:

comment = reddit.comment("d8r4im1")
comment.refresh()
comment.replies.replace_more()

Note

This method can take a long time as each replacement will discover at most 100 new Comment instances. As a result, consider looping and handling exceptions until the method returns successfully. For example:

while True:
    try:
        submission.comments.replace_more()
        break
    except PossibleExceptions:
        print("Handling replace_more exception")
        sleep(1)

Warning

If this method is called, and the comments are refreshed, calling this method again will result in a DuplicateReplaceException.

CommentHelper

class praw.models.listing.mixins.subreddit.CommentHelper(subreddit: praw.models.Subreddit)

Provide a set of functions to interact with a Subreddit’s comments.

__call__(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Comment]

Return a ListingGenerator for the Subreddit’s comments.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method should be used in a way similar to the example below:

for comment in reddit.subreddit("test").comments(limit=25):
    print(comment.author)
__init__(subreddit: praw.models.Subreddit)

Initialize a CommentHelper instance.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Config

class praw.config.Config(site_name: str, config_interpolation: Optional[str] = None, **settings: str)

A class containing the configuration for a Reddit site.

__init__(site_name: str, config_interpolation: Optional[str] = None, **settings: str)

Initialize a Config instance.

property short_url: str

Return the short url.

Raises

ClientException if it is not set.

DomainListing

class praw.models.DomainListing(reddit: praw.Reddit, domain: str)

Provide a set of functions to interact with domain listings.

__init__(reddit: praw.Reddit, domain: str)

Initialize a DomainListing instance.

Parameters
  • reddit – An instance of Reddit.

  • domain – The domain for which to obtain listings.

controversial(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for controversial items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").controversial(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").controversial(
    time_filter="day"
)
reddit.redditor("spez").controversial(time_filter="month")
reddit.redditor("spez").comments.controversial(time_filter="year")
reddit.redditor("spez").submissions.controversial(time_filter="all")
reddit.subreddit("all").controversial(time_filter="hour")
hot(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for hot items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").hot()
reddit.multireddit(redditor="samuraisam", name="programming").hot()
reddit.redditor("spez").hot()
reddit.redditor("spez").comments.hot()
reddit.redditor("spez").submissions.hot()
reddit.subreddit("all").hot()
new(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for new items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").new()
reddit.multireddit(redditor="samuraisam", name="programming").new()
reddit.redditor("spez").new()
reddit.redditor("spez").comments.new()
reddit.redditor("spez").submissions.new()
reddit.subreddit("all").new()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

random_rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for random rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get random rising submissions for r/test:

for submission in reddit.subreddit("test").random_rising():
    print(submission.title)
rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get rising submissions for r/test:

for submission in reddit.subreddit("test").rising():
    print(submission.title)
top(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for top items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").top(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").top(time_filter="day")
reddit.redditor("spez").top(time_filter="month")
reddit.redditor("spez").comments.top(time_filter="year")
reddit.redditor("spez").submissions.top(time_filter="all")
reddit.subreddit("all").top(time_filter="hour")

DraftList

class praw.models.DraftList(reddit: praw.Reddit, _data: Dict[str, Any])

A list of Draft objects. Works just like a regular list.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a BaseList instance.

Parameters

reddit – An instance of Reddit.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Emoji

class praw.models.reddit.emoji.Emoji(reddit: praw.Reddit, subreddit: praw.models.Subreddit, name: str, _data: Optional[Dict[str, Any]] = None)

An individual Emoji object.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

mod_flair_only

Whether the emoji is restricted for mod use only.

name

The name of the emoji.

post_flair_allowed

Whether the emoji may appear in post flair.

url

The URL of the emoji image.

user_flair_allowed

Whether the emoji may appear in user flair.

__init__(reddit: praw.Reddit, subreddit: praw.models.Subreddit, name: str, _data: Optional[Dict[str, Any]] = None)

Initialize an Emoji instance.

delete()

Delete an emoji from this subreddit by Emoji.

To delete "emoji" as an emoji on r/test try:

reddit.subreddit("test").emoji["emoji"].delete()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

update(*, mod_flair_only: Optional[bool] = None, post_flair_allowed: Optional[bool] = None, user_flair_allowed: Optional[bool] = None)

Update the permissions of an emoji in this subreddit.

Parameters
  • mod_flair_only – Indicate whether the emoji is restricted to mod use only. Respects pre-existing settings if not provided.

  • post_flair_allowed – Indicate whether the emoji may appear in post flair. Respects pre-existing settings if not provided.

  • user_flair_allowed – Indicate whether the emoji may appear in user flair. Respects pre-existing settings if not provided.

Note

In order to retain pre-existing values for those that are not explicitly passed, a network request is issued. To avoid that network request, explicitly provide all values.

To restrict the emoji "emoji" in r/test to mod use only, try:

reddit.subreddit("test").emoji["emoji"].update(mod_flair_only=True)

FullnameMixin

class praw.models.reddit.mixins.FullnameMixin

Interface for classes that have a fullname.

__init__()
property fullname: str

Return the object’s fullname.

A fullname is an object’s kind mapping like t3 followed by an underscore and the object’s base36 ID, e.g., t1_c5s96e0.

InboxableMixin

class praw.models.reddit.mixins.InboxableMixin

Interface for RedditBase subclasses that originate from the inbox.

__init__()
block()

Block the user who sent the item.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.block()

# or, identically:

comment.author.block()
collapse()

Mark the item as collapsed.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox()

# select first inbox item and collapse it message = next(inbox)
message.collapse()

See also

uncollapse()

mark_read()

Mark a single inbox item as read.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox.unread()

for message in inbox:
    # process unread messages
    ...

See also

mark_unread()

To mark the whole inbox as read with a single network request, use Inbox.mark_all_read()

mark_unread()

Mark the item as unread.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox(limit=10)

for message in inbox:
    # process messages
    ...

See also

mark_read()

unblock_subreddit()

Unblock a subreddit.

Note

This method pertains only to objects which were retrieved via the inbox.

For example, to unblock all blocked subreddits that you can find by going through your inbox:

from praw.models import SubredditMessage

subs = set()
for item in reddit.inbox.messages(limit=None):
    if isinstance(item, SubredditMessage):
        if (
            item.subject == "[message from blocked subreddit]"
            and str(item.subreddit) not in subs
        ):
            item.unblock_subreddit()
            subs.add(str(item.subreddit))
uncollapse()

Mark the item as uncollapsed.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox()

# select first inbox item and uncollapse it
message = next(inbox)
message.uncollapse()

See also

collapse()

ListingGenerator

class praw.models.ListingGenerator(reddit: praw.Reddit, url: str, limit: int = 100, params: Optional[Dict[str, Union[str, int]]] = None)

Instances of this class generate RedditBase instances.

Warning

This class should not be directly utilized. Instead, you will find a number of methods that return instances of the class here.

__init__(reddit: praw.Reddit, url: str, limit: int = 100, params: Optional[Dict[str, Union[str, int]]] = None)

Initialize a ListingGenerator instance.

Parameters
  • reddit – An instance of Reddit.

  • url – A URL returning a Reddit listing.

  • limit – The number of content entries to fetch. If limit is None, then fetch as many entries as possible. Most of Reddit’s listings contain a maximum of 1000 items, and are returned 100 at a time. This class will automatically issue all necessary requests (default: 100).

  • params – A dictionary containing additional query string parameters to send with the request.

__iter__() Iterator[Any]

Permit ListingGenerator to operate as an iterator.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

ModAction

class praw.models.ModAction(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Represent a moderator action.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

property mod: praw.models.Redditor

Return the Redditor who the action was issued by.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

ModeratedList

class praw.models.ModeratedList(reddit: praw.Reddit, _data: Dict[str, Any])

A list of moderated Subreddit objects. Works just like a regular list.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a BaseList instance.

Parameters

reddit – An instance of Reddit.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Modmail

class praw.models.reddit.subreddit.Modmail(subreddit: praw.models.Subreddit)

Provides modmail functions for a Subreddit.

For example, to send a new modmail from r/test to u/spez with the subject "test" along with a message body of "hello":

reddit.subreddit("test").modmail.create(subject="test", body="hello", recipient="spez")
__call__(id: Optional[str] = None, mark_read: bool = False)

Return an individual conversation.

Parameters
  • id – A reddit base36 conversation ID, e.g., "2gmz".

  • mark_read – If True, conversation is marked as read (default: False).

For example:

reddit.subreddit("test").modmail("2gmz", mark_read=True)

To print all messages from a conversation as Markdown source:

conversation = reddit.subreddit("test").modmail("2gmz", mark_read=True)
for message in conversation.messages:
    print(message.body_markdown)

ModmailConversation.user is a special instance of Redditor with extra attributes describing the non-moderator user’s recent posts, comments, and modmail messages within the subreddit, as well as information on active bans and mutes. This attribute does not exist on internal moderator discussions.

For example, to print the user’s ban status:

conversation = reddit.subreddit("test").modmail("2gmz", mark_read=True)
print(conversation.user.ban_status)

To print a list of recent submissions by the user:

conversation = reddit.subreddit("test").modmail("2gmz", mark_read=True)
print(conversation.user.recent_posts)
__init__(subreddit: praw.models.Subreddit)

Initialize a Modmail instance.

bulk_read(*, other_subreddits: Optional[List[Union[str, praw.models.Subreddit]]] = None, state: Optional[str] = None) List[ModmailConversation]

Mark conversations for subreddit(s) as read.

Note

Due to server-side restrictions, r/all is not a valid subreddit for this method. Instead, use subreddits() to get a list of subreddits using the new modmail.

Parameters
  • other_subreddits – A list of Subreddit instances for which to mark conversations (default: None).

  • state – Can be one of: "all", "archived", or "highlighted", "inprogress", "join_requests", "mod", "new", "notifications", or "appeals" (default: "all"). "all" does not include internal, archived, or appeals conversations.

Returns

A list of ModmailConversation instances that were marked read.

For example, to mark all notifications for a subreddit as read:

subreddit = reddit.subreddit("test")
subreddit.modmail.bulk_read(state="notifications")
conversations(*, after: Optional[str] = None, other_subreddits: Optional[List[praw.models.Subreddit]] = None, sort: Optional[str] = None, state: Optional[str] = None, **generator_kwargs) Iterator[ModmailConversation]

Generate ModmailConversation objects for subreddit(s).

Parameters
  • after

    A base36 modmail conversation id. When provided, the listing begins after this conversation (default: None).

    Deprecated since version 7.4.0: This parameter is deprecated and will be removed in PRAW 8.0. This method will automatically fetch the next batch. Please pass it in the params argument like so:

    for convo in subreddit.modmail.conversations(params={"after": "qovbn"}):
        # process conversation
        ...
    

  • other_subreddits – A list of Subreddit instances for which to fetch conversations (default: None).

  • sort – Can be one of: "mod", "recent", "unread", or "user" (default: "recent").

  • state – Can be one of: "all", "archived", "highlighted", "inprogress", "join_requests", "mod", "new", "notifications", or "appeals" (default: "all"). "all" does not include internal, archived, or appeals conversations.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example:

conversations = reddit.subreddit("all").modmail.conversations(state="mod")
create(*, author_hidden: bool = False, body: str, recipient: Union[str, praw.models.Redditor], subject: str) ModmailConversation

Create a new ModmailConversation.

Parameters
  • author_hidden – When True, author is hidden from non-moderators (default: False).

  • body – The message body. Cannot be empty.

  • recipient – The recipient; a username or an instance of Redditor.

  • subject – The message subject. Cannot be empty.

Returns

A ModmailConversation object for the newly created conversation.

subreddit = reddit.subreddit("test")
redditor = reddit.redditor("bboe")
subreddit.modmail.create(subject="Subject", body="Body", recipient=redditor)
subreddits() Generator[praw.models.Subreddit, None, None]

Yield subreddits using the new modmail that the user moderates.

For example:

subreddits = reddit.subreddit("all").modmail.subreddits()
unread_count() Dict[str, int]

Return unread conversation count by conversation state.

At time of writing, possible states are: "archived", "highlighted", "inprogress", "join_requests", "mod", "new", "notifications", or "appeals".

Returns

A dict mapping conversation states to unread counts.

For example, to print the count of unread moderator discussions:

subreddit = reddit.subreddit("test")
unread_counts = subreddit.modmail.unread_count()
print(unread_counts["mod"])

ModmailMessage

class praw.models.ModmailMessage(reddit: praw.Reddit, _data: Optional[Dict[str, Any]], _extra_attribute_to_check: Optional[str] = None, _fetched: bool = False, _str_field: bool = True)

A class for modmail messages.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]], _extra_attribute_to_check: Optional[str] = None, _fetched: bool = False, _str_field: bool = True)

Initialize a RedditBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

PollData

class praw.models.reddit.poll.PollData(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Class to represent poll data on a poll submission.

If submission is a poll Submission, access the poll data like so:

poll_data = submission.poll_data
print(f"There are {poll_data.total_vote_count} votes total.")
print("The options are:")
for option in poll_data.options:
    print(f"{option} ({option.vote_count} votes)")
print(f"I voted for {poll_data.user_selection}.")

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

options

A list of PollOption of the poll.

total_vote_count

The total number of votes cast in the poll.

user_selection

The poll option selected by the authenticated user (possibly None).

voting_end_timestamp

Time the poll voting closes, represented in Unix Time.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

option(option_id: str) PollOption

Get the option with the specified ID.

Parameters

option_id – The ID of a poll option, as a str.

Returns

The specified PollOption.

Raises

KeyError if no option exists with the specified ID.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

user_selection() Optional[PollOption]

Get the user’s selection in this poll, if any.

Returns

The user’s selection as a PollOption, or None if there is no choice.

PollOption

class praw.models.reddit.poll.PollOption(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Class to represent one option of a poll.

If submission is a poll Submission, access the poll’s options like so:

poll_data = submission.poll_data

# By index -- print the first option
print(poll_data.options[0])

# By ID -- print the option with ID "576797"
print(poll_data.option("576797"))

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

id

ID of the poll option.

text

The text of the poll option.

vote_count

The number of votes the poll option has received.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

PartialRedditor

class praw.models.redditors.PartialRedditor

A namespace object that provides a subset of Redditor attributes.

__init__(*args, **kwargs)

PRAWBase

class praw.models.base.PRAWBase(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Superclass for all models in PRAW.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Preferences

class praw.models.Preferences(reddit: praw.Reddit)

A class for Reddit preferences.

The Preferences class provides access to the Reddit preferences of the currently authenticated user.

__call__() Dict[str, Union[str, int, bool]]

Return the preference settings of the authenticated user as a dict.

This method is intended to be accessed as reddit.user.preferences() like so:

preferences = reddit.user.preferences()
print(preferences["show_link_flair"])

See https://www.reddit.com/dev/api#GET_api_v1_me_prefs for the list of possible values.

__init__(reddit: praw.Reddit)

Initialize a Preferences instance.

Parameters

reddit – The Reddit instance.

update(**preferences: Union[bool, int, str])

Modify the specified settings.

Parameters
  • accept_pms – Who can send you personal messages (one of "everyone" or "whitelisted").

  • activity_relevant_ads – Allow Reddit to use your activity on Reddit to show you more relevant advertisements.

  • allow_clicktracking – Allow Reddit to log my outbound clicks for personalization.

  • beta – I would like to beta test features for Reddit.

  • clickgadget – Show me links I’ve recently viewed.

  • collapse_read_messages – Collapse messages after I’ve read them.

  • compress – Compress the link display.

  • creddit_autorenew – Use a creddit to automatically renew my gold if it expires.

  • default_comment_sort – Default comment sort (one of "confidence", "top", "new", "controversial", "old", "random", "qa", or "live").

  • domain_details (bool) – Show additional details in the domain text when available, such as the source subreddit or the content author’s url/name.

  • email_chat_request (bool) – Send chat requests as emails.

  • email_comment_reply (bool) – Send comment replies as emails.

  • email_digests (bool) – Send email digests.

  • email_messages (bool) – Send messages as emails.

  • email_post_reply (bool) – Send post replies as emails.

  • email_private_message (bool) – Send private messages as emails.

  • email_unsubscribe_all (bool) – Unsubscribe from all emails.

  • email_upvote_comment (bool) – Send comment upvote updates as emails.

  • email_upvote_post (bool) – Send post upvote updates as emails.

  • email_user_new_follower (bool) – Send new follower alerts as emails.

  • email_username_mention (bool) – Send username mentions as emails.

  • enable_default_themes (bool) – Use Reddit theme.

  • feed_recommendations_enabled (bool) – Enable feed recommendations.

  • geopopular (str) – Location (one of "GLOBAL", "AR", "AU", "BG", "CA", "CL", "CO", "CZ", "FI", "GB", "GR", "HR", "HU", "IE", "IN", "IS", "JP", "MX", "MY", "NZ", "PH", "PL", "PR", "PT", "RO", "RS", "SE", "SG", "TH", "TR", "TW", "US", "US_AK", "US_AL", "US_AR", "US_AZ", "US_CA", "US_CO", "US_CT", "US_DC", "US_DE", "US_FL", "US_GA", "US_HI", "US_IA", "US_ID", "US_IL", "US_IN", "US_KS", "US_KY", "US_LA", "US_MA", "US_MD", "US_ME", "US_MI", "US_MN", "US_MO", "US_MS", "US_MT", "US_NC", "US_ND", "US_NE", "US_NH", "US_NJ", "US_NM", "US_NV", "US_NY", "US_OH", "US_OK", "US_OR", "US_PA", "US_RI", "US_SC", "US_SD", "US_TN", "US_TX", "US_UT", "US_VA", "US_VT", "US_WA", "US_WI", "US_WV", or "US_WY").

  • hide_ads (bool) – Hide ads.

  • hide_downs (bool) – Don’t show me submissions after I’ve downvoted them, except my own.

  • hide_from_robots (bool) – Don’t allow search engines to index my user profile.

  • hide_ups (bool) – Don’t show me submissions after I’ve upvoted them, except my own.

  • highlight_controversial (bool) – Show a dagger on comments voted controversial.

  • highlight_new_comments (bool) – Highlight new comments.

  • ignore_suggested_sort (bool) – Ignore suggested sorts.

  • in_redesign_beta (bool) – In redesign beta.

  • label_nsfw (bool) – Label posts that are not safe for work.

  • lang (str) – Interface language (IETF language tag, underscore separated).

  • legacy_search (bool) – Show legacy search page.

  • live_orangereds (bool) – Send message notifications in my browser.

  • mark_messages_read (bool) – Mark messages as read when I open my inbox.

  • media (str) – Thumbnail preference (one of "on", "off", or "subreddit").

  • media_preview (str) – Media preview preference (one of "on", "off", or "subreddit").

  • min_comment_score (int) – Don’t show me comments with a score less than this number (between -100 and 100).

  • min_link_score (int) – Don’t show me submissions with a score less than this number (between -100 and 100).

  • monitor_mentions (bool) – Notify me when people say my username.

  • newwindow (bool) – Open links in a new window.

  • nightmode (bool) – Enable night mode.

  • no_profanity (bool) – Don’t show thumbnails or media previews for anything labeled NSFW.

  • num_comments (int) – Display this many comments by default (between 1 and 500).

  • numsites (int) – Number of links to display at once (between 1 and 100).

  • organic (bool) – Show the spotlight box on the home feed.

  • other_theme (str) – Subreddit theme to use (subreddit name).

  • over_18 (bool) – I am over eighteen years old and willing to view adult content.

  • private_feeds (bool) – Enable private RSS feeds.

  • profile_opt_out (bool) – View user profiles on desktop using legacy mode.

  • public_votes (bool) – Make my votes public.

  • research (bool) – Allow my data to be used for research purposes.

  • search_include_over_18 (bool) – Include not safe for work (NSFW) search results in searches.

  • send_crosspost_messages (bool) – Send crosspost messages.

  • send_welcome_messages (bool) – Send welcome messages.

  • show_flair (bool) – Show user flair.

  • show_gold_expiration (bool) – Show how much gold you have remaining on your userpage.

  • show_link_flair (bool) – Show link flair.

  • show_location_based_recommendations (bool) – Show location based recommendations.

  • show_presence (bool) – Show presence.

  • show_promote (bool) – Show promote.

  • show_stylesheets (bool) – Allow subreddits to show me custom themes.

  • show_trending (bool) – Show trending subreddits on the home feed.

  • show_twitter (bool) – Show a link to your Twitter account on your profile.

  • store_visits (bool) – Store visits.

  • theme_selector (bool) – Theme selector (subreddit name).

  • third_party_data_personalized_ads (bool) – Allow Reddit to use data provided by third-parties to show you more relevant advertisements on Reddit.

  • third_party_personalized_ads (bool) – Allow personalization of advertisements.

  • third_party_site_data_personalized_ads (bool) – Allow personalization of advertisements using third-party website data.

  • third_party_site_data_personalized_content (bool) – Allow personalization of content using third-party website data.

  • threaded_messages (bool) – Show message conversations in the inbox.

  • threaded_modmail (bool) – Enable threaded modmail display.

  • top_karma_subreddits (bool) – Top karma subreddits.

  • use_global_defaults (bool) – Use global defaults.

  • video_autoplay (bool) – Autoplay Reddit videos on the desktop comments page.

Additional keyword arguments can be provided to handle new settings as Reddit introduces them.

See https://www.reddit.com/dev/api#PATCH_api_v1_me_prefs for the most up-to-date list of possible parameters.

This is intended to be used like so:

reddit.user.preferences.update(show_link_flair=True)

This method returns the new state of the preferences as a dict, which can be used to check whether a change went through.

original_preferences = reddit.user.preferences()
new_preferences = reddit.user.preferences.update(invalid_param=123)
print(original_preferences == new_preferences)  # True, no change

Warning

Passing an unknown parameter name or an illegal value (such as an int when a boolean is expected) does not result in an error from the Reddit API. As a consequence, any invalid input will fail silently. To verify that changes have been made, use the return value of this method, which is a dict of the preferences after the update action has been performed.

Some preferences have names that are not valid keyword arguments in Python. To update these, construct a dict and use ** to unpack it as keyword arguments:

reddit.user.preferences.update(**{"third_party_data_personalized_ads": False})

RedditBase

class praw.models.reddit.base.RedditBase(reddit: praw.Reddit, _data: Optional[Dict[str, Any]], _extra_attribute_to_check: Optional[str] = None, _fetched: bool = False, _str_field: bool = True)

Base class that represents actual Reddit objects.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]], _extra_attribute_to_check: Optional[str] = None, _fetched: bool = False, _str_field: bool = True)

Initialize a RedditBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

RedditorList

class praw.models.RedditorList(reddit: praw.Reddit, _data: Dict[str, Any])

A list of Redditor objects. Works just like a regular list.

__contains__(item: Any) bool

Test if item exists in the list.

__getitem__(index: int) Any

Return the item at position index in the list.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a BaseList instance.

Parameters

reddit – An instance of Reddit.

__iter__() Iterator[Any]

Return an iterator to the list.

__len__() int

Return the number of items in the list.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

RedditorStream

class praw.models.reddit.redditor.RedditorStream(redditor: praw.models.Redditor)

Provides submission and comment streams.

__init__(redditor: praw.models.Redditor)

Initialize a RedditorStream instance.

Parameters

redditor – The redditor associated with the streams.

comments(**stream_options: Union[str, int, Dict[str, str]]) Generator[praw.models.Comment, None, None]

Yield new comments as they become available.

Comments are yielded oldest first. Up to 100 historical comments will initially be returned.

Keyword arguments are passed to stream_generator().

For example, to retrieve all new comments made by redditor u/spez, try:

for comment in reddit.redditor("spez").stream.comments():
    print(comment)
submissions(**stream_options: Union[str, int, Dict[str, str]]) Generator[praw.models.Submission, None, None]

Yield new submissions as they become available.

Submissions are yielded oldest first. Up to 100 historical submissions will initially be returned.

Keyword arguments are passed to stream_generator().

For example, to retrieve all new submissions made by redditor u/spez, try:

for submission in reddit.redditor("spez").stream.submissions():
    print(submission)

RemovalReason

class praw.models.reddit.removal_reasons.RemovalReason(reddit: praw.Reddit, subreddit: praw.models.Subreddit, id: Optional[str] = None, reason_id: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

An individual Removal Reason object.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

id

The ID of the removal reason.

message

The message of the removal reason.

title

The title of the removal reason.

__init__(reddit: praw.Reddit, subreddit: praw.models.Subreddit, id: Optional[str] = None, reason_id: Optional[str] = None, _data: Optional[Dict[str, Any]] = None)

Initialize a RemovalReason instance.

Parameters
  • reddit – An instance of Reddit.

  • subreddit – An instance of Subreddit.

  • id – The ID of the removal reason.

  • reason_id – The original name of the id parameter. Used for backwards compatibility. This parameter should not be used.

delete()

Delete a removal reason from this subreddit.

To delete "141vv5c16py7d" from r/test try:

reddit.subreddit("test").mod.removal_reasons["141vv5c16py7d"].delete()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

update(*, message: Optional[str] = None, title: Optional[str] = None)

Update the removal reason from this subreddit.

Note

Existing values will be used for any unspecified arguments.

Parameters
  • message – The removal reason’s new message.

  • title – The removal reason’s new title.

To update "141vv5c16py7d" from r/test try:

reddit.subreddit("test").mod.removal_reasons["141vv5c16py7d"].update(
    title="New title", message="New message"
)

Rule

class praw.models.Rule(reddit: praw.Reddit, subreddit: Optional[praw.models.Subreddit] = None, short_name: Optional[str] = None, _data: Optional[Dict[str, str]] = None)

An individual Rule object.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

created_utc

Time the rule was created, represented in Unix Time.

description

The description of the rule, if provided, otherwise a blank string.

kind

The kind of rule. Can be "link", comment", or "all".

priority

Represents where the rule is ranked. For example, the first rule is at priority 0. Serves as an index number on the list of rules.

short_name

The name of the rule.

violation_reason

The reason that is displayed on the report menu for the rule.

__init__(reddit: praw.Reddit, subreddit: Optional[praw.models.Subreddit] = None, short_name: Optional[str] = None, _data: Optional[Dict[str, str]] = None)

Initialize a Rule instance.

mod() praw.models.reddit.rules.RuleModeration

Contain methods used to moderate rules.

To delete "No spam" from r/test try:

reddit.subreddit("test").rules["No spam"].mod.delete()

To update "No spam" from r/test try:

reddit.subreddit("test").removal_reasons["No spam"].mod.update(
    description="Don't do this!", violation_reason="Spam post"
)
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

Stylesheet

class praw.models.Stylesheet(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Represent a stylesheet.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

images

A list of images used by the stylesheet.

stylesheet

The contents of the stylesheet, as CSS.

__init__(reddit: praw.Reddit, _data: Optional[Dict[str, Any]])

Initialize a PRAWBase instance.

Parameters

reddit – An instance of Reddit.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

SubListing

class praw.models.listing.mixins.redditor.SubListing(reddit: praw.Reddit, base_path: str, subpath: str)

Helper class for generating ListingGenerator objects.

__init__(reddit: praw.Reddit, base_path: str, subpath: str)

Initialize a SubListing instance.

Parameters
  • reddit – An instance of Reddit.

  • base_path – The path to the object up to this point.

  • subpath – The additional path to this sublisting.

controversial(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for controversial items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").controversial(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").controversial(
    time_filter="day"
)
reddit.redditor("spez").controversial(time_filter="month")
reddit.redditor("spez").comments.controversial(time_filter="year")
reddit.redditor("spez").submissions.controversial(time_filter="all")
reddit.subreddit("all").controversial(time_filter="hour")
hot(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for hot items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").hot()
reddit.multireddit(redditor="samuraisam", name="programming").hot()
reddit.redditor("spez").hot()
reddit.redditor("spez").comments.hot()
reddit.redditor("spez").submissions.hot()
reddit.subreddit("all").hot()
new(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for new items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").new()
reddit.multireddit(redditor="samuraisam", name="programming").new()
reddit.redditor("spez").new()
reddit.redditor("spez").comments.new()
reddit.redditor("spez").submissions.new()
reddit.subreddit("all").new()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

top(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for top items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").top(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").top(time_filter="day")
reddit.redditor("spez").top(time_filter="month")
reddit.redditor("spez").comments.top(time_filter="year")
reddit.redditor("spez").submissions.top(time_filter="all")
reddit.subreddit("all").top(time_filter="hour")

SubredditMessage

class praw.models.SubredditMessage(reddit: praw.Reddit, _data: Dict[str, Any])

A class for messages to a subreddit.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

author

Provides an instance of Redditor.

body

The body of the message, as Markdown.

body_html

The body of the message, as HTML.

created_utc

Time the message was created, represented in Unix Time.

dest

Provides an instance of Redditor. The recipient of the message.

id

The ID of the message.

name

The full ID of the message, prefixed with t4_.

subject

The subject of the message.

subreddit

If the message was sent from a subreddit, provides an instance of Subreddit.

was_comment

Whether or not the message was a comment reply.

__init__(reddit: praw.Reddit, _data: Dict[str, Any])

Initialize a Message instance.

block()

Block the user who sent the item.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

comment = reddit.comment("dkk4qjd")
comment.block()

# or, identically:

comment.author.block()
collapse()

Mark the item as collapsed.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox()

# select first inbox item and collapse it message = next(inbox)
message.collapse()

See also

uncollapse()

delete()

Delete the message.

Note

Reddit does not return an indication of whether or not the message was successfully deleted.

For example, to delete the most recent message in your inbox:

next(reddit.inbox.all()).delete()
property fullname: str

Return the object’s fullname.

A fullname is an object’s kind mapping like t3 followed by an underscore and the object’s base36 ID, e.g., t1_c5s96e0.

mark_read()

Mark a single inbox item as read.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox.unread()

for message in inbox:
    # process unread messages
    ...

See also

mark_unread()

To mark the whole inbox as read with a single network request, use Inbox.mark_all_read()

mark_unread()

Mark the item as unread.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox(limit=10)

for message in inbox:
    # process messages
    ...

See also

mark_read()

mute()

Mute the sender of this SubredditMessage.

For example, to mute the sender of the first SubredditMessage in the authenticated users’ inbox:

from praw.models import SubredditMessage

msg = next(
    message for message in reddit.inbox.all() if isinstance(message, SubredditMessage)
)
msg.mute()
property parent: Optional[praw.models.Message]

Return the parent of the message if it exists.

classmethod parse(data: Dict[str, Any], reddit: praw.Reddit)

Return an instance of Message or SubredditMessage from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

reply(body: str) Optional[Union[praw.models.Comment, praw.models.Message]]

Reply to the object.

Parameters

body – The Markdown formatted content for a comment.

Returns

A Comment or Message object for the newly created comment or message or None if Reddit doesn’t provide one.

Raises

prawcore.exceptions.Forbidden when attempting to reply to some items, such as locked submissions/comments or non-replyable messages.

A None value can be returned if the target is a comment or submission in a quarantined subreddit and the authenticated user has not opt-ed into viewing the content. When this happens the comment will be successfully created on Reddit and can be retried by drawing the comment from the user’s comment history.

Example usage:

submission = reddit.submission("5or86n")
submission.reply("reply")

comment = reddit.comment("dxolpyc")
comment.reply("reply")
unblock_subreddit()

Unblock a subreddit.

Note

This method pertains only to objects which were retrieved via the inbox.

For example, to unblock all blocked subreddits that you can find by going through your inbox:

from praw.models import SubredditMessage

subs = set()
for item in reddit.inbox.messages(limit=None):
    if isinstance(item, SubredditMessage):
        if (
            item.subject == "[message from blocked subreddit]"
            and str(item.subreddit) not in subs
        ):
            item.unblock_subreddit()
            subs.add(str(item.subreddit))
uncollapse()

Mark the item as uncollapsed.

Note

This method pertains only to objects which were retrieved via the inbox.

Example usage:

inbox = reddit.inbox()

# select first inbox item and uncollapse it
message = next(inbox)
message.uncollapse()

See also

collapse()

unmute()

Unmute the sender of this SubredditMessage.

For example, to unmute the sender of the first SubredditMessage in the authenticated users’ inbox:

from praw.models import SubredditMessage

msg = next(
    message for message in reddit.inbox.all() if isinstance(message, SubredditMessage)
)
msg.unmute()

Token Manager

Token Manager classes.

There should be a 1-to-1 mapping between an instance of a subclass of BaseTokenManager and a Reddit instance.

A few proof of concept token manager classes are provided here, but it is expected that PRAW users will create their own token manager classes suitable for their needs.

Deprecated since version 7.4.0: Tokens managers have been deprecated and will be removed in the near future.

class praw.util.token_manager.BaseTokenManager

An abstract class for all token managers.

__init__()

Initialize a BaseTokenManager instance.

abstract post_refresh_callback(authorizer)

Handle callback that is invoked after a refresh token is used.

Parameters

authorizer – The prawcore.Authorizer instance used containing access_token and refresh_token attributes.

This function will be called after refreshing the access and refresh tokens. This callback can be used for saving the updated refresh_token.

abstract pre_refresh_callback(authorizer)

Handle callback that is invoked before refreshing PRAW’s authorization.

Parameters

authorizer – The prawcore.Authorizer instance used containing access_token and refresh_token attributes.

This callback can be used to inspect and modify the attributes of the prawcore.Authorizer instance, such as setting the refresh_token.

property reddit

Return the Reddit instance bound to the token manager.

class praw.util.token_manager.FileTokenManager(filename)

Provides a single-file based token manager.

It is expected that the file with the initial refresh_token is created prior to use.

Warning

The same file should not be used by more than one instance of this class concurrently. Doing so may result in data corruption. Consider using SQLiteTokenManager if you want more than one instance of PRAW to concurrently manage a specific refresh_token chain.

__init__(filename)

Initialize a FileTokenManager instance.

Parameters

filename – The file the contains the refresh token.

post_refresh_callback(authorizer)

Update the saved copy of the refresh token.

pre_refresh_callback(authorizer)

Load the refresh token from the file.

property reddit

Return the Reddit instance bound to the token manager.

class praw.util.token_manager.SQLiteTokenManager(*, database, key)

Provides a SQLite3 based token manager.

Unlike, FileTokenManager, the initial database need not be created ahead of time, as it’ll automatically be created on first use. However, initial refresh tokens will need to be registered via register() prior to use.

Warning

This class is untested on Windows because we encountered file locking issues in the test environment.

__init__(*, database, key)

Initialize a SQLiteTokenManager instance.

Parameters
  • database – The path to the SQLite database.

  • key – The key used to locate the refresh token. This key can be anything. You might use the client_id if you expect to have unique a refresh token for each client_id, or you might use a redditor’s username if you’re managing multiple users’ authentications.

is_registered()

Return whether or not key already has a refresh_token.

post_refresh_callback(authorizer)

Update the refresh token in the database.

pre_refresh_callback(authorizer)

Load the refresh token from the database.

property reddit

Return the Reddit instance bound to the token manager.

register(refresh_token)

Register the initial refresh token in the database.

Returns

True if refresh_token is saved to the database, otherwise, False if there is already a refresh_token for the associated key.

Trophy

class praw.models.Trophy(reddit: praw.Reddit, _data: Dict[str, Any])

Represent a trophy.

End users should not instantiate this class directly. Redditor.trophies() can be used to get a list of the redditor’s trophies.

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

award_id

The ID of the trophy (sometimes None).

description

The description of the trophy (sometimes None).

icon_40

The URL of a 41x41 px icon for the trophy.

icon_70

The URL of a 71x71 px icon for the trophy.

name

The name of the trophy.

url

A relevant URL (sometimes None).

__str__() str

Return a name of the trophy.

UserSubreddit

class praw.models.UserSubreddit(reddit: praw.Reddit, *args, **kwargs)

A class for User Subreddits.

To obtain an instance of this class execute:

subreddit = reddit.user.me().subreddit

Typical Attributes

Note

This table describes attributes that typically belong to objects of this class. PRAW dynamically provides the attributes that Reddit returns via the API. Since those attributes are subject to change on Reddit’s end, PRAW makes no effort to document any new/removed/changed attributes, other than to instruct you on how to discover what is available. As a result, this table of attributes may not be complete. See Determine Available Attributes of an Object for detailed information.

If you would like to add an attribute to this table, feel free to open a pull request.

Attribute

Description

can_assign_link_flair

Whether users can assign their own link flair.

can_assign_user_flair

Whether users can assign their own user flair.

created_utc

Time the subreddit was created, represented in Unix Time.

description

Subreddit description, in Markdown.

description_html

Subreddit description, in HTML.

display_name

Name of the subreddit.

id

ID of the subreddit.

name

Fullname of the subreddit.

over18

Whether the subreddit is NSFW.

public_description

Description of the subreddit, shown in searches and on the “You must be invited to visit this community” page (if applicable).

spoilers_enabled

Whether the spoiler tag feature is enabled.

subscribers

Count of subscribers. This will be 0 unless unless the authenticated user is a moderator.

user_is_banned

Whether the authenticated user is banned.

user_is_moderator

Whether the authenticated user is a moderator.

user_is_subscriber

Whether the authenticated user is subscribed.

__getitem__(item)

Show deprecation notice for dict method __getitem__.

__init__(reddit: praw.Reddit, *args, **kwargs)

Initialize an UserSubreddit instance.

Parameters

reddit – An instance of Reddit.

Note

This class should not be initialized directly. Instead, obtain an instance via: reddit.user.me().subreddit or reddit.redditor("redditor_name").subreddit.

banned() praw.models.reddit.subreddit.SubredditRelationship

Provide an instance of SubredditRelationship.

For example, to ban a user try:

reddit.subreddit("test").banned.add("spez", ban_reason="...")

To list the banned users along with any notes, try:

for ban in reddit.subreddit("test").banned():
    print(f"{ban}: {ban.note}")
collections() praw.models.reddit.collections.SubredditCollections

Provide an instance of SubredditCollections.

To see the permalinks of all Collections that belong to a subreddit, try:

for collection in reddit.subreddit("test").collections:
    print(collection.permalink)

To get a specific Collection by its UUID or permalink, use one of the following:

collection = reddit.subreddit("test").collections("some_uuid")
collection = reddit.subreddit("test").collections(
    permalink="https://reddit.com/r/SUBREDDIT/collection/some_uuid"
)
comments() CommentHelper

Provide an instance of CommentHelper.

For example, to output the author of the 25 most recent comments of r/test execute:

for comment in reddit.subreddit("test").comments(limit=25):
    print(comment.author)
contributor() praw.models.reddit.subreddit.ContributorRelationship

Provide an instance of ContributorRelationship.

Contributors are also known as approved submitters.

To add a contributor try:

reddit.subreddit("test").contributor.add("spez")
controversial(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for controversial items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").controversial(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").controversial(
    time_filter="day"
)
reddit.redditor("spez").controversial(time_filter="month")
reddit.redditor("spez").comments.controversial(time_filter="year")
reddit.redditor("spez").submissions.controversial(time_filter="all")
reddit.subreddit("all").controversial(time_filter="hour")
emoji() SubredditEmoji

Provide an instance of SubredditEmoji.

This attribute can be used to discover all emoji for a subreddit:

for emoji in reddit.subreddit("test").emoji:
    print(emoji)

A single emoji can be lazily retrieved via:

reddit.subreddit("test").emoji["emoji_name"]

Note

Attempting to access attributes of a nonexistent emoji will result in a ClientException.

filters() praw.models.reddit.subreddit.SubredditFilters

Provide an instance of SubredditFilters.

For example, to add a filter, run:

reddit.subreddit("all").filters.add("test")
flair() praw.models.reddit.subreddit.SubredditFlair

Provide an instance of SubredditFlair.

Use this attribute for interacting with a Subreddit’s flair. For example, to list all the flair for a subreddit which you have the flair moderator permission on try:

for flair in reddit.subreddit("test").flair():
    print(flair)

Flair templates can be interacted with through this attribute via:

for template in reddit.subreddit("test").flair.templates:
    print(template)
property fullname: str

Return the object’s fullname.

A fullname is an object’s kind mapping like t3 followed by an underscore and the object’s base36 ID, e.g., t1_c5s96e0.

gilded(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for gilded items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get gilded items in r/test:

for item in reddit.subreddit("test").gilded():
    print(item.id)
hot(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for hot items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").hot()
reddit.multireddit(redditor="samuraisam", name="programming").hot()
reddit.redditor("spez").hot()
reddit.redditor("spez").comments.hot()
reddit.redditor("spez").submissions.hot()
reddit.subreddit("all").hot()
message(*, from_subreddit: Optional[Union[praw.models.Subreddit, str]] = None, message: str, subject: str)

Send a message to a Redditor or a Subreddit’s moderators (modmail).

Parameters
  • from_subreddit

    A Subreddit instance or string to send the message from. When provided, messages are sent from the subreddit rather than from the authenticated user.

    Note

    The authenticated user must be a moderator of the subreddit and have the mail moderator permission.

  • message – The message content.

  • subject – The subject of the message.

For example, to send a private message to u/spez, try:

reddit.redditor("spez").message(subject="TEST", message="test message from PRAW")

To send a message to u/spez from the moderators of r/test try:

reddit.redditor("spez").message(
    subject="TEST", message="test message from r/test", from_subreddit="test"
)

To send a message to the moderators of r/test, try:

reddit.subreddit("test").message(subject="TEST", message="test PM from PRAW")
mod() praw.models.reddit.user_subreddit.UserSubredditModeration

Provide an instance of UserSubredditModeration.

For example, to update the authenticated user’s display name:

reddit.user.me().subreddit.mod.update(title="New display name")
moderator() praw.models.reddit.subreddit.ModeratorRelationship

Provide an instance of ModeratorRelationship.

For example, to add a moderator try:

reddit.subreddit("test").moderator.add("spez")

To list the moderators along with their permissions try:

for moderator in reddit.subreddit("test").moderator():
    print(f"{moderator}: {moderator.mod_permissions}")
modmail() praw.models.reddit.subreddit.Modmail

Provide an instance of Modmail.

For example, to send a new modmail from r/test to u/spez with the subject "test" along with a message body of "hello":

reddit.subreddit("test").modmail.create(subject="test", body="hello", recipient="spez")
muted() praw.models.reddit.subreddit.SubredditRelationship

Provide an instance of SubredditRelationship.

For example, muted users can be iterated through like so:

for mute in reddit.subreddit("test").muted():
    print(f"{mute}: {mute.note}")
new(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for new items.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").new()
reddit.multireddit(redditor="samuraisam", name="programming").new()
reddit.redditor("spez").new()
reddit.redditor("spez").comments.new()
reddit.redditor("spez").submissions.new()
reddit.subreddit("all").new()
classmethod parse(data: Dict[str, Any], reddit: praw.Reddit) Any

Return an instance of cls from data.

Parameters
  • data – The structured data.

  • reddit – An instance of Reddit.

post_requirements() Dict[str, Union[str, int, bool]]

Get the post requirements for a subreddit.

Returns

A dict with the various requirements.

The returned dict contains the following keys:

  • domain_blacklist

  • body_restriction_policy

  • domain_whitelist

  • title_regexes

  • body_blacklisted_strings

  • body_required_strings

  • title_text_min_length

  • is_flair_required

  • title_text_max_length

  • body_regexes

  • link_repost_age

  • body_text_min_length

  • link_restriction_policy

  • body_text_max_length

  • title_required_strings

  • title_blacklisted_strings

  • guidelines_text

  • guidelines_display_policy

For example, to fetch the post requirements for r/test:

print(reddit.subreddit("test").post_requirements)
quaran() praw.models.reddit.subreddit.SubredditQuarantine

Provide an instance of SubredditQuarantine.

This property is named quaran because quarantine is a subreddit attribute returned by Reddit to indicate whether or not a subreddit is quarantined.

To opt-in into a quarantined subreddit:

reddit.subreddit("test").quaran.opt_in()
random() Optional[praw.models.Submission]

Return a random Submission.

Returns None on subreddits that do not support the random feature. One example, at the time of writing, is r/wallpapers.

For example, to get a random submission off of r/AskReddit:

submission = reddit.subreddit("AskReddit").random()
print(submission.title)
random_rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for random rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get random rising submissions for r/test:

for submission in reddit.subreddit("test").random_rising():
    print(submission.title)
rising(**generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[praw.models.Submission]

Return a ListingGenerator for rising submissions.

Additional keyword arguments are passed in the initialization of ListingGenerator.

For example, to get rising submissions for r/test:

for submission in reddit.subreddit("test").rising():
    print(submission.title)
rules() SubredditRules

Provide an instance of SubredditRules.

Use this attribute for interacting with a Subreddit’s rules.

For example, to list all the rules for a subreddit:

for rule in reddit.subreddit("test").rules:
    print(rule)

Moderators can also add rules to the subreddit. For example, to make a rule called "No spam" in r/test:

reddit.subreddit("test").rules.mod.add(
    short_name="No spam", kind="all", description="Do not spam. Spam bad"
)
search(query: str, *, sort: str = 'relevance', syntax: str = 'lucene', time_filter: str = 'all', **generator_kwargs: Any) Iterator[praw.models.Submission]

Return a ListingGenerator for items that match query.

Parameters
  • query – The query string to search for.

  • sort – Can be one of: "relevance", "hot", "top", "new", or "comments". (default: "relevance").

  • syntax – Can be one of: "cloudsearch", "lucene", or "plain" (default: "lucene").

  • time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

For more information on building a search query see: https://www.reddit.com/wiki/search

For example, to search all subreddits for "praw" try:

for submission in reddit.subreddit("all").search("praw"):
    print(submission.title)
sticky(*, number: int = 1) praw.models.Submission

Return a Submission object for a sticky of the subreddit.

Parameters

number – Specify which sticky to return. 1 appears at the top (default: 1).

Raises

prawcore.NotFound if the sticky does not exist.

For example, to get the stickied post on r/test:

reddit.subreddit("test").sticky()
stream() praw.models.reddit.subreddit.SubredditStream

Provide an instance of SubredditStream.

Streams can be used to indefinitely retrieve new comments made to a subreddit, like:

for comment in reddit.subreddit("test").stream.comments():
    print(comment)

Additionally, new submissions can be retrieved via the stream. In the following example all submissions are fetched via the special r/all:

for submission in reddit.subreddit("all").stream.submissions():
    print(submission)
stylesheet() praw.models.reddit.subreddit.SubredditStylesheet

Provide an instance of SubredditStylesheet.

For example, to add the css data .test{color:blue} to the existing stylesheet:

subreddit = reddit.subreddit("test")
stylesheet = subreddit.stylesheet()
stylesheet.stylesheet += ".test{color:blue}"
subreddit.stylesheet.update(stylesheet.stylesheet)
submit(title: str, *, collection_id: Optional[str] = None, discussion_type: Optional[str] = None, draft_id: Optional[str] = None, flair_id: Optional[str] = None, flair_text: Optional[str] = None, inline_media: Optional[Dict[str, praw.models.InlineMedia]] = None, nsfw: bool = False, resubmit: bool = True, selftext: Optional[str] = None, send_replies: bool = True, spoiler: bool = False, url: Optional[str] = None) praw.models.Submission

Add a submission to the Subreddit.

Parameters
  • title – The title of the submission.

  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • draft_id – The ID of a draft to submit.

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • inline_media – A dict of InlineMedia objects where the key is the placeholder name in selftext.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • resubmit – When False, an error will occur if the URL has already been submitted (default: True).

  • selftext – The Markdown formatted content for a text submission. Use an empty string, "", to make a title-only submission.

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

  • url – The URL for a link submission.

Returns

A Submission object for the newly created submission.

Either selftext or url can be provided, but not both.

For example, to submit a URL to r/test do:

title = "PRAW documentation"
url = "https://praw.readthedocs.io"
reddit.subreddit("test").submit(title, url=url)

For example, to submit a self post with inline media do:

from praw.models import InlineGif, InlineImage, InlineVideo

gif = InlineGif(path="path/to/image.gif", caption="optional caption")
image = InlineImage(path="path/to/image.jpg", caption="optional caption")
video = InlineVideo(path="path/to/video.mp4", caption="optional caption")
selftext = "Text with a gif {gif1} an image {image1} and a video {video1} inline"
media = {"gif1": gif, "image1": image, "video1": video}
reddit.subreddit("test").submit("title", inline_media=media, selftext=selftext)

Note

Inserted media will have a padding of \\n\\n automatically added. This is due to the weirdness with Reddit’s API. Using the example above, the result selftext body will look like so:

Text with a gif

![gif](u1rchuphryq51 "optional caption")

an image

![img](srnr8tshryq51 "optional caption")

and video

![video](gmc7rvthryq51 "optional caption")

inline

Note

To submit a post to a subreddit with the "news" flair, you can get the flair id like this:

choices = list(subreddit.flair.link_templates.user_selectable())
template_id = next(x for x in choices if x["flair_text"] == "news")["flair_template_id"]
subreddit.submit("title", flair_id=template_id, url="https://www.news.com/")

See also

Add an image gallery submission to the subreddit.

Parameters
  • title – The title of the submission.

  • images – The images to post in dict with the following structure: {"image_path": "path", "caption": "caption", "outbound_url": "url"}, only image_path is required.

  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked asa spoiler (default: False).

Returns

A Submission object for the newly created submission.

Raises

ClientException if image_path in images refers to a file that is not an image.

For example, to submit an image gallery to r/test do:

title = "My favorite pictures"
image = "/path/to/image.png"
image2 = "/path/to/image2.png"
image3 = "/path/to/image3.png"
images = [
    {"image_path": image},
    {
        "image_path": image2,
        "caption": "Image caption 2",
    },
    {
        "image_path": image3,
        "caption": "Image caption 3",
        "outbound_url": "https://example.com/link3",
    },
]
reddit.subreddit("test").submit_gallery(title, images)

See also

submit_image(title: str, image_path: str, *, collection_id: Optional[str] = None, discussion_type: Optional[str] = None, flair_id: Optional[str] = None, flair_text: Optional[str] = None, nsfw: bool = False, resubmit: bool = True, send_replies: bool = True, spoiler: bool = False, timeout: int = 10, without_websockets: bool = False)

Add an image submission to the subreddit.

Parameters
  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • image_path – The path to an image, to upload and post.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • resubmit – When False, an error will occur if the URL has already been submitted (default: True).

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

  • timeout – Specifies a particular timeout, in seconds. Use to avoid “Websocket error” exceptions (default: 10).

  • title – The title of the submission.

  • without_websockets – Set to True to disable use of WebSockets (see note below for an explanation). If True, this method doesn’t return anything (default: False).

Returns

A Submission object for the newly created submission, unless without_websockets is True.

Raises

ClientException if image_path refers to a file that is not an image.

Note

Reddit’s API uses WebSockets to respond with the link of the newly created post. If this fails, the method will raise WebSocketException. Occasionally, the Reddit post will still be created. More often, there is an error with the image file. If you frequently get exceptions but successfully created posts, try setting the timeout parameter to a value above 10.

To disable the use of WebSockets, set without_websockets=True. This will make the method return None, though the post will still be created. You may wish to do this if you are running your program in a restricted network environment, or using a proxy that doesn’t support WebSockets connections.

For example, to submit an image to r/test do:

title = "My favorite picture"
image = "/path/to/image.png"
reddit.subreddit("test").submit_image(title, image)

See also

submit_poll(title: str, *, collection_id: Optional[str] = None, discussion_type: Optional[str] = None, duration: int, flair_id: Optional[str] = None, flair_text: Optional[str] = None, nsfw: bool = False, options: List[str], resubmit: bool = True, selftext: str, send_replies: bool = True, spoiler: bool = False)

Add a poll submission to the subreddit.

Parameters
  • title – The title of the submission.

  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • duration – The number of days the poll should accept votes, as an int. Valid values are between 1 and 7, inclusive.

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • options – A list of two to six poll options as str.

  • resubmit – When False, an error will occur if the URL has already been submitted (default: True).

  • selftext – The Markdown formatted content for the submission. Use an empty string, "", to make a submission with no text contents.

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

Returns

A Submission object for the newly created submission.

For example, to submit a poll to r/test do:

title = "Do you like PRAW?"
reddit.subreddit("test").submit_poll(
    title, selftext="", options=["Yes", "No"], duration=3
)

See also

submit_video(title: str, video_path: str, *, collection_id: Optional[str] = None, discussion_type: Optional[str] = None, flair_id: Optional[str] = None, flair_text: Optional[str] = None, nsfw: bool = False, resubmit: bool = True, send_replies: bool = True, spoiler: bool = False, thumbnail_path: Optional[str] = None, timeout: int = 10, videogif: bool = False, without_websockets: bool = False)

Add a video or videogif submission to the subreddit.

Parameters
  • title – The title of the submission.

  • video_path – The path to a video, to upload and post.

  • collection_id – The UUID of a Collection to add the newly-submitted post to.

  • discussion_type – Set to "CHAT" to enable live discussion instead of traditional comments (default: None).

  • flair_id – The flair template to select (default: None).

  • flair_text – If the template’s flair_text_editable value is True, this value will set a custom text (default: None). flair_id is required when flair_text is provided.

  • nsfw – Whether the submission should be marked NSFW (default: False).

  • resubmit – When False, an error will occur if the URL has already been submitted (default: True).

  • send_replies – When True, messages will be sent to the submission author when comments are made to the submission (default: True).

  • spoiler – Whether the submission should be marked as a spoiler (default: False).

  • thumbnail_path – The path to an image, to be uploaded and used as the thumbnail for this video. If not provided, the PRAW logo will be used as the thumbnail.

  • timeout – Specifies a particular timeout, in seconds. Use to avoid “Websocket error” exceptions (default: 10).

  • videogif – If True, the video is uploaded as a videogif, which is essentially a silent video (default: False).

  • without_websockets – Set to True to disable use of WebSockets (see note below for an explanation). If True, this method doesn’t return anything (default: False).

Returns

A Submission object for the newly created submission, unless without_websockets is True.

Raises

ClientException if video_path refers to a file that is not a video.

Note

Reddit’s API uses WebSockets to respond with the link of the newly created post. If this fails, the method will raise WebSocketException. Occasionally, the Reddit post will still be created. More often, there is an error with the image file. If you frequently get exceptions but successfully created posts, try setting the timeout parameter to a value above 10.

To disable the use of WebSockets, set without_websockets=True. This will make the method return None, though the post will still be created. You may wish to do this if you are running your program in a restricted network environment, or using a proxy that doesn’t support WebSockets connections.

For example, to submit a video to r/test do:

title = "My favorite movie"
video = "/path/to/video.mp4"
reddit.subreddit("test").submit_video(title, video)

See also

subscribe(*, other_subreddits: Optional[List[praw.models.Subreddit]] = None)

Subscribe to the subreddit.

Parameters

other_subreddits – When provided, also subscribe to the provided list of subreddits.

For example, to subscribe to r/test:

reddit.subreddit("test").subscribe()
top(*, time_filter: str = 'all', **generator_kwargs: Union[str, int, Dict[str, str]]) Iterator[Any]

Return a ListingGenerator for top items.

Parameters

time_filter – Can be one of: "all", "day", "hour", "month", "week", or "year" (default: "all").

Raises

ValueError if time_filter is invalid.

Additional keyword arguments are passed in the initialization of ListingGenerator.

This method can be used like:

reddit.domain("imgur.com").top(time_filter="week")
reddit.multireddit(redditor="samuraisam", name="programming").top(time_filter="day")
reddit.redditor("spez").top(time_filter="month")
reddit.redditor("spez").comments.top(time_filter="year")
reddit.redditor("spez").submissions.top(time_filter="all")
reddit.subreddit("all").top(time_filter="hour")
traffic() Dict[str, List[List[int]]]

Return a dictionary of the Subreddit’s traffic statistics.

Raises

prawcore.NotFound when the traffic stats aren’t available to the authenticated user, that is, they are not public and the authenticated user is not a moderator of the subreddit.

The traffic method returns a dict with three keys. The keys are day, hour and month. Each key contains a list of lists with 3 or 4 values. The first value is a timestamp indicating the start of the category (start of the day for the day key, start of the hour for the hour key, etc.). The second, third, and fourth values indicate the unique pageviews, total pageviews, and subscribers, respectively.

Note

The hour key does not contain subscribers, and therefore each sub-list contains three values.

For example, to get the traffic stats for r/test:

stats = reddit.subreddit("test").traffic()
unsubscribe(*, other_subreddits: Optional[List[praw.models.Subreddit]] = None)

Unsubscribe from the subreddit.

Parameters

other_subreddits – When provided, also unsubscribe from the provided list of subreddits.

To unsubscribe from r/test:

reddit.subreddit("test").unsubscribe()
widgets() praw.models.SubredditWidgets

Provide an instance of SubredditWidgets.

Example usage

Get all sidebar widgets:

for widget in reddit.subreddit("test").widgets.sidebar:
    print(widget)

Get ID card widget:

print(reddit.subreddit("test").widgets.id_card)
wiki() praw.models.reddit.subreddit.SubredditWiki

Provide an instance of SubredditWiki.

This attribute can be used to discover all wikipages for a subreddit:

for wikipage in reddit.subreddit("test").wiki:
    print(wikipage)

To fetch the content for a given wikipage try:

wikipage = reddit.subreddit("test").wiki["proof"]
print(wikipage.content_md)

Util

class praw.models.util.BoundedSet(max_items: int)

A set with a maximum size that evicts the oldest items when necessary.

This class does not implement the complete set interface.

__contains__(item: Any) bool

Test if the BoundedSet contains item.

__init__(max_items: int)

Initialize a BoundedSet instance.

add(item: Any)

Add an item to the set discarding the oldest item if necessary.

class praw.models.util.ExponentialCounter(max_counter: int)

A class to provide an exponential counter with jitter.

__init__(max_counter: int)

Initialize an ExponentialCounter instance.

Parameters

max_counter

The maximum base value.

Note

The computed value may be 3.125% higher due to jitter.

counter() Union[int, float]

Increment the counter and return the current value with jitter.

reset()

Reset the counter to 1.

praw.models.util.permissions_string(*, known_permissions: Set[str], permissions: Optional[List[str]]) str

Return a comma separated string of permission changes.

Parameters
  • known_permissions – A set of strings representing the available permissions.

  • permissions – A list of strings, or None. These strings can exclusively contain + or - prefixes, or contain no prefixes at all. When prefixed, the resulting string will simply be the joining of these inputs. When not prefixed, all permissions are considered to be additions, and all permissions in the known_permissions set that aren’t provided are considered to be removals. When None, the result is "+all".

praw.models.util.stream_generator(function: Callable, *, attribute_name: str = 'fullname', exclude_before: bool = False, pause_after: Optional[int] = None, skip_existing: bool = False, **function_kwargs: Any) Generator[Any, None, None]

Yield new items from function as they become available.

Parameters
  • function – A callable that returns a ListingGenerator, e.g., Subreddit.comments() or Subreddit.new().

  • attribute_name – The field to use as an ID (default: "fullname").

  • exclude_before – When True does not pass params to function (default: False).

  • pause_after – An integer representing the number of requests that result in no new items before this function yields None, effectively introducing a pause into the stream. A negative value yields None after items from a single response have been yielded, regardless of number of new items obtained in that response. A value of 0 yields None after every response resulting in no new items, and a value of None never introduces a pause (default: None).

  • skip_existing – When True, this does not yield any results from the first request thereby skipping any items that existed in the stream prior to starting the stream (default: False).

Additional keyword arguments will be passed to function.

Note

This function internally uses an exponential delay with jitter between subsequent responses that contain no new results, up to a maximum delay of just over 16 seconds. In practice, that means that the time before pause for pause_after=N+1 is approximately twice the time before pause for pause_after=N.

For example, to create a stream of comment replies, try:

reply_function = reddit.inbox.comment_replies
for reply in praw.models.util.stream_generator(reply_function):
    print(reply)

To pause a comment stream after six responses with no new comments, try:

subreddit = reddit.subreddit("test")
for comment in subreddit.stream.comments(pause_after=6):
    if comment is None:
        break
    print(comment)

To resume fetching comments after a pause, try:

subreddit = reddit.subreddit("test")
comment_stream = subreddit.stream.comments(pause_after=5)

for comment in comment_stream:
    if comment is None:
        break
    print(comment)
# Do any other processing, then try to fetch more data
for comment in comment_stream:
    if comment is None:
        break
    print(comment)

To bypass the internal exponential backoff, try the following. This approach is useful if you are monitoring a subreddit with infrequent activity, and you want to consistently learn about new items from the stream as soon as possible, rather than up to a delay of just over sixteen seconds.

subreddit = reddit.subreddit("test")
for comment in subreddit.stream.comments(pause_after=0):
    if comment is None:
        continue
    print(comment)

Comment Extraction and Parsing

A common use for Reddit’s API is to extract comments from submissions and use them to perform keyword or phrase analysis.

As always, you need to begin by creating an instance of Reddit:

import praw

reddit = praw.Reddit(
    client_id="CLIENT_ID",
    client_secret="CLIENT_SECRET",
    password="PASSWORD",
    user_agent="Comment Extraction (by u/USERNAME)",
    username="USERNAME",
)

Note

If you are only analyzing public comments, entering a username and password is optional.

In this document, we will detail the process of finding all the comments for a given submission. If you instead want to process all comments on Reddit, or comments belonging to one or more specific subreddits, please see SubredditStream.comments().

Extracting comments with PRAW

Assume we want to process the comments for this submission: https://www.reddit.com/r/funny/comments/3g1jfi/buttons/

We first need to obtain a submission object. We can do that either with the entire URL:

url = "https://www.reddit.com/r/funny/comments/3g1jfi/buttons/"
submission = reddit.submission(url=url)

or with the submission’s ID which comes after comments/ in the URL:

submission = reddit.submission("3g1jfi")

With a submission object we can then interact with its CommentForest through the submission’s Submission.comments attribute. A CommentForest is a list of top-level comments each of which contains a CommentForest of replies.

If we wanted to output only the body of the top-level comments in the thread we could do:

for top_level_comment in submission.comments:
    print(top_level_comment.body)

While running this you will most likely encounter the exception AttributeError: 'MoreComments' object has no attribute 'body'. This submission’s comment forest contains a number of MoreComments objects. These objects represent the “load more comments”, and “continue this thread” links encountered on the website. While we could ignore MoreComments in our code, like so:

from praw.models import MoreComments

for top_level_comment in submission.comments:
    if isinstance(top_level_comment, MoreComments):
        continue
    print(top_level_comment.body)

The replace_more method

In the previous snippet, we used isinstance() to check whether the item in the comment list was a MoreComments so that we could ignore it. But there is a better way: the CommentForest object has a method called replace_more(), which replaces or removes MoreComments objects from the forest.

Each replacement requires one network request, and its response may yield additional MoreComments instances. As a result, by default, replace_more() only replaces at most 32 MoreComments instances – all other instances are simply removed. The maximum number of instances to replace can be configured via the limit parameter. Additionally a threshold parameter can be set to only perform replacement of MoreComments instances that represent a minimum number of comments; it defaults to 0, meaning all MoreComments instances will be replaced up to limit.

A limit of 0 simply removes all MoreComments from the forest. The previous snippet can thus be simplified:

submission.comments.replace_more(limit=0)
for top_level_comment in submission.comments:
    print(top_level_comment.body)

Note

Calling replace_more() is destructive. Calling it again on the same submission instance has no effect.

Meanwhile, a limit of None means that all MoreComments objects will be replaced until there are none left, as long as they satisfy the threshold.

submission.comments.replace_more(limit=None)
for top_level_comment in submission.comments:
    print(top_level_comment.body)

Now we are able to successfully iterate over all the top-level comments. What about their replies? We could output all second-level comments like so:

submission.comments.replace_more(limit=None)
for top_level_comment in submission.comments:
    for second_level_comment in top_level_comment.replies:
        print(second_level_comment.body)

However, the comment forest can be arbitrarily deep, so we’ll want a more robust solution. One way to iterate over a tree, or forest, is via a breadth-first traversal using a queue:

submission.comments.replace_more(limit=None)
comment_queue = submission.comments[:]  # Seed with top-level
while comment_queue:
    comment = comment_queue.pop(0)
    print(comment.body)
    comment_queue.extend(comment.replies)

The above code will output all the top-level comments, followed by second-level, third-level, etc. While it is awesome to be able to do your own breadth-first traversals, CommentForest provides a convenience method, list(), which returns a list of comments traversed in the same order as the code above. Thus the above can be rewritten as:

submission.comments.replace_more(limit=None)
for comment in submission.comments.list():
    print(comment.body)

You can now properly extract and parse all (or most) of the comments belonging to a single submission. Combine this with submission iteration and you can build some really cool stuff.

Finally, note that the value of submission.num_comments may not match up 100% with the number of comments extracted via PRAW. This discrepancy is normal as that count includes deleted, removed, and spam comments.

Working with Refresh Tokens

Reddit OAuth2 Scopes

Before working with refresh tokens you should decide which scopes your application requires. If you want to use all scopes, you can use the special scope *.

To get an up-to-date listing of all Reddit scopes and their descriptions run the following:

import requests

response = requests.get(
    "https://www.reddit.com/api/v1/scopes.json",
    headers={"User-Agent": "fetch-scopes by u/bboe"},
)

for scope, data in sorted(response.json().items()):
    print(f"{scope:>18s}  {data['description']}")

As of February 2021, the available scopes are:

Scope

Description

account

Update preferences and related account information. Will not have access to your email or password.

creddits

Spend my reddit gold creddits on giving gold to other users.

edit

Edit and delete my comments and submissions.

flair

Select my subreddit flair. Change link flair on my submissions.

history

Access my voting history and comments or submissions I’ve saved or hidden.

identity

Access my reddit username and signup date.

livemanage

Manage settings and contributors of live threads I contribute to.

modconfig

Manage the configuration, sidebar, and CSS of subreddits I moderate.

modcontributors

Add/remove users to approved user lists and ban/unban or mute/unmute users from subreddits I moderate.

modflair

Manage and assign flair in subreddits I moderate.

modlog

Access the moderation log in subreddits I moderate.

modmail

Access and manage modmail via mod.reddit.com.

modothers

Invite or remove other moderators from subreddits I moderate.

modposts

Approve, remove, mark nsfw, and distinguish content in subreddits I moderate.

modself

Accept invitations to moderate a subreddit. Remove myself as a moderator or contributor of subreddits I moderate or contribute to.

modtraffic

Access traffic stats in subreddits I moderate.

modwiki

Change editors and visibility of wiki pages in subreddits I moderate.

mysubreddits

Access the list of subreddits I moderate, contribute to, and subscribe to.

privatemessages

Access my inbox and send private messages to other users.

read

Access posts and comments through my account.

report

Report content for rules violations. Hide & show individual submissions.

save

Save and unsave comments and submissions.

structuredstyles

Edit structured styles for a subreddit I moderate.

submit

Submit links and comments from my account.

subscribe

Manage my subreddit subscriptions. Manage “friends” - users whose content I follow.

vote

Submit and change my votes on comments and submissions.

wikiedit

Edit wiki pages on my behalf

wikiread

Read wiki pages through my account

Obtaining Refresh Tokens

The following program can be used to obtain a refresh token with the desired scopes:

#!/usr/bin/env python

"""This example demonstrates the flow for retrieving a refresh token.

This tool can be used to conveniently create refresh tokens for later use with your web
application OAuth2 credentials.

To create a Reddit application visit the following link while logged into the account
you want to create a refresh token for: https://www.reddit.com/prefs/apps/

Create a "web app" with the redirect uri set to: http://localhost:8080

After the application is created, take note of:

- REDDIT_CLIENT_ID; the line just under "web app" in the upper left of the Reddit
  Application
- REDDIT_CLIENT_SECRET; the value to the right of "secret"

Usage:

    EXPORT praw_client_id=<REDDIT_CLIENT_ID>
    EXPORT praw_client_secret=<REDDIT_CLIENT_SECRET>
    python3 obtain_refresh_token.py

"""
import random
import socket
import sys

import praw


def main():
    """Provide the program's entry point when directly executed."""
    scope_input = input(
        "Enter a comma separated list of scopes, or '*' for all scopes: "
    )
    scopes = [scope.strip() for scope in scope_input.strip().split(",")]

    reddit = praw.Reddit(
        redirect_uri="http://localhost:8080",
        user_agent="obtain_refresh_token/v0 by u/bboe",
    )
    state = str(random.randint(0, 65000))
    url = reddit.auth.url(duration="permanent", scopes=scopes, state=state)
    print(f"Now open this url in your browser: {url}")

    client = receive_connection()
    data = client.recv(1024).decode("utf-8")
    param_tokens = data.split(" ", 2)[1].split("?", 1)[1].split("&")
    params = {
        key: value for (key, value) in [token.split("=") for token in param_tokens]
    }

    if state != params["state"]:
        send_message(
            client,
            f"State mismatch. Expected: {state} Received: {params['state']}",
        )
        return 1
    elif "error" in params:
        send_message(client, params["error"])
        return 1

    refresh_token = reddit.auth.authorize(params["code"])
    send_message(client, f"Refresh token: {refresh_token}")
    return 0


def receive_connection():
    """Wait for and then return a connected socket..

    Opens a TCP connection on port 8080, and waits for a single client.

    """
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind(("localhost", 8080))
    server.listen(1)
    client = server.accept()[0]
    server.close()
    return client


def send_message(client, message):
    """Send message to client and close the connection."""
    print(message)
    client.send(f"HTTP/1.1 200 OK\r\n\r\n{message}".encode("utf-8"))
    client.close()


if __name__ == "__main__":
    sys.exit(main())

This script assumes you have configured your application’s redirect uri to localhost:8080

When you execute this script interactively:

  1. You will be prompted to provide a comma-separated list of scopes.

  2. You will be given a URL that will take you through the auth flow on Reddit.

  3. When you open the provided link in your browser, Reddit will ask you for permission to grant the application permissions to the scopes requested.

  4. After clicking allow, you will have a new authorized application configured.

  5. You will be redirected to another page (the application’s redirect uri) where your refresh token will be displayed and will be printed to the command line.

You only have to run this script once for each refresh token. The refresh token (along with the application’s client_id, client_secret) are valid credentials until manually revoked by the user.

Submission Stream Reply Bot

Most redditors have seen bots in action on the site. Reddit bots can perform a number of tasks including providing useful information, e.g., an Imperial to Metric units bot; convenience, e.g., a link corrector bot; or analytical information, e.g., redditor analyzer bot for writing complexity.

PRAW provides a simple way to build your own bot using the Python programming language. As a result, it is little surprise that a majority of bots on Reddit are powered by PRAW.

This tutorial will show you how to build a bot that monitors a particular subreddit, r/AskReddit, for new submissions containing simple questions and replies with an appropriate link to lmgtfy (Let Me Google That For You).

There are three key components we will address to perform this task:

  1. Monitor new submissions.

  2. Analyze the title of each submission to see if it contains a simple question.

  3. Reply with an appropriate lmgtfy link.

LMGTFY Bot

The goal of the LMGTFY Bot is to point users in the right direction when they ask a simple question that is unlikely to be upvoted or answered by other users.

Two examples of such questions are:

  1. “What is the capital of Canada?”

  2. “How many feet are in a yard?”

Once we identify these questions, the LMGTFY Bot will reply to the submission with an appropriate lmgtfy link. For the example questions those links are:

  1. https://lmgtfy.com/?q=What+is+the+capital+of+Canada%3F

  2. https://lmgtfy.com/?q=How+many+feet+are+in+a+yard%3F

Step 1: Getting Started

Access to Reddit’s API requires a set of OAuth2 credentials. Those credentials are obtained by registering an application with Reddit. To register an application and receive a set of OAuth2 credentials please follow only the “First Steps” section of Reddit’s OAuth2 Quick Start Example wiki page.

Once the credentials are obtained we can begin writing the LMGTFY Bot. Start by creating an instance of Reddit:

import praw

reddit = praw.Reddit(
    client_id="CLIENT_ID",
    client_secret="CLIENT_SECRET",
    password="PASSWORD",
    user_agent="LMGTFY (by u/USERNAME)",
    username="USERNAME",
)

In addition to the OAuth2 credentials, the username and password of the Reddit account that registered the application are required.

Note

This example demonstrates use of a script type application. For other application types please see Reddit’s wiki page OAuth2 App Types.

Step 2: Monitoring New Submissions to r/AskReddit

PRAW provides a convenient way to obtain new submissions to a given subreddit. To indefinitely iterate over new submissions to a subreddit add:

subreddit = reddit.subreddit("AskReddit")
for submission in subreddit.stream.submissions():
    # do something with submission
    ...

Replace "AskReddit" with the name of another subreddit if you want to iterate through its new submissions. Additionally, multiple subreddits can be specified by joining them with pluses (+), for example "AskReddit+NoStupidQuestions". All subreddits can be specified using the special name "all". Subreddits can be excluded from the special "all" subreddit by joining them with minuses (-), for example "all-excluded_subreddit1-excluded_subreddit2".

Step 3: Analyzing the Submission Titles

Now that we have a stream of new submissions to r/AskReddit, it is time to see if their titles contain a simple question. We naïvely define a simple question as:

  1. It must contain no more than ten words.

  2. It must contain one of the phrases "what is", "what are", or "who is".

Warning

These naïve criteria result in many false positives. It is strongly recommended that you develop more precise heuristics before launching a bot on any popular subreddits.

First we filter out titles that contain more than ten words:

if len(submission.title.split()) > 10:
    return

We then check to see if the submission’s title contains any of the desired phrases:

questions = ["what is", "who is", "what are"]
normalized_title = submission.title.lower()
for question_phrase in questions:
    if question_phrase in normalized_title:
        # do something with a matched submission
        break

String comparison in Python is case sensitive. As a result, we only compare a normalized version of the title to our lower-case question phrases. In this case, “normalized” means only lower-case.

The break at the end prevents us from matching more than once on a single submission. For instance, what would happen without the break if a submission’s title was “Who is or what are buffalo?”?

Step 4: Automatically Replying to the Submission

The LMGTFY Bot is nearly complete. We iterate through submissions and find ones that appear to be simple questions. All that is remaining is to reply to those submissions with an appropriate lmgtfy link.

First we will need to construct a working lmgtfy link. In essence, we want to pass the entire submission title to lmgtfy. However, there are certain characters that are not permitted in URLs or have other meanings. For instance, the space character, `` , is not permitted, and the question mark, ``?, has a special meaning. Thus we will transform those into their URL-safe representation so that a question like “What is the capital of Canada?” is transformed into the link https://lmgtfy.com/?q=What+is+the+capital+of+Canada%3F.

There are a number of ways we could accomplish this task. For starters, we could write a function to replace spaces with pluses (+) and question marks with %3F. However, there is even an easier way; using an existing built-in function to do so.

Add the following code where the “do something with a matched submission” comment is located:

from urllib.parse import quote_plus

reply_template = "[Let me google that for you](https://lmgtfy.com/?q={})"

url_title = quote_plus(submission.title)
reply_text = reply_template.format(url_title)

Now that we have the reply text, replying to the submission is easy:

submission.reply(reply_text)

If all went well, your comment should have been made. If your bot account is brand new, you will likely run into rate limit issues. These rate limits will persist until that account acquires sufficient karma.

Step 5: Cleaning Up The Code

While we have a working bot, we have added little segments here and there. If we were to continue to do so in this fashion our code would be quite unreadable. Let’s clean it up some.

The first thing we should do is put all of our import statements at the top of the file. It is common to list built-in packages before third-party ones:

#!/usr/bin/env python3
from urllib.parse import quote_plus

import praw

Next, we extract a few constants that are used in our script:

QUESTIONS = ["what is", "who is", "what are"]
REPLY_TEMPLATE = "[Let me google that for you](https://lmgtfy.com/?q={})"

We then extract the segment of code pertaining to processing a single submission into its own function:

def process_submission(submission):
    # Ignore titles with more than 10 words as they probably are not simple questions.
    if len(submission.title.split()) > 10:
        return

    normalized_title = submission.title.lower()
    for question_phrase in QUESTIONS:
        if question_phrase in normalized_title:
            url_title = quote_plus(submission.title)
            reply_text = REPLY_TEMPLATE.format(url_title)
            print(f"Replying to: {submission.title}")
            submission.reply(reply_text)
            # A reply has been made so do not attempt to match other phrases.
            break

Observe that we added some comments and a print() call. The print() addition informs us every time we are about to reply to a submission, which is useful to ensure the script is running.

Next, it is a good practice to not have any top-level executable code in case you want to turn your Python script into a Python module, i.e., import it from another Python script or module. A common way to do that is to move the top-level code to a main function:

def main():
    reddit = praw.Reddit(
        client_id="CLIENT_ID",
        client_secret="CLIENT_SECRET",
        password="PASSWORD",
        user_agent="LMGTFY (by u/USERNAME)",
        username="USERNAME",
    )

    subreddit = reddit.subreddit("AskReddit")
    for submission in subreddit.stream.submissions():
        process_submission(submission)

Finally, we need to call main only in the cases that this script is the one being executed:

if __name__ == "__main__":
    main()
The Complete LMGTFY Bot

The following is the complete LMGTFY Bot:

#!/usr/bin/env python3
from urllib.parse import quote_plus

import praw

QUESTIONS = ["what is", "who is", "what are"]
REPLY_TEMPLATE = "[Let me google that for you](https://lmgtfy.com/?q={})"


def main():
    reddit = praw.Reddit(
        client_id="CLIENT_ID",
        client_secret="CLIENT_SECRET",
        password="PASSWORD",
        user_agent="LMGTFY (by u/USERNAME)",
        username="USERNAME",
    )

    subreddit = reddit.subreddit("AskReddit")
    for submission in subreddit.stream.submissions():
        process_submission(submission)


def process_submission(submission):
    # Ignore titles with more than 10 words as they probably are not simple questions.
    if len(submission.title.split()) > 10:
        return

    normalized_title = submission.title.lower()
    for question_phrase in QUESTIONS:
        if question_phrase in normalized_title:
            url_title = quote_plus(submission.title)
            reply_text = REPLY_TEMPLATE.format(url_title)
            print(f"Replying to: {submission.title}")
            submission.reply(reply_text)
            # A reply has been made so do not attempt to match other phrases.
            break


if __name__ == "__main__":
    main()

Change Log

PRAW follows semantic versioning.

7.6.1 (2022/11/11)

Changed

  • Revert edit() positional argument deprecation.

  • Revert reply() positional argument deprecation.

  • Revert reply() positional argument deprecation.

  • Revert edit() positional argument deprecation.

  • Revert reply() positional argument deprecation.

Fixed

  • An issue where ModmailConversation’s messages attribute would only contain the latest message.

7.6.0 (2022/05/10)

Added

Changed

  • Drop support for Python 3.6, which is end-of-life on 2021-12-23.

  • conversations() now returns a ListingGenerator allowing you to page through more than 100 conversations.

Deprecated

  • The after argument for conversations() will now have to be included in params keyword argument.

  • Positional keyword arguments for applicable functions and methods. Starting with PRAW 8, most functions and methods will no longer support positional arguments. It will encourage more explicit argument passing, enable arguments to be sorted alphabetically, and prevent breaking changes when adding new arguments to existing methods.

7.5.0 (2021/11/13)

Added

  • Log a warning if a submission’s comment_sort attribute is updated after the submission has already been fetched and a warn_comment_sort config setting to turn off the warning.

  • user_selectable() to get available subreddit link flairs.

  • Automatic RateLimit handling will support errors with millisecond resolution.

Fixed

  • An import error when using PRAW in environments where libsqlite3-dev is needed to utilize the sqlite3 builtin.

  • Fixed bug where some keyword arguments that are passed to Draft.submit() would not have an effect.

7.4.0 (2021/07/30)

Added

Changed

Deprecated

  • Reddit keyword argument token_manager.

7.3.0 (2021/06/17)

Added

Changed

  • moderated() will now objectify all data returned from the API.

  • The wiki_edit endpoint has been changed from r/{subreddit}/api/wiki/edit/ to r/{subreddit}/api/wiki/edit.

  • Redditor.block() no longer needs to retrieve a user’s fullname.

Deprecated

Fixed

  • Fixed bug where WikiPage.edit() and SubredditWiki.create() would fail if passed content and reason parameters that produced a request with a body greater than 500 KiB, even when the parameters did not exceed their respective permitted maximum lengths.

  • Fixed bug where request() could not handle instances of BadRequests when the JSON data contained only the keys “reason” and “message”.

  • Fixed bug where request() could not handle instances of BadRequests when the response did not contain valid JSON data.

  • Fixed bug where fullname() sometimes returned the wrong fullname.

7.2.0 (2021/02/24)

Added

Deprecated

  • The configuration setting refresh_token is deprecated and its use will result in a DeprecationWarning. This deprecation applies in all ways of setting configuration values, i.e., via praw.ini, as a keyword argument when initializing an instance of Reddit, and via the PRAW_REFRESH_TOKEN environment variable. To be prepared for PRAW 8, use the new Reddit keyword argument token_manager. See Working with Refresh Tokens in PRAW’s documentation for an example.

  • me() will no longer return None when called in read_only mode starting in PRAW 8. A DeprecationWarning will be issued. To switch forward to the PRAW 8 behavior set praw8_raise_exception_on_me=True in your Reddit call.

7.1.4 (2021/02/07)

Fixed

  • Asynchronous check will no longer fail in Python 3.6 multithreading edge cases.

7.1.3 (2021/02/05)

Changed

  • Asynchronous check will no longer occur when in a Jupyter notebook.

7.1.2 (2021/02/03)

Fixed

  • Asynchronous check would not work on Python 3.6 as get_running_loop() only exists on Python 3.7+.

7.1.1 (2021/02/02)

Added

  • Add method Subreddits.premium() to reflect the naming change in Reddit’s API.

  • Ability to submit image galleries with submit_gallery().

  • Ability to pass a gallery url to Reddit.submission().

  • Ability to specify modmail mute duration.

  • Add method invited() to get invited moderators of a subreddit.

  • Ability to submit text/self posts with inline media.

  • Add method Submission.award() and Comment.award() with the ability to specify type of award, anonymity, and message when awarding a submission or comment.

  • Ability to specify subreddits by name using the subreddits parameter in Reddit.info().

  • A check to see if PRAW is running in an asynchronous environment and will advise the user to use Async PRAW. This also adds a configuration option to disable the check.

Changed

  • Drop support for Python 3.5, which is end-of-life on 2020-09-13.

  • BoundedSet will now utilize a Last-Recently-Used (LRU) storing mechanism, which will change the order in which elements are removed from the set.

  • Improved submit_image() and submit_video() performance in slow network environments by removing a race condition when establishing a websocket connection.

Deprecated

Fixed

  • An issue where leaving as a moderator fails if you are using token auth.

  • An issue where an incorrect error was being raised due to invalid submission urls.

  • Some cases where streams yield the same item multiple times. This cannot be prevented in every case.

7.1.0 (2020/06/22)

Added

Changed

Deprecated

Fixed

  • An issue where certain subreddit settings could not be set through SubredditModeration.update(), such as welcome_message_enabled and welcome_message_text. This change also removes the need for PRAW to track current subreddit settings and send unmodified ones in the update request.

  • Instances of BadRequests captured by PRAW that do not contain any detailed JSON data are re-raised as the original BadRequest.

  • submit_image() and submit_video() will throw MediaPostFailed when Reddit fails to post an image or video post.

7.0.0 (2020/04/24)

Added

Warning

In May-June 2020, Reddit will force all submissions to run through a subreddit’s validation rules.

  • Introduced a data class, RedditErrorItem, to represent an individual error item returned from Reddit.

  • Class RedditAPIException now serves as a container for the RedditErrorItems. You can access the items by doing RedditAPIException.items, which returns a list.

  • APIException is an alias to RedditAPIException.

  • Parameter discussion_type to methods submit(), submit_image(), and submit_video() to support submitting as a live discussion (set to "CHAT").

  • Instances of Trophy can be compared for equality with each other.

  • Reddit has a new configurable parameter, timeout. This defaults to 16 seconds. It controls how long PRAW will wait for a response before throwing an exception.

  • PRAW now handles ratelimit errors returned as instances of RedditAPIException.

  • Reddit has one new parameter, ratelimit_seconds . The parameter configures the maximum amount of seconds to catch ratelimits for. It defaults to 5 seconds when not specified.

Changed

  • prawcore.BadRequest should no longer be raised. Instead, a more useful RedditAPIException instance will be raised.

  • Set the default comment sort to confidence instead of best because it turns out best isn’t actually the correct value for the parameter.

Deprecated

  • APIException is deprecated and slated for removal in PRAW 8.0.

Fixed

Removed

6.5.1 (2020/01/07)

Fixed

  • Removed usages of NoReturn that caused PRAW to fail due to ImportError in Python <3.5.4 and <3.6.2.

6.5.0 (2020/01/05)

Added

Deprecated

  • Method reddit.user.moderator_subreddits as moderated() provides more functionality.

  • The file for ModActions (praw/models/modaction.py) has been moved to praw/models/mod_action.py and the previous has been deprecated.

Expected Changes

  • The behavior of APIException will no longer unicode-escape strings in the next minor release.

6.4.0 (2019/09/21)

Added

  • crosspost() support parameter flair_id to flair the submission immediately upon crossposting.

  • crosspost() support parameter flair_text to set a custom text to the flair immediately upon crossposting.

  • crosspost() support parameter nsfw to mark the submission NSFW immediately upon crossposting.

  • crosspost() support parameter spoiler to mark the submission as a spoiler immediately upon crossposting.

Fixed

Changed

  • Removed css_class parameter cannot be used with background_color, text_color, or mod_only constraint on methods:

    • SubredditFlairTemplates.update()

    • SubredditRedditorFlairTemplates.add()

    • SubredditLinkFlairTemplates.add()

Removed

  • Drop official support for Python 2.7.

  • Multireddit.rename() no longer works due to a change in the Reddit API.

6.3.1 (2019/06/10)

Removed

  • SubredditListingMixin.gilded(), as this was supposed to be removed in 6.0.0 after deprecation in 5.2.0.

6.3.0 (2019/06/09)

Added

Changed

  • Reddit.info() now accepts any non-str iterable for fullnames (not just list).

  • Reddit.info() now returns a generator instead of a list when using the url parameter.

6.2.0 (2019/05/05)

Added

Fixed

Other

  • Bumped minimum prawcore version to 1.0.1.

6.1.1 (2019/01/29)

Added

6.1.0 (2019/01/19)

Added

Changed

Fixed

  • Widgets of unknown types are parsed as Widgets rather than raising an exception.

6.0.0 (2018/07/24)

Added

Fixed

Removed

5.4.0 (2018/03/27)

Added

Deprecated

Fixed

  • Fix bug with positive pause_after values in streams provided by stream_generator() where the wait time was not reset after a yielded None.

  • Parse URLs with trailing slashes and no "comments" element when creating Submission objects.

  • Fix bug where Subreddit.submissions returns a same submission more than once

  • Fix bug where ListingGenerator fetches the same batch of submissions in an infinite loop when "before" parameter is provided.

Removed

  • Removed support for Python 3.3 as it is no longer supported by requests.

5.3.0 (2017/12/16)

Added

Fixed

  • Now raises prawcore.UnavailableForLegalReasons instead of an AssertionError when encountering a HTTP 451 response.

5.2.0 (2017/10/24)

Changed

  • An attribute on LiveUpdate now works as lazy attribute (i.e., populate an attribute when the attribute is first accessed).

Deprecated

  • subreddit.comments.gilded because there isn’t actually an endpoint that returns only gilded comments. Use subreddit.gilded instead.

Fixed

  • Removed comment.permalink() because comment.permalink is now an attribute returned by Reddit.

5.1.0 (2017/08/31)

Added

Fixed

  • Calling Comment.refresh() on a directly fetched, deeply nested Comment will additionally pull in as many parent comments as possible (currently 8) enabling significantly quicker traversal to the top-most Comment via successive parent() calls.

  • Calling refresh() previously could have resulted in a AttributeError: "MoreComments" object has no attribute "_replies" exception. This situation will now result in a ClientException.

  • Properly handle BAD_CSS_NAME errors when uploading stylesheet images with invalid filenames. Previously an AssertionError was raised.

  • Submission’s gilded attribute properly returns the expected value from reddit.

5.0.1 (2017/07/11)

Fixed

  • Calls to hide() and unhide() properly batch into requests of 50 submissions at a time.

  • Lowered the average maximum delay between inactive stream checks by 4x to 16 seconds. It was previously 64 seconds, which was too long.

5.0.0 (2017/07/04)

Added

Changed

  • cloudsearch is no longer the default syntax for search(). lucene is now the default syntax so that PRAW’s default is aligned with Reddit’s default.

  • Reddit.info() will now take either a list of fullnames or a single URL string.

  • Subreddit.submit() accepts a flair template ID and text.

Fixed

Removed

4.6.0 (2017/07/04)

The release’s sole purpose is to announce the deprecation of the is_link parameter as described below:

Added

Deprecated

4.5.1 (2017/05/07)

Fixed

4.5.0 (2017/04/29)

Added

Changed

Deprecated

  • cloudsearch will no longer be the default syntax for Subreddit.search() in PRAW 5. Instead, lucene will be the default syntax so that PRAW’s default is aligned with Reddit’s default.

Fixed

  • Fix bug where WikiPage revisions with deleted authors caused TypeError.

  • Submission attributes comment_limit and comment_sort maintain their values after making instances non-lazy.

4.4.0 (2017/02/21)

Added

Fixed

  • Uploading an image resulting in too large of a request (>500 KB) now raises prawcore.TooLarge instead of an AssertionError.

  • Uploading an invalid image raises APIException.

  • Redditor instances obtained via moderator (e.g., reddit.subreddit("test").moderator()) will contain attributes with the relationship metadata (e.g., mod_permissions).

  • Message instances retrieved from the inbox now have attributes author, dest replies and subreddit properly converted to their appropriate PRAW model.

4.3.0 (2017/01/19)

Added

Fixed

4.2.0 (2017/01/07)

Added

Deprecated

Fixed

  • hide() and unhide() now accept a list of additional submissions.

  • replace_more() is now recoverable. Previously, when an exception was raised during the work done by replace_more(), all unreplaced MoreComments instances were lost. Now MoreComments instances are only removed once their children have been added to the CommentForest enabling callers of replace_more() to call the method as many times as required to complete the replacement.

  • Working with contributors on SubredditWiki is done consistently through contributor not contributors.

  • Subreddit.moderator() works.

  • live_thread.contributor() now returns RedditorList correctly.

Removed

  • validate_time_filter is no longer part of the public interface.

4.1.0 (2016/12/24)

Added

Changed

  • me() now caches its result in order to reduce redundant requests for methods that depend on it. Set use_cache=False when calling to bypass the cache.

  • replace_more() can be called on Comment replies.

Deprecated

  • validate_time_filter will be removed from the public interface in PRAW 4.2 as it was never intended to be part of it to begin with.

  • Iterating directly over SubredditRelationship (e.g., subreddit.banned, subreddit.contributor, subreddit.moderator, etc) and SubredditFlair will be removed in PRAW 5. Iterate instead over their callables, e.g. subreddit.banned() and subreddit.flair().

  • The following methods are deprecated to be removed in PRAW 5 and are replaced with similar Comment.mod... and Submission.mod... alternatives: Subreddit.mod.approve, Subreddit.mod.distinguish, Subreddit.mod.ignore_reports, Subreddit.mod.remove, Subreddit.mod.undistinguish, Subreddit.mod.unignore_reports.

  • Support for passing a Submission to SubredditFlair.set() will be removed in PRAW 5. Use Submission.flair() instead.

  • The thing argument to SubredditFlair.set() is replaced with redditor and will be removed in PRAW 5.

Fixed

  • SubredditModeration.update() accurately updates exclude_banned_modqueue, header_hover_text, show_media and show_media_preview values.

  • Instances of Comment obtained through the inbox (including mentions) are now refreshable.

  • Searching r/all should now work as intended for all users.

  • Accessing an invalid attribute on an instance of Message will raise AttributeError instead of PRAWException.

4.0.0 (2016/11/29)

Fixed

  • Fix bug where ipython tries to access attribute _ipython_canary_method_should_not_exist_ resulting in a useless fetch.

  • Fix bug where Comment replies becomes [] after attempting to access an invalid attribute on the Comment.

  • Reddit.wiki[…] converts the passed in page name to lower case as pages are only saved in lower case and non-lower case page names results in a Redirect exception (thanks pcjonathan).

4.0.0rc3 (2016/11/26)

Added

4.0.0rc2 (2016/11/20)

Fixed

  • Auth.authorize() properly sets the session’s Authentication (thanks @williammck).

4.0.0rc1 (2016/11/20)

PRAW 4 introduces significant breaking changes. The numerous changes are not listed here, only the feature removals. Please read through Quick Start to help with updating your code to PRAW 4. If you require additional help please ask on r/redditdev or via Slack.

Added

Changed

Note

Only prominent changes are listed here.

  • helpers.comments_stream is now SubredditStream.comments()

  • helpers.submissions_between is now Subreddit.submissions. This new method now only iterates through newest submissions first and as a result makes approximately 33% fewer requests.

  • helpers.submission_stream is now SubredditStream.submissions()

Removed

  • Removed Reddit’s login method. Authentication must be done through OAuth.

  • Removed praw-multiprocess as this functionality is no longer needed with PRAW 4.

  • Removed non-oauth functions Message.collapse and Message.uncollapse is_username_available.

  • Removed captcha related functions.

For changes prior to version 4.0 please see: 3.6.2 changelog

Contributing to PRAW

PRAW gladly welcomes new contributions. As with most larger projects, we have an established consistent way of doing things. A consistent style increases readability, decreases bug-potential and makes it faster to understand how everything works together.

Setting Up Your Development Environment

This section will cover the recommended steps to get you started with contributing to PRAW.

Create a Virtual Environment

It is strongly recommended to use a virtual environment to isolate your development environment. This is a good idea because it will make managing the needed dependencies and their versions much easier. For more information, see the venv documentation. Assuming you have the minimum Python version required for PRAW, you can create a virtual environment with the following commands from the root of the cloned project directory:

python3 -m venv .venv

Next you need to activate the virtual environment. This is done by running the following:

MacOS/Linux:

source .venv/bin/activate

Windows Command Prompt

.venv\Scripts\activate.bat
Install Development Dependencies

Next, you will need to install the dependencies development dependencies. This is done by running the following:

pip install -e .[dev]

Important

If you are using zsh for your shell, you will need to double-quote .[dev] like so:

pip install -e ".[dev]"

Note

The -e tells pip to install PRAW in an editable state. This will allow for easier testing and debugging. The [dev] extra will install all development dependencies. This includes the dependencies for both linting and testing.

Code Style

Linting

PRAW follows PEP 8 and PEP 257 and some PRAW Specific Style Guidelines. pre-commit is used to manage a suite of pre-commit hooks that enforce conformance with these PEPs along with several other checks. Additionally, the pre_push.py script can be used to run the full pre-commit suite and the docs build prior to submitting a pull request.

Note

In order to use the pre-commit hooks and the pre_push.py dependencies, you must either install the development dependencies as outlined in the Install Development Dependencies section above or you must install the [lint] extra manually:

pip install -e .[lint]

To install the pre-commit hooks to automatically run when you commit, run the following:

pre-commit install

To run all the needed checks and to ensure the docs build correctly, run the following:

./pre_push.py
PRAW Specific Style Guidelines

The following are PRAW-specific guidelines in addition to the PEPs specified in Linting:

  • Within a single file classes are sorted alphabetically where inheritance permits.

  • Within a class, methods are sorted alphabetically within their respective groups with the following as the grouping order:

    • Static methods

    • Class methods

    • Cached properties

    • Properties

    • Instance Methods

  • Use descriptive names for the catch-all keyword argument, e.g., **other_options rather than **kwargs.

  • Methods with more than one argument should have all its arguments sorted alphabetically and marked as keyword only with the * argument. For example:

    class ExampleClass:
        def example_method(
            self,
            *,
            arg1,
            arg2,
            optional_arg1=None,
        ):
            ...
    

    There is some exceptions to this:

    • If it’s clear without reading documentation what the mandatory positional arguments would be and their order, then they can be positional arguments. For example:

      class ExampleClass:
          def pair(self, left, right):
              ...
      
    • If there is one or two mandatory arguments and some optional arguments, then the mandatory arguments may be positional (as long as it adheres to the previous point), however, the optional arguments must be made keyword only and sorted alphabetically. For example:

      class Subreddit:
          def submit(
              self,
              title,
              *,
              collection_id=None,
              discussion_type=None,
              draft_id=None,
              flair_id=None,
              flair_text=None,
              inline_media=None,
              nsfw=False,
              resubmit=True,
              selftext=None,
              send_replies=True,
              spoiler=False,
              url=None,
          ):
              ...
      

Testing

Contributions to PRAW requires 100% test coverage as reported by Coveralls. If you know how to add a feature, but aren’t sure how to write the necessary tests, please open a pull request anyway so we can work with you to write the necessary tests.

Running the Test Suite

GitHub Actions automatically runs all updates to known branches and pull requests. However, it’s useful to be able to run the tests locally. The simplest way is via:

pytest

Without any configuration or modification, all the tests should pass. If they do not, please file a bug report.

Adding and Updating Integration Tests

PRAW’s integration tests utilize Betamax to record an interaction with Reddit. The recorded interaction is then replayed for subsequent test runs.

To safely record a cassette without leaking your account credentials, PRAW utilizes a number of environment variables which are replaced with placeholders in the cassettes. The environment variables are (listed in bash export format):

export prawtest_client_id=myclientid
export prawtest_client_secret=myclientsecret
export prawtest_password=mypassword
export prawtest_test_subreddit=test
export prawtest_username=myusername
export prawtest_user_agent=praw_pytest

By setting these environment variables prior to running pytest, when adding or updating cassettes, instances of mypassword will be replaced by the placeholder text <PASSWORD> and similar for the other environment variables.

To use a refresh token instead of username/password set prawtest_refresh_token instead of prawtest_password and prawtest_username.

When adding or updating a cassette, you will likely want to force requests to occur again rather than using an existing cassette. The simplest way to rebuild a cassette is to first delete it, and then rerun the test suite.

Please always verify that only the requests you expect to be made are contained within your cassette.

Documentation

  • All publicly available functions, classes, and modules should have a docstring.

  • All documentation files and docstrings should be linted and formatted by docstrfmt.

  • Use correct terminology. A subreddit’s fullname is something like t5_xyfc7. The correct term for a subreddit’s “name” like python for r/python is its display name.

Static Checker

PRAW’s test suite comes with a checker tool that can warn you of using incorrect documentation styles (using .. code:: instead of .. code-block::, using /r/ instead of r/, etc.). This is run automatically by the pre-commit hooks and the pre_push.py script.

class tools.static_word_checks.StaticChecker(replace: bool)

Run simple checks on the entire document or specific lines.

__init__(replace: bool)

Initialize a StaticChecker instance.

Parameters

replace – Whether or not to make replacements.

check_for_double_syntax(filename: str, content: str) bool

Checks a file for double-slash statements (/r/ and /u/).

Parameters
  • filename – The name of the file to check & replace.

  • content – The content of the file.

Returns

A boolean with the status of the check.

check_for_noreturn(filename: str, line_number: int, content: str) bool

Checks a line for NoReturn statements.

Parameters
  • filename – The name of the file to check & replace.

  • line_number – The line number.

  • content – The content of the line.

Returns

A boolean with the status of the check.

run_checks() bool

Scan a directory and run the checks.

The directory is assumed to be the praw directory located in the parent directory of the file, so if this file exists in ~/praw/tools/static_word_checks.py, it will check ~/praw/praw.

It runs the checks located in the self.full_file_checks and self.line_checks lists, with full file checks being run first.

Full-file checks are checks that can also fix the errors they find, while the line checks can just warn about found errors.

Files to Update

AUTHORS.rst

For your first contribution, please add yourself to the end of the respective list in the AUTHORS.rst file.

CHANGES.rst

For feature additions, bugfixes, or code removal please add an appropriate entry to CHANGES.rst. If the Unreleased section does not exist at the top of CHANGES.rst please add it. See commit 280525c16ba28cdd69cdbb272a0e2764b1c7e6a0 for an example.

See Also

Please also read the Contributing Guidelines

Glossary

  • Access Token: A temporary token to allow access to the Reddit API. Lasts for one hour.

  • Creddit: Back when the only award was Reddit Gold, a creddit was equal to one month of Reddit Gold. Creddits have been converted to Reddit Coins. See this for more info about the old Reddit Gold system.

  • Fullname: The fullname of an object is the object’s type followed by an underscore and its base-36 id. An example would be t3_1h4f3, where the t3 signals that it is a Submission, and the submission ID is 1h4f3.

    Here is a list of the six different types of objects returned from Reddit:

    • t1 These object represent Comments.

    • t4 These object represent Messages.

    • t6 These object represent Awards, such as Reddit Gold or Reddit Silver.

  • Gild: Back when the only award was Reddit Gold, gilding a post meant awarding one month of Reddit Gold. Currently, gilding means awarding one month of Reddit Platinum, or giving a Platinum award.

  • Websocket: A special connection type that supports both a client and a server (the running program and Reddit respectively) sending multiple messages to each other. Reddit uses websockets to notify clients when an image or video submission is completed, as well as certain types of asset uploads, such as subreddit banners.

Migrating to PRAW 7.X

Exception Handling

Class APIException has also been renamed to RedditAPIException. Importing APIException will still work, but is deprecated, but will be removed in PRAW 8.0.

PRAW 7 introduced a fundamental change in how exceptions are received from Reddit’s API. Reddit can return multiple exceptions for one API action, and as such, the exception RedditAPIException serves as a container for each of the true exception objects. These objects are instances of RedditErrorItem, and they contain the information of one “error” from Reddit’s API. They have the three data attributes that APIException used to contain.

Most code regarding exceptions can be quickly fixed to work under the new system. All of the exceptions are stored in the items attribute of the exception as entries in a list. In the example code below, observe how attributes are accessed.

try:
    reddit.subreddit("test").submit("Test Title", url="invalidurl")
except APIException as exception:
    print(exception.error_type)

This can generally be changed to:

try:
    reddit.subreddit("test").submit("Test Title", url="invalidurl")
except RedditAPIException as exception:
    print(exception.items[0].error_type)

However, this should not be done, as this will only work for one error. The probability of Reddit’s API returning multiple exceptions, especially on submit actions, should be addressed. Rather, iterate over the exception, and do the action on each item in the iterator.

try:
    reddit.subreddit("test").submit("Test Title", url="invalidurl")
except RedditAPIException as exception:
    for subexception in exception.items:
        print(subexception.error_type)

Alternatively, the exceptions are provided to the exception constructor, so printing the exception directly will also allow you to see all the exceptions.

try:
    reddit.subreddit("test").submit("Test Title", url="invalidurl")
except RedditAPIException as exception:
    print(exception)

References

Sponsors

Nuclei

Index