Python Reddit API Wrapper - simple access to Reddit's API
—
PRAW provides comprehensive moderation capabilities for Reddit communities including content moderation, user management, subreddit configuration, moderation logs, queues, and advanced moderator tools. These features enable effective community management and content curation.
Moderate Reddit submissions with approval, removal, and advanced moderation actions.
class SubmissionModeration:
def __init__(self, submission): ...
def approve(self):
"""
Approve the submission.
Removes from moderation queue and makes visible to users.
"""
def remove(self, *, mod_note: str = None, spam: bool = None):
"""
Remove the submission.
Parameters:
- mod_note: Internal moderator note (visible to other mods)
- spam: Whether to mark as spam (trains spam filter)
"""
def spam(self):
"""
Mark submission as spam.
Equivalent to remove(spam=True). Trains Reddit's spam filter.
"""
def distinguish(self, *, how: str = "yes", sticky: bool = False):
"""
Distinguish the submission (moderator only).
Parameters:
- how: Distinguish type ("yes", "no", "admin", "special")
- sticky: Pin to top of subreddit
"""
def undistinguish(self):
"""Remove distinguish from submission."""
def ignore_reports(self):
"""Ignore future reports on this submission."""
def unignore_reports(self):
"""Stop ignoring reports on this submission."""
def lock(self):
"""Lock submission (prevent new comments)."""
def unlock(self):
"""Unlock submission (allow new comments)."""
def nsfw(self):
"""Mark submission as NSFW."""
def sfw(self):
"""Mark submission as SFW (not NSFW)."""
def spoiler(self):
"""Mark submission as spoiler."""
def unspoiler(self):
"""Remove spoiler mark from submission."""
def contest_mode(self, *, state: bool = True):
"""
Enable or disable contest mode.
Parameters:
- state: True to enable, False to disable
Contest mode randomizes comment order and hides scores.
"""
def sticky(self, *, state: bool = True, bottom: bool = True):
"""
Sticky or unsticky the submission.
Parameters:
- state: True to sticky, False to unsticky
- bottom: Sticky to bottom slot (False for top slot)
"""
def suggested_sort(self, sort: str = "blank"):
"""
Set suggested comment sort order.
Parameters:
- sort: Sort order ("confidence", "top", "new", "controversial",
"old", "random", "qa", "live", "blank" to clear)
"""
def flair(
self,
text: str = None,
css_class: str = None,
flair_template_id: str = None
):
"""
Set submission flair.
Parameters:
- text: Flair text
- css_class: CSS class for styling
- flair_template_id: Template ID for predefined flair
"""
def create_note(
self,
*,
note: str,
thing = None,
**kwargs
):
"""
Create moderator note for submission.
Parameters:
- note: Note content
- thing: Associated object (comment, etc.)
"""Moderate Reddit comments with approval, removal, and distinguishing capabilities.
class CommentModeration:
def __init__(self, comment): ...
def approve(self):
"""
Approve the comment.
Removes from moderation queue and makes visible to users.
"""
def remove(self, *, mod_note: str = None, spam: bool = None):
"""
Remove the comment.
Parameters:
- mod_note: Internal moderator note (visible to other mods)
- spam: Whether to mark as spam (trains spam filter)
"""
def spam(self):
"""
Mark comment as spam.
Equivalent to remove(spam=True). Trains Reddit's spam filter.
"""
def distinguish(self, *, how: str = "yes", sticky: bool = False):
"""
Distinguish the comment.
Parameters:
- how: Distinguish type ("yes", "no", "admin", "special")
- sticky: Pin to top of comment thread
"""
def undistinguish(self):
"""Remove distinguish from comment."""
def ignore_reports(self):
"""Ignore future reports on this comment."""
def unignore_reports(self):
"""Stop ignoring reports on this comment."""
def lock(self):
"""Lock comment thread (prevent replies)."""
def unlock(self):
"""Unlock comment thread (allow replies)."""
def show(self):
"""Make comment visible (if hidden due to low score)."""
def create_note(
self,
*,
note: str,
thing = None,
**kwargs
):
"""
Create moderator note for comment.
Parameters:
- note: Note content
- thing: Associated object
"""Comprehensive subreddit management and moderation capabilities.
class SubredditModeration:
def __init__(self, subreddit): ...
def accept_moderator_invite(self):
"""Accept pending moderator invitation."""
def approve(self, thing):
"""
Approve submission or comment.
Parameters:
- thing: Submission or Comment instance to approve
"""
def remove(
self,
thing,
*,
mod_note: str = None,
spam: bool = None
):
"""
Remove submission or comment.
Parameters:
- thing: Submission or Comment instance to remove
- mod_note: Internal moderator note
- spam: Whether to mark as spam
"""
def spam(self, thing):
"""
Mark content as spam.
Parameters:
- thing: Submission or Comment instance to mark as spam
"""
def distinguish(
self,
thing,
*,
how: str = "yes",
sticky: bool = False
):
"""
Distinguish content as moderator.
Parameters:
- thing: Submission or Comment instance to distinguish
- how: Distinguish type ("yes", "no", "admin", "special")
- sticky: Pin content
"""
def ignore_reports(self, thing):
"""
Ignore reports on content.
Parameters:
- thing: Submission or Comment instance
"""
def unignore_reports(self, thing):
"""
Stop ignoring reports on content.
Parameters:
- thing: Submission or Comment instance
"""
def notes(self, **kwargs):
"""
Get moderator notes.
Parameters:
- limit: Number of notes (default: 25, max: 100)
- params: Additional query parameters
Returns:
ListingGenerator of moderator notes
"""
def create_note(
self,
*,
redditor,
note: str,
thing = None,
**kwargs
):
"""
Create moderator note.
Parameters:
- redditor: Redditor instance or username
- note: Note content
- thing: Associated submission/comment
"""Access various moderation queues and activity logs.
def log(self, **kwargs):
"""
Get moderation log entries.
Parameters:
- limit: Number of entries (default: 25, max: 100)
- mod: Filter by moderator username
- action: Filter by action type
- params: Additional query parameters
Returns:
ListingGenerator of ModAction instances
"""
def queue(self, **kwargs):
"""
Get moderation queue (reported/flagged content).
Parameters:
- limit: Number of items (default: 25, max: 100)
- only: Filter by type ("submissions", "comments")
- params: Additional query parameters
Returns:
ListingGenerator of Submission/Comment instances requiring moderation
"""
def reports(self, **kwargs):
"""
Get reported content.
Parameters:
- limit: Number of items (default: 25, max: 100)
- only: Filter by type ("submissions", "comments")
- params: Additional query parameters
Returns:
ListingGenerator of reported Submission/Comment instances
"""
def spam(self, **kwargs):
"""
Get spam queue.
Parameters:
- limit: Number of items (default: 25, max: 100)
- only: Filter by type ("submissions", "comments")
- params: Additional query parameters
Returns:
ListingGenerator of spam-filtered Submission/Comment instances
"""
def modqueue(self, **kwargs):
"""
Get items requiring moderator attention.
Parameters:
- limit: Number of items (default: 25, max: 100)
- only: Filter by type ("submissions", "comments")
- params: Additional query parameters
Returns:
ListingGenerator of items needing moderation
"""
def unmoderated(self, **kwargs):
"""
Get unmoderated submissions.
Parameters:
- limit: Number of submissions (default: 25, max: 100)
- params: Additional query parameters
Returns:
ListingGenerator of unmoderated Submission instances
"""
def edited(self, **kwargs):
"""
Get recently edited content.
Parameters:
- limit: Number of items (default: 25, max: 100)
- only: Filter by type ("submissions", "comments")
- params: Additional query parameters
Returns:
ListingGenerator of edited Submission/Comment instances
"""Manage subreddit users including banning, muting, and role assignments.
def banned(self, **kwargs):
"""
Get banned users list.
Parameters:
- limit: Number of users (default: 25, max: 100)
- params: Additional query parameters
Returns:
ListingGenerator of banned Redditor instances with ban info
"""
def muted(self, **kwargs):
"""
Get muted users list.
Parameters:
- limit: Number of users (default: 25, max: 100)
- params: Additional query parameters
Returns:
ListingGenerator of muted Redditor instances
"""
def wiki_banned(self, **kwargs):
"""
Get wiki-banned users list.
Parameters:
- limit: Number of users (default: 25, max: 100)
- params: Additional query parameters
Returns:
ListingGenerator of wiki-banned Redditor instances
"""
def contributors(self, **kwargs):
"""
Get approved submitters list.
Parameters:
- limit: Number of users (default: 25, max: 100)
- params: Additional query parameters
Returns:
ListingGenerator of contributor Redditor instances
"""
def wiki_contributors(self, **kwargs):
"""
Get wiki contributors list.
Parameters:
- limit: Number of users (default: 25, max: 100)
- params: Additional query parameters
Returns:
ListingGenerator of wiki contributor Redditor instances
"""
def moderators(self, **kwargs):
"""
Get moderators list.
Parameters:
- params: Additional query parameters
Returns:
ModeratorListing of moderator Redditor instances with permissions
"""Perform moderation actions on users.
def ban(
self,
redditor,
*,
ban_reason: str = None,
ban_message: str = None,
duration: int = None,
mod_note: str = None
):
"""
Ban a user from the subreddit.
Parameters:
- redditor: Redditor instance or username
- ban_reason: Public ban reason
- ban_message: Private message to banned user
- duration: Ban duration in days (None for permanent)
- mod_note: Internal moderator note
"""
def unban(self, redditor):
"""
Unban a user from the subreddit.
Parameters:
- redditor: Redditor instance or username
"""
def mute(self, redditor, *, mod_note: str = None):
"""
Mute a user (prevent modmail messages).
Parameters:
- redditor: Redditor instance or username
- mod_note: Internal moderator note
"""
def unmute(self, redditor):
"""
Unmute a user (allow modmail messages).
Parameters:
- redditor: Redditor instance or username
"""
def contributor_add(self, redditor):
"""
Add user as approved submitter.
Parameters:
- redditor: Redditor instance or username
"""
def contributor_remove(self, redditor):
"""
Remove user from approved submitters.
Parameters:
- redditor: Redditor instance or username
"""
def moderator_add(
self,
redditor,
*,
permissions: list = None
):
"""
Add user as moderator.
Parameters:
- redditor: Redditor instance or username
- permissions: List of permissions to grant
"""
def moderator_remove(self, redditor):
"""
Remove user as moderator.
Parameters:
- redditor: Redditor instance or username
"""
def moderator_invite(
self,
redditor,
*,
permissions: list = None
):
"""
Invite user to be moderator.
Parameters:
- redditor: Redditor instance or username
- permissions: List of permissions to grant
"""Manage subreddit configuration and settings.
def settings(self):
"""
Get current subreddit settings.
Returns:
Dictionary with subreddit configuration
"""
def update(self, **settings):
"""
Update subreddit settings.
Parameters:
- title: Subreddit title
- public_description: Short description
- description: Full description (markdown)
- submission_type: "any", "link", "self"
- subreddit_type: "public", "private", "restricted"
- over_18: NSFW subreddit
- allow_images: Allow image posts
- allow_videos: Allow video posts
- allow_polls: Allow poll posts
- spoilers_enabled: Enable spoiler tags
- suggested_comment_sort: Default comment sort
- collapse_deleted_comments: Collapse deleted comments
- comment_score_hide_mins: Minutes to hide comment scores
- exclude_banned_modqueue: Exclude banned users from modqueue
- spam_links: Spam filter strength for links
- spam_selfposts: Spam filter strength for self posts
- spam_comments: Spam filter strength for comments
- wiki_edit_age: Minimum account age to edit wiki
- wiki_edit_karma: Minimum karma to edit wiki
- wikimode: Wiki mode ("disabled", "modonly", "anyone")
"""Manage removal reasons for consistent moderation messaging.
class RemovalReason:
"""Removal reason template."""
def __init__(self, subreddit, id: str = None): ...
def delete(self):
"""Delete this removal reason."""
def update(self, **kwargs):
"""Update removal reason properties."""
def removal_reasons(self):
"""
Get removal reasons list.
Returns:
List of RemovalReason instances
"""
def create_removal_reason(
self,
message: str,
title: str,
**kwargs
):
"""
Create new removal reason.
Parameters:
- message: Removal message template
- title: Reason title/name
"""Handle modern modmail conversations and actions.
def modmail_conversations(self, **kwargs):
"""
Get modmail conversations for subreddit.
Parameters:
- limit: Number of conversations (default: 25, max: 100)
- sort: Sort order ("recent", "mod", "user", "unread")
- state: Filter by state (0=new, 1=in_progress, 2=archived, etc.)
Returns:
ListingGenerator of ModmailConversation instances
"""
def create_modmail_conversation(
self,
subject: str,
body: str,
recipient: str,
**kwargs
):
"""
Create new modmail conversation.
Parameters:
- subject: Conversation subject
- body: Initial message content
- recipient: Username to start conversation with
"""Reddit moderator permission types and management.
# Available moderator permissions
MODERATOR_PERMISSIONS = [
"access", # Access moderation tools
"config", # Manage settings and sidebar
"flair", # Manage flair
"mail", # Access modmail
"posts", # Approve/remove posts and comments
"wiki", # Manage wiki
"all" # All permissions
]
# Permission management in moderator actions
def invite_moderator_with_permissions():
subreddit.moderator_invite(
"new_moderator",
permissions=["posts", "flair", "mail"]
)import praw
reddit = praw.Reddit(...)
subreddit = reddit.subreddit("mysubreddit")
# Process moderation queue
print("Processing moderation queue:")
for item in subreddit.mod.queue(limit=20):
print(f"Reported: {item.title if hasattr(item, 'title') else item.body[:50]}")
print(f"Reports: {item.num_reports}")
# Auto-approve items with low report count from trusted users
if item.num_reports <= 2 and item.author.comment_karma > 1000:
item.mod.approve()
print(f"Auto-approved post by {item.author}")
# Remove obvious spam
if "spam" in str(item.title).lower() or "spam" in str(item.body).lower():
item.mod.remove(spam=True, mod_note="Obvious spam content")
print(f"Removed spam by {item.author}")
# Process reports
print("\nProcessing reports:")
for item in subreddit.mod.reports(limit=15):
print(f"Reported item by {item.author}: {item.num_reports} reports")
# Manual review required for multiple reports
if item.num_reports >= 3:
print("Manual review needed - multiple reports")# Ban management
def moderate_user(username, action, reason=None):
user = reddit.redditor(username)
if action == "ban":
subreddit.banned.add(
user,
ban_reason="Rule violation",
ban_message=f"You have been banned for: {reason}",
duration=7, # 7-day ban
mod_note=f"Banned by bot: {reason}"
)
print(f"Banned {username} for 7 days")
elif action == "mute":
subreddit.muted.add(user, mod_note=f"Muted: {reason}")
print(f"Muted {username}")
elif action == "unban":
subreddit.banned.remove(user)
print(f"Unbanned {username}")
# Check banned users
print("Banned users:")
for banned_user in subreddit.banned(limit=10):
print(f"Banned: {banned_user.name}")
print(f"Reason: {banned_user.ban_reason}")
print(f"Duration: {banned_user.days_left} days left")
# Manage contributors
trusted_users = ["user1", "user2", "user3"]
for username in trusted_users:
subreddit.contributor.add(reddit.redditor(username))
print(f"Added {username} as contributor")import re
def automated_content_moderation():
"""Automated moderation based on rules."""
# Spam patterns
spam_patterns = [
r"click here",
r"free money",
r"buy now",
r"limited time"
]
# Check new submissions
for submission in subreddit.new(limit=50):
# Skip if already moderated
if hasattr(submission, 'approved_by') and submission.approved_by:
continue
# Check for spam patterns
text_to_check = f"{submission.title} {submission.selftext}".lower()
is_spam = any(re.search(pattern, text_to_check) for pattern in spam_patterns)
if is_spam:
submission.mod.remove(
spam=True,
mod_note="Auto-removed: spam pattern detected"
)
print(f"Auto-removed spam: {submission.title}")
continue
# Auto-approve from trusted users
if submission.author.comment_karma > 5000 and submission.author.link_karma > 1000:
submission.mod.approve()
print(f"Auto-approved trusted user: {submission.author}")
# Flair enforcement
if not submission.link_flair_text and subreddit.display_name in ["programming", "askreddit"]:
submission.mod.remove(mod_note="No flair - auto-removed")
submission.reply(
"Your post was removed because it doesn't have flair. "
"Please add appropriate flair and resubmit."
)
print(f"Removed for missing flair: {submission.title}")
automated_content_moderation()from collections import defaultdict
import datetime
def analyze_moderation_activity():
"""Analyze moderation patterns."""
mod_actions = defaultdict(int)
mod_activity = defaultdict(int)
# Analyze moderation log
for action in subreddit.mod.log(limit=1000):
mod_actions[action.action] += 1
mod_activity[action.mod.name] += 1
print(f"{action.created_utc}: {action.mod} - {action.action}")
if hasattr(action, 'target_title'):
print(f" Target: {action.target_title}")
# Print statistics
print("\nModeration Actions Summary:")
for action, count in sorted(mod_actions.items(), key=lambda x: x[1], reverse=True):
print(f"{action}: {count}")
print("\nModerator Activity:")
for mod, count in sorted(mod_activity.items(), key=lambda x: x[1], reverse=True):
print(f"{mod}: {count} actions")
analyze_moderation_activity()def process_all_queues():
"""Process all moderation queues systematically."""
# Process spam queue
print("Processing spam queue:")
for item in subreddit.mod.spam(limit=50):
# Double-check if it's actually spam
if item.author.comment_karma < -10: # Negative karma user
item.mod.remove(spam=True)
print(f"Confirmed spam removal: {item.author}")
else:
# Might be false positive, approve
item.mod.approve()
print(f"Approved false positive: {item.author}")
# Process unmoderated queue
print("\nProcessing unmoderated:")
for submission in subreddit.mod.unmoderated(limit=30):
# Basic quality check
if len(submission.title) < 10:
submission.mod.remove(mod_note="Title too short")
elif submission.author.link_karma > 100:
submission.mod.approve()
else:
# Needs manual review
print(f"Manual review needed: {submission.title}")
# Process edited content
print("\nChecking edited content:")
for item in subreddit.mod.edited(limit=20):
# Re-check edited content for rule violations
if hasattr(item, 'selftext') and len(item.selftext) > 5000:
print(f"Long edited post needs review: {item.title}")
process_all_queues()# Create standard removal reasons
def setup_removal_reasons():
"""Set up standard removal reasons."""
reasons = [
{
"title": "Low Quality",
"message": "Your post was removed for being low quality. Please see our posting guidelines."
},
{
"title": "Rule 1 - Be Civil",
"message": "Your comment was removed for violating Rule 1: Be Civil. Personal attacks are not allowed."
},
{
"title": "Spam",
"message": "Your post was removed as spam. Self-promotion should be limited to 10% of your activity."
}
]
for reason_data in reasons:
try:
subreddit.mod.create_removal_reason(**reason_data)
print(f"Created removal reason: {reason_data['title']}")
except Exception as e:
print(f"Failed to create reason: {e}")
# Use removal reasons when moderating
def moderate_with_reasons():
for item in subreddit.mod.queue(limit=10):
if item.num_reports >= 2:
# Get appropriate removal reason
reasons = subreddit.mod.removal_reasons()
spam_reason = next((r for r in reasons if "spam" in r.title.lower()), None)
if spam_reason and "buy" in item.selftext.lower():
item.mod.remove(mod_note=f"Used reason: {spam_reason.title}")
print(f"Removed with spam reason: {item.title}")class ModAction:
"""Moderation log entry."""
id: str # Action ID
action: str # Action type ("approve", "remove", "ban", etc.)
mod: Redditor # Moderator who performed action
target_author: str # Target user (for user actions)
target_title: str # Target content title
target_permalink: str # Target content link
created_utc: float # Action timestamp (UTC)
subreddit: Subreddit # Subreddit where action occurred
details: str # Additional action details
class ModmailConversation:
"""Modern modmail conversation."""
id: str # Conversation ID
subject: str # Conversation subject
participant: Redditor # Main participant (non-moderator)
authors: list # All conversation participants
state: int # Conversation state
last_updated: str # Last update timestamp
is_highlighted: bool # Whether highlighted
num_messages: int # Number of messages
class ThingModerationMixin:
"""Base moderation capabilities."""
def approve(self):
"""Approve the item."""
def remove(self, **kwargs):
"""Remove the item."""
def spam(self):
"""Mark as spam."""
def ignore_reports(self):
"""Ignore reports."""
def unignore_reports(self):
"""Stop ignoring reports."""
class ModNoteMixin:
"""Moderator note capabilities."""
def create_note(self, **kwargs):
"""Create moderator note."""Install with Tessl CLI
npx tessl i tessl/pypi-praw