Discord API (discord.py)
Community-maintained Python wrapper for the Discord API. Current version is 2.7.1 (Mar 2026). PyPI package is 'discord.py' (with dot), imports as 'discord'. Note: 'pip install discord' installs a mirror stub that redirects to discord.py — always install discord.py directly. The library was abandoned in 2021 and resumed in 2022 with a full v2 rewrite; vast amounts of pre-v2 tutorial code is broken.
Warnings
- breaking discord.py was abandoned Aug 2021 and resumed Aug 2022 with v2.0 — a near-complete rewrite. Any tutorial or code from 2021 or earlier is likely broken. v1.x and v2.x are not API-compatible.
- breaking Intents are mandatory in v2. Client() and Bot() constructors require an intents= argument. Omitting it raises: 'TypeError: __init__() missing 1 required keyword argument: intents'.
- breaking message_content is a Privileged Intent since Sep 2022. Without it, message.content is always empty string. Prefix commands silently stop working. Must be enabled BOTH in Developer Portal AND in code.
- breaking Slash commands (app commands) are not available via the old @bot.command() decorator. They require discord.app_commands.CommandTree or the @bot.tree.command() decorator introduced in v2.
- breaking client.run() is synchronous and blocks. Do not wrap it in asyncio.run() — this causes RuntimeError: This event loop is already running.
- gotcha pip install discord installs a mirror stub package that just re-exports discord.py. It may lag behind the real package version. Always install discord.py explicitly.
- gotcha Privileged Intents (message_content, members, presences) require Discord Developer Portal approval for bots in 100+ servers. Enabling in code alone is insufficient — the bot will connect but receive empty data silently.
- gotcha Third-party slash command libraries (discord-py-slash-command, discord-interactions) were built for v1.x. They conflict with v2.x which has native app_commands support. Remove them before upgrading.
Install
-
pip install discord.py -
pip install "discord.py[voice]"
Imports
- discord
import discord from discord.ext import commands
Quickstart
import discord
from discord.ext import commands
# Intents are REQUIRED in v2 — no defaults silently work
intents = discord.Intents.default()
intents.message_content = True # privileged intent — must enable in Dev Portal too
bot = commands.Bot(command_prefix='!', intents=intents)
@bot.command()
async def ping(ctx):
await ctx.send('pong')
bot.run('YOUR_BOT_TOKEN')