A modern, async-ready Python API wrapper for Discord with comprehensive bot development features
Overall
score
93%
Extension modules providing command frameworks, hybrid commands, background tasks, and pagination utilities for building sophisticated Discord bots. These extensions offer powerful abstractions and tools for complex bot functionality.
Comprehensive command framework for prefix-based commands with argument parsing, checks, error handling, and cog organization.
# Import the commands extension
from discord.ext import commands
class Bot(commands.Bot):
"""
Enhanced bot class with command processing capabilities.
"""
def __init__(
self,
command_prefix: Union[str, Callable],
*,
help_command: Optional[HelpCommand] = None,
description: str = None,
case_insensitive: bool = False,
strip_after_prefix: bool = False,
owner_id: int = None,
owner_ids: Set[int] = None,
**options
) -> None:
"""
Create a commands bot.
Parameters:
- command_prefix: Union[str, Callable] - Prefix for commands
- help_command: HelpCommand - Custom help command implementation
- description: str - Bot description for help
- case_insensitive: bool - Whether commands are case-insensitive
- strip_after_prefix: bool - Strip whitespace after prefix
- owner_id: int - Bot owner user ID
- owner_ids: Set[int] - Set of bot owner user IDs
"""
def command(
self,
name: str = None,
*,
cls: Type[Command] = None,
**attrs
) -> Callable:
"""
Decorator to create a command.
Parameters:
- name: str - Command name (defaults to function name)
- cls: Type[Command] - Command class to use
"""
def group(
self,
name: str = None,
*,
cls: Type[Group] = None,
**attrs
) -> Callable:
"""
Decorator to create a command group.
Parameters:
- name: str - Group name (defaults to function name)
- cls: Type[Group] - Group class to use
"""
async def get_prefix(self, message: Message) -> Union[List[str], str]:
"""Get the prefix for a message."""
async def get_context(
self,
origin: Union[Message, Interaction],
*,
cls: Type[Context] = None
) -> Context:
"""Get the context for a message or interaction."""
async def invoke(self, ctx: Context) -> None:
"""Invoke a command from context."""
async def process_commands(self, message: Message) -> None:
"""Process commands from a message."""
def add_command(self, command: Command) -> None:
"""Add a command to the bot."""
def remove_command(self, name: str) -> Optional[Command]:
"""Remove a command from the bot."""
def get_command(self, name: str) -> Optional[Command]:
"""Get a command by name."""
@property
def commands(self) -> Set[Command]:
"""All commands registered to the bot."""
class AutoShardedBot(Bot):
"""Auto-sharded version of the commands bot."""
pass
def command(name: str = None, **kwargs) -> Callable:
"""
Decorator to create a command outside of a bot class.
Parameters:
- name: str - Command name
**kwargs: Command attributes
"""
def group(name: str = None, **kwargs) -> Callable:
"""
Decorator to create a command group outside of a bot class.
Parameters:
- name: str - Group name
**kwargs: Group attributes
"""
class Command:
"""
Represents a bot command.
"""
def __init__(
self,
func: Callable,
*,
name: str = None,
aliases: List[str] = None,
description: str = None,
brief: str = None,
usage: str = None,
help: str = None,
hidden: bool = False,
enabled: bool = True,
parent: Optional[Group] = None,
cog: Optional[Cog] = None,
checks: List[Callable] = None,
cooldown_after_parsing: bool = False,
**kwargs
) -> None: ...
@property
def name(self) -> str: ...
@property
def aliases(self) -> List[str]: ...
@property
def description(self) -> str: ...
@property
def brief(self) -> str: ...
@property
def usage(self) -> str: ...
@property
def help(self) -> str: ...
@property
def hidden(self) -> bool: ...
@property
def enabled(self) -> bool: ...
@property
def parent(self) -> Optional[Group]: ...
@property
def cog(self) -> Optional[Cog]: ...
@property
def checks(self) -> List[Callable]: ...
@property
def qualified_name(self) -> str: ...
@property
def signature(self) -> str: ...
def add_check(self, func: Callable) -> None:
"""Add a check to the command."""
def remove_check(self, func: Callable) -> None:
"""Remove a check from the command."""
async def invoke(self, ctx: Context) -> None:
"""Invoke the command."""
async def can_run(self, ctx: Context) -> bool:
"""Check if the command can run in the given context."""
class Group(Command):
"""
A command that can contain subcommands.
"""
def __init__(
self,
*,
invoke_without_subcommand: bool = False,
case_insensitive: bool = False,
**kwargs
) -> None: ...
@property
def commands(self) -> Set[Command]: ...
@property
def invoke_without_subcommand(self) -> bool: ...
@property
def case_insensitive(self) -> bool: ...
def command(self, *args, **kwargs) -> Callable:
"""Decorator to add a subcommand."""
def group(self, *args, **kwargs) -> Callable:
"""Decorator to add a subgroup."""
def add_command(self, command: Command) -> None: ...
def remove_command(self, name: str) -> Optional[Command]: ...
def get_command(self, name: str) -> Optional[Command]: ...
async def invoke(self, ctx: Context) -> None: ...
class Context:
"""
Represents the context for a command invocation.
"""
@property
def message(self) -> Message: ...
@property
def bot(self) -> Bot: ...
@property
def args(self) -> List[str]: ...
@property
def kwargs(self) -> Dict[str, Any]: ...
@property
def prefix(self) -> str: ...
@property
def command(self) -> Optional[Command]: ...
@property
def invoked_with(self) -> str: ...
@property
def invoked_parents(self) -> List[str]: ...
@property
def invoked_subcommand(self) -> Optional[Command]: ...
@property
def subcommand_passed(self) -> Optional[str]: ...
@property
def command_failed(self) -> bool: ...
@property
def author(self) -> Union[User, Member]: ...
@property
def guild(self) -> Optional[Guild]: ...
@property
def channel(self) -> Union[GuildChannel, DMChannel, PartialMessageable]: ...
@property
def me(self) -> Union[Member, ClientUser]: ...
@property
def voice_client(self) -> Optional[VoiceProtocol]: ...
@property
def valid(self) -> bool: ...
@property
def clean_prefix(self) -> str: ...
@property
def cog(self) -> Optional[Cog]: ...
async def invoke(self, command: Command, /, *args, **kwargs) -> None:
"""Invoke another command."""
async def reinvoke(self, *, call_hooks: bool = False, restart: bool = True) -> None:
"""Reinvoke the current command."""
async def send(
self,
content: str = None,
*,
tts: bool = False,
embed: Embed = None,
embeds: List[Embed] = None,
file: File = None,
files: List[File] = None,
view: View = None,
reference: Union[Message, MessageReference, PartialMessage] = None,
mention_author: bool = None,
allowed_mentions: AllowedMentions = None,
suppress_embeds: bool = False,
ephemeral: bool = False,
silent: bool = False,
**kwargs
) -> Message:
"""Send a message to the context channel."""
async def reply(self, *args, **kwargs) -> Message:
"""Reply to the context message."""
def typing(self) -> Typing:
"""Trigger typing indicator in the channel."""Decorators and functions for controlling command access and execution.
def check(predicate: Callable[[Context], bool]) -> Callable:
"""
Decorator to add a check to a command.
Parameters:
- predicate: Callable - Function that returns True if check passes
"""
def check_any(*checks: Callable) -> Callable:
"""
Require any of the given checks to pass.
Parameters:
*checks: Check functions
"""
def has_role(item: Union[int, str, Role]) -> Callable:
"""
Check if user has a specific role.
Parameters:
- item: Union[int, str, Role] - Role ID, name, or object
"""
def has_any_role(*items: Union[int, str, Role]) -> Callable:
"""
Check if user has any of the specified roles.
Parameters:
*items: Role IDs, names, or objects
"""
def has_permissions(**perms) -> Callable:
"""
Check if user has specific permissions.
Parameters:
**perms: Permission flags to check
"""
def has_guild_permissions(**perms) -> Callable:
"""
Check if user has guild-level permissions.
Parameters:
**perms: Permission flags to check
"""
def bot_has_role(item: Union[int, str, Role]) -> Callable:
"""Check if bot has a specific role."""
def bot_has_any_role(*items: Union[int, str, Role]) -> Callable:
"""Check if bot has any of the specified roles."""
def bot_has_permissions(**perms) -> Callable:
"""Check if bot has specific permissions."""
def bot_has_guild_permissions(**perms) -> Callable:
"""Check if bot has guild-level permissions."""
def is_owner() -> Callable:
"""Check if user is the bot owner."""
def is_nsfw() -> Callable:
"""Check if channel is NSFW."""
def dm_only() -> Callable:
"""Restrict command to DMs only."""
def guild_only() -> Callable:
"""Restrict command to guilds only."""System for managing command cooldowns and concurrency limits.
def cooldown(
rate: int,
per: float,
type: BucketType = BucketType.default
) -> Callable:
"""
Add a cooldown to a command.
Parameters:
- rate: int - Number of times the command can be used
- per: float - Time period in seconds
- type: BucketType - Cooldown bucket type
"""
def dynamic_cooldown(
cooldown: Callable[[Context], Optional[Cooldown]],
type: BucketType = BucketType.default
) -> Callable:
"""
Add a dynamic cooldown to a command.
Parameters:
- cooldown: Callable - Function that returns cooldown or None
- type: BucketType - Cooldown bucket type
"""
def max_concurrency(
number: int,
*,
per: BucketType = BucketType.default,
wait: bool = False
) -> Callable:
"""
Limit concurrent usage of a command.
Parameters:
- number: int - Maximum concurrent uses
- per: BucketType - Concurrency bucket type
- wait: bool - Whether to wait for availability
"""
class BucketType(Enum):
"""Cooldown bucket types."""
default = 0
user = 1
guild = 2
channel = 3
member = 4
category = 5
role = 6
class Cooldown:
"""Represents a command cooldown."""
def __init__(self, rate: int, per: float) -> None: ...
@property
def rate(self) -> int: ...
@property
def per(self) -> float: ...
def get_tokens(self, current: float = None) -> int:
"""Get available tokens."""
def get_retry_after(self, current: float = None) -> float:
"""Get retry after time."""
def update_rate_limit(self, current: float = None) -> Optional[float]:
"""Update rate limit and get retry after."""
def reset(self) -> None:
"""Reset the cooldown."""
def copy(self) -> Cooldown:
"""Create a copy of the cooldown."""
class CooldownMapping:
"""Maps cooldowns to different entities."""
def __init__(self, original: Cooldown, type: BucketType) -> None: ...
def copy(self) -> CooldownMapping: ...
def get_bucket(self, message: Message, current: float = None) -> Cooldown: ...
def update_rate_limit(self, message: Message, current: float = None) -> Optional[float]: ...
class MaxConcurrency:
"""Limits concurrent command usage."""
def __init__(self, number: int, *, per: BucketType, wait: bool) -> None: ...
@property
def number(self) -> int: ...
@property
def per(self) -> BucketType: ...
@property
def wait(self) -> bool: ...
def get_key(self, message: Message) -> Any: ...
async def acquire(self, message: Message) -> None: ...
async def release(self, message: Message) -> None: ...System for converting command arguments to appropriate types.
class Converter:
"""Base class for argument converters."""
async def convert(self, ctx: Context, argument: str) -> Any:
"""
Convert a string argument to the desired type.
Parameters:
- ctx: Context - Command context
- argument: str - String argument to convert
Returns:
Any - Converted value
"""
class UserConverter(Converter):
"""Convert arguments to User objects."""
async def convert(self, ctx: Context, argument: str) -> User: ...
class MemberConverter(Converter):
"""Convert arguments to Member objects."""
async def convert(self, ctx: Context, argument: str) -> Member: ...
class TextChannelConverter(Converter):
"""Convert arguments to TextChannel objects."""
async def convert(self, ctx: Context, argument: str) -> TextChannel: ...
class VoiceChannelConverter(Converter):
"""Convert arguments to VoiceChannel objects."""
async def convert(self, ctx: Context, argument: str) -> VoiceChannel: ...
class CategoryChannelConverter(Converter):
"""Convert arguments to CategoryChannel objects."""
async def convert(self, ctx: Context, argument: str) -> CategoryChannel: ...
class ForumChannelConverter(Converter):
"""Convert arguments to ForumChannel objects."""
async def convert(self, ctx: Context, argument: str) -> ForumChannel: ...
class StageChannelConverter(Converter):
"""Convert arguments to StageChannel objects."""
async def convert(self, ctx: Context, argument: str) -> StageChannel: ...
class ThreadConverter(Converter):
"""Convert arguments to Thread objects."""
async def convert(self, ctx: Context, argument: str) -> Thread: ...
class GuildChannelConverter(Converter):
"""Convert arguments to any GuildChannel object."""
async def convert(self, ctx: Context, argument: str) -> GuildChannel: ...
class RoleConverter(Converter):
"""Convert arguments to Role objects."""
async def convert(self, ctx: Context, argument: str) -> Role: ...
class GuildConverter(Converter):
"""Convert arguments to Guild objects."""
async def convert(self, ctx: Context, argument: str) -> Guild: ...
class InviteConverter(Converter):
"""Convert arguments to Invite objects."""
async def convert(self, ctx: Context, argument: str) -> Invite: ...
class EmojiConverter(Converter):
"""Convert arguments to Emoji objects."""
async def convert(self, ctx: Context, argument: str) -> Emoji: ...
class PartialEmojiConverter(Converter):
"""Convert arguments to PartialEmoji objects."""
async def convert(self, ctx: Context, argument: str) -> PartialEmoji: ...
class ColourConverter(Converter):
"""Convert arguments to Colour objects."""
async def convert(self, ctx: Context, argument: str) -> Colour: ...
class ColorConverter(ColourConverter):
"""Alias for ColourConverter."""
pass
class GameConverter(Converter):
"""Convert arguments to Game activity objects."""
async def convert(self, ctx: Context, argument: str) -> Game: ...
class clean_content(Converter):
"""
Converter for cleaning message content.
Removes mentions, @everyone, @here, and other Discord formatting.
"""
def __init__(
self,
*,
fix_channel_mentions: bool = False,
use_nicknames: bool = True,
escape_markdown: bool = False,
remove_markdown: bool = False
) -> None: ...
async def convert(self, ctx: Context, argument: str) -> str: ...
class Greedy:
"""
Converter wrapper that consumes multiple arguments greedily.
Usage: def command(self, ctx, *, users: Greedy[Member])
"""
def __init__(self, converter: Any) -> None: ...
def run_converters(
ctx: Context,
converter: Any,
argument: str,
param: inspect.Parameter
) -> Any:
"""
Run the conversion process for an argument.
Parameters:
- ctx: Context - Command context
- converter: Any - Converter type or callable
- argument: str - Argument to convert
- param: Parameter - Parameter information
"""Organization system for grouping commands and event listeners.
class Cog:
"""
Base class for command cogs.
"""
def __init_subclass__(cls, **kwargs) -> None: ...
@property
def qualified_name(self) -> str:
"""The cog's qualified name."""
@property
def description(self) -> Optional[str]:
"""The cog's description."""
def get_commands(self) -> List[Command]:
"""Get all commands in this cog."""
def get_listeners(self) -> List[Tuple[str, Callable]]:
"""Get all event listeners in this cog."""
async def cog_load(self) -> None:
"""Called when the cog is loaded."""
async def cog_unload(self) -> None:
"""Called when the cog is unloaded."""
def cog_check(self, ctx: Context) -> bool:
"""Check that applies to all commands in this cog."""
async def cog_command_error(self, ctx: Context, error: Exception) -> None:
"""Error handler for commands in this cog."""
async def cog_before_invoke(self, ctx: Context) -> None:
"""Called before any command in this cog is invoked."""
async def cog_after_invoke(self, ctx: Context) -> None:
"""Called after any command in this cog is invoked."""
class CogMeta(type):
"""Metaclass for cogs."""
passHybrid commands that work as both slash commands and traditional prefix commands.
from discord.ext import bridge
class Bot(bridge.Bot):
"""Bot that supports both slash and prefix commands."""
def __init__(
self,
command_prefix: Union[str, Callable],
*,
debug_guilds: List[int] = None,
**options
) -> None: ...
def bridge_command(self, **kwargs) -> Callable:
"""Create a hybrid command that works as both slash and prefix."""
def bridge_group(self, **kwargs) -> Callable:
"""Create a hybrid command group."""
def bridge_command(**kwargs) -> Callable:
"""
Create a bridge command.
The decorated function will work as both a slash command and prefix command.
"""
def bridge_group(**kwargs) -> Callable:
"""Create a bridge command group."""
class BridgeContext:
"""Base context for bridge commands."""
@property
def bot(self) -> Bot: ...
@property
def command(self) -> BridgeCommand: ...
@property
def is_app(self) -> bool:
"""Whether this is an application command context."""
async def respond(self, *args, **kwargs) -> Union[Message, InteractionMessage]: ...
async def reply(self, *args, **kwargs) -> Message: ...
async def send(self, *args, **kwargs) -> Message: ...
async def edit(self, *args, **kwargs) -> Union[Message, InteractionMessage]: ...
async def defer(self, *args, **kwargs) -> None: ...
class BridgeExtContext(BridgeContext):
"""Context for prefix command execution."""
pass
class BridgeApplicationContext(BridgeContext):
"""Context for slash command execution."""
pass
class BridgeCommand:
"""Hybrid command that supports both slash and prefix."""
@property
def name(self) -> str: ...
@property
def description(self) -> str: ...
@property
def slash_command(self) -> SlashCommand: ...
@property
def ext_command(self) -> Command: ...
def add_to(self, bot: Bot) -> None: ...
class BridgeOption:
"""Option for bridge commands."""
def __init__(
self,
input_type: SlashCommandOptionType,
description: str,
*,
name: str = None,
**kwargs
) -> None: ...
def bridge_option(name: str, **kwargs) -> Callable:
"""Decorator for bridge command options."""Background task scheduling and management system.
from discord.ext import tasks
def loop(
*,
seconds: float = None,
minutes: float = None,
hours: float = None,
time: Union[datetime.time, List[datetime.time]] = None,
count: int = None,
reconnect: bool = True
) -> Callable:
"""
Decorator to create a background task loop.
Parameters:
- seconds: float - Interval in seconds
- minutes: float - Interval in minutes
- hours: float - Interval in hours
- time: Union[time, List[time]] - Specific time(s) to run
- count: int - Number of iterations (None for infinite)
- reconnect: bool - Whether to reconnect on network errors
"""
class Loop:
"""
Represents a background task loop.
"""
def __init__(
self,
coro: Callable,
*,
seconds: float = None,
minutes: float = None,
hours: float = None,
time: Union[datetime.time, List[datetime.time]] = None,
count: int = None,
reconnect: bool = True
) -> None: ...
@property
def current_loop(self) -> int:
"""Current iteration number."""
@property
def next_iteration(self) -> Optional[datetime]:
"""When the next iteration will occur."""
@property
def is_running(self) -> bool:
"""Whether the loop is running."""
@property
def failed(self) -> bool:
"""Whether the loop has failed."""
@property
def is_being_cancelled(self) -> bool:
"""Whether the loop is being cancelled."""
def start(self, *args, **kwargs) -> None:
"""Start the loop."""
def stop(self) -> None:
"""Stop the loop."""
def cancel(self) -> None:
"""Cancel the loop."""
def restart(self, *args, **kwargs) -> None:
"""Restart the loop."""
def change_interval(
self,
*,
seconds: float = None,
minutes: float = None,
hours: float = None
) -> None:
"""Change the loop interval."""
def before_loop(self, coro: Callable) -> Callable:
"""Decorator for function to run before the loop starts."""
def after_loop(self, coro: Callable) -> Callable:
"""Decorator for function to run after the loop ends."""
def error(self, coro: Callable) -> Callable:
"""Decorator for error handler."""Pagination utilities for creating multi-page messages with navigation.
from discord.ext import pages
class Paginator:
"""
Main paginator for handling multi-page content.
"""
def __init__(
self,
pages: List[Union[str, Embed, Dict]],
*,
show_disabled: bool = True,
show_indicator: bool = True,
author_check: bool = True,
disable_on_timeout: bool = True,
use_default_buttons: bool = True,
default_button_row: int = 0,
loop_pages: bool = False,
timeout: Optional[float] = 180.0,
custom_view: View = None,
**kwargs
) -> None:
"""
Create a paginator.
Parameters:
- pages: List - Content for each page
- show_disabled: bool - Show disabled navigation buttons
- show_indicator: bool - Show page number indicator
- author_check: bool - Only allow author to interact
- disable_on_timeout: bool - Disable buttons on timeout
- use_default_buttons: bool - Use default navigation buttons
- default_button_row: int - Row for default buttons
- loop_pages: bool - Loop from last page to first
- timeout: float - Interaction timeout
- custom_view: View - Custom view for additional components
"""
@property
def pages(self) -> List[Union[str, Embed, Dict]]: ...
@property
def current_page(self) -> int: ...
@property
def page_count(self) -> int: ...
def add_page(self, page: Union[str, Embed, Dict]) -> None:
"""Add a page to the paginator."""
def remove_page(self, page_number: int) -> None:
"""Remove a page from the paginator."""
def update_page(self, page_number: int, page: Union[str, Embed, Dict]) -> None:
"""Update a specific page."""
async def send(
self,
destination: Union[Context, Interaction, Messageable],
*,
ephemeral: bool = False,
**kwargs
) -> Union[Message, InteractionMessage]:
"""Send the paginator."""
async def edit(
self,
interaction: Interaction,
*,
suppress: bool = None
) -> InteractionMessage:
"""Edit the paginator message."""
def go_to_page(self, page_number: int) -> None:
"""Go to a specific page."""
def next_page(self) -> None:
"""Go to the next page."""
def previous_page(self) -> None:
"""Go to the previous page."""
class PaginatorButton:
"""
Navigation button for paginators.
"""
def __init__(
self,
button_type: str,
*,
label: str = None,
emoji: Union[str, Emoji, PartialEmoji] = None,
style: ButtonStyle = ButtonStyle.secondary,
disabled: bool = False,
custom_id: str = None,
row: int = None
) -> None: ...
class PageGroup:
"""
Group of related pages.
"""
def __init__(
self,
pages: List[Union[str, Embed, Dict]],
label: str,
*,
description: str = None,
emoji: Union[str, Emoji, PartialEmoji] = None,
use_default_buttons: bool = True,
default_button_row: int = 0,
custom_view: View = None
) -> None: ...
@property
def label(self) -> str: ...
@property
def description(self) -> Optional[str]: ...
@property
def emoji(self) -> Optional[Union[str, Emoji, PartialEmoji]]: ...
@property
def pages(self) -> List[Union[str, Embed, Dict]]: ...
class Page:
"""
Individual page content.
"""
def __init__(
self,
*,
content: str = None,
embeds: List[Embed] = None,
files: List[File] = None,
custom_view: View = None
) -> None: ...
@property
def content(self) -> Optional[str]: ...
@property
def embeds(self) -> List[Embed]: ...
@property
def files(self) -> List[File]: ...
@property
def custom_view(self) -> Optional[View]: ...Helper functions for managing command prefixes.
def when_mentioned(bot: Bot, message: Message) -> List[str]:
"""
Get prefixes when the bot is mentioned.
Parameters:
- bot: Bot - The bot instance
- message: Message - The message to get prefixes for
Returns:
List[str] - List of mention prefixes
"""
def when_mentioned_or(*prefixes: str) -> Callable[[Bot, Message], List[str]]:
"""
Combine mention prefixes with custom prefixes.
Parameters:
*prefixes: Custom prefixes to add
Returns:
Callable - Function that returns prefixes including mentions
"""The extensions system provides powerful frameworks and utilities for building sophisticated Discord bots with organized command structures, background tasks, interactive pagination, and hybrid command support that works across both traditional and modern Discord interfaces.
Install with Tessl CLI
npx tessl i tessl/pypi-py-corddocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10