CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-disnake

A modern, easy-to-use, feature-rich async-ready API wrapper for Discord written in Python

Pending
Overview
Eval results
Files

command-framework.mddocs/

Command Framework

Traditional message-based command framework with comprehensive command handling, argument parsing, permission checks, cooldowns, error handling, and organized command structure through cogs for text-based bot functionality.

Capabilities

Bot Classes

Command-enabled bot classes extending basic client functionality with message command processing.

class Bot(commands.BotBase, Client):
    def __init__(
        self,
        command_prefix: Union[str, Iterable[str], Callable[[Bot, Message], Union[str, Iterable[str]]]],
        *,
        help_command: Optional[commands.HelpCommand] = ...,
        description: Optional[str] = None,
        **options
    ):
        """
        Initialize a message command bot.
        
        Parameters:
        - command_prefix: Command prefix(es) or callable returning prefix(es)
        - help_command: Custom help command implementation
        - description: Bot description for help command
        - options: Additional client options
        """

    @property
    def commands(self) -> Set[commands.Command]:
        """All registered commands."""

    @property
    def cogs(self) -> Mapping[str, commands.Cog]:
        """All loaded cogs."""

    def add_command(self, command: commands.Command) -> None:
        """
        Add a command to the bot.
        
        Parameters:
        - command: Command to add
        """

    def remove_command(self, name: str) -> Optional[commands.Command]:
        """
        Remove a command by name.
        
        Parameters:
        - name: Command name
        
        Returns:
        Removed command if found
        """

    def get_command(self, name: str) -> Optional[commands.Command]:
        """
        Get a command by name.
        
        Parameters:
        - name: Command name (supports subcommands with spaces)
        
        Returns:
        Command if found
        """

    def walk_commands(self) -> Generator[commands.Command, None, None]:
        """
        Iterate over all commands including subcommands.
        
        Yields:
        All registered commands
        """

    async def get_prefix(self, message: Message) -> Union[List[str], str]:
        """
        Get command prefix for a message.
        
        Parameters:
        - message: Message to get prefix for
        
        Returns:
        Prefix or list of prefixes
        """

    async def get_context(self, message: Message, *, cls: Type[Context] = None) -> Context:
        """
        Get command context from a message.
        
        Parameters:
        - message: Message to create context from
        - cls: Custom context class
        
        Returns:
        Command context
        """

    async def process_commands(self, message: Message) -> None:
        """
        Process a message for commands.
        
        Parameters:
        - message: Message to process
        """

    async def invoke(self, ctx: commands.Context) -> None:
        """
        Invoke a command from context.
        
        Parameters:
        - ctx: Command context
        """

    def command(self, name: str = None, **kwargs):
        """
        Decorator for registering commands.
        
        Parameters:
        - name: Command name (optional)
        - kwargs: Command options
        """

    def group(self, name: str = None, **kwargs):
        """
        Decorator for registering command groups.
        
        Parameters:
        - name: Group name (optional)
        - kwargs: Group options
        """

    def listen(self, name: str = None):
        """
        Decorator for event listeners.
        
        Parameters:
        - name: Event name (optional)
        """

    def add_cog(self, cog: commands.Cog, *, override: bool = False) -> None:
        """
        Add a cog to the bot.
        
        Parameters:
        - cog: Cog instance to add
        - override: Whether to override existing commands
        """

    def remove_cog(self, name: str) -> Optional[commands.Cog]:
        """
        Remove a cog by name.
        
        Parameters:
        - name: Cog name
        
        Returns:
        Removed cog if found
        """

    def get_cog(self, name: str) -> Optional[commands.Cog]:
        """
        Get a cog by name.
        
        Parameters:
        - name: Cog name
        
        Returns:
        Cog if found
        """

    async def load_extension(self, name: str, *, package: Optional[str] = None) -> None:
        """
        Load an extension module.
        
        Parameters:
        - name: Extension module name
        - package: Package name for relative imports
        """

    async def unload_extension(self, name: str, *, package: Optional[str] = None) -> None:
        """
        Unload an extension module.
        
        Parameters:
        - name: Extension module name
        - package: Package name for relative imports
        """

    async def reload_extension(self, name: str, *, package: Optional[str] = None) -> None:
        """
        Reload an extension module.
        
        Parameters:
        - name: Extension module name
        - package: Package name for relative imports
        """

class AutoShardedBot(commands.AutoShardedBotBase, Bot):
    """Auto-sharded message command bot."""
    
    def __init__(self, command_prefix, **options):
        """Initialize auto-sharded command bot."""

Command Objects

Command representation and execution with parameter handling and validation.

class Command:
    def __init__(
        self,
        func: Callable,
        *,
        name: str = None,
        aliases: List[str] = None,
        help: str = None,
        brief: str = None,
        usage: str = None,
        description: str = None,
        enabled: bool = True,
        hidden: bool = False,
        ignore_extra: bool = True,
        cooldown_after_parsing: bool = False,
        extras: Dict[str, Any] = None,
        **kwargs
    ):
        """
        Initialize a command.
        
        Parameters:
        - func: Command callback function
        - name: Command name
        - aliases: Command aliases
        - help: Help text
        - brief: Brief description
        - usage: Usage syntax
        - description: Long description
        - enabled: Whether command is enabled
        - hidden: Whether to hide from help
        - ignore_extra: Ignore extra arguments
        - cooldown_after_parsing: Apply cooldown after parsing
        - extras: Extra metadata
        """

    name: str
    callback: Callable
    help: Optional[str]
    brief: Optional[str]
    usage: Optional[str]
    aliases: List[str]
    enabled: bool
    hidden: bool
    checks: List[Check]
    description: Optional[str]
    signature: str
    extras: Dict[str, Any]

    @property
    def cog(self) -> Optional[Cog]:
        """Cog the command belongs to."""

    @property
    def short_doc(self) -> Optional[str]:
        """Short documentation string."""

    @property
    def signature(self) -> str:
        """Command signature with parameters."""

    def can_run(self, ctx: Context) -> bool:
        """
        Check if command can be run in context.
        
        Parameters:
        - ctx: Command context
        
        Returns:
        True if command can run
        """

    async def invoke(self, ctx: Context) -> None:
        """
        Invoke the command.
        
        Parameters:
        - ctx: Command context
        """

    async def reinvoke(self, ctx: Context, *, call_hooks: bool = False) -> None:
        """
        Reinvoke the command bypassing cooldowns.
        
        Parameters:
        - ctx: Command context
        - call_hooks: Whether to call before/after hooks
        """

    def error(self, coro):
        """
        Decorator for command error handlers.
        
        Parameters:
        - coro: Error handler coroutine
        """

    def before_invoke(self, coro):
        """
        Decorator for pre-command hooks.
        
        Parameters:
        - coro: Hook coroutine
        """

    def after_invoke(self, coro):
        """
        Decorator for post-command hooks.
        
        Parameters:
        - coro: Hook coroutine
        """

class Group(Command):
    """Command group container for subcommands."""
    
    def __init__(
        self,
        *args,
        invoke_without_subcommand: bool = False,
        case_insensitive: bool = False,
        **kwargs
    ):
        """
        Initialize a command group.
        
        Parameters:
        - invoke_without_subcommand: Allow invoking group without subcommand
        - case_insensitive: Case insensitive subcommand matching
        """

    @property
    def commands(self) -> Set[Command]:
        """Subcommands in this group."""

    def add_command(self, command: Command) -> None:
        """
        Add a subcommand.
        
        Parameters:
        - command: Subcommand to add
        """

    def remove_command(self, name: str) -> Optional[Command]:
        """
        Remove a subcommand.
        
        Parameters:
        - name: Subcommand name
        
        Returns:
        Removed command if found
        """

    def get_command(self, name: str) -> Optional[Command]:
        """
        Get a subcommand.
        
        Parameters:
        - name: Subcommand name
        
        Returns:
        Command if found
        """

    def walk_commands(self) -> Generator[Command, None, None]:
        """
        Walk all commands in group recursively.
        
        Yields:
        All commands and subcommands
        """

    def command(self, *args, **kwargs):
        """Decorator for adding subcommands."""

    def group(self, *args, **kwargs):
        """Decorator for adding subgroups."""

Context Objects

Command invocation context providing access to message, channel, guild, and bot state.

class Context:
    def __init__(
        self,
        *,
        message: Message,
        bot: Bot,
        prefix: str = None,
        command: Command = None,
        invoked_with: str = None,
        invoked_parents: List[str] = None,
        invoked_subcommand: Command = None,
        subcommand_passed: str = None,
        command_failed: bool = False,
        current_parameter: Parameter = None
    ):
        """
        Initialize command context.
        
        Parameters:
        - message: Message that triggered command
        - bot: Bot instance
        - prefix: Used command prefix
        - command: Invoked command
        - invoked_with: Command name used for invocation
        - invoked_parents: Parent command names
        - invoked_subcommand: Invoked subcommand
        - subcommand_passed: Subcommand argument
        - command_failed: Whether command execution failed
        - current_parameter: Currently parsing parameter
        """

    message: Message
    bot: Bot
    command: Optional[Command]
    invoked_with: Optional[str]
    invoked_parents: List[str]
    invoked_subcommand: Optional[Command]
    subcommand_passed: Optional[str]
    command_failed: bool
    prefix: Optional[str]
    args: List[Any]
    kwargs: Dict[str, Any]

    @property
    def author(self) -> Union[User, Member]:
        """Message author."""

    @property
    def guild(self) -> Optional[Guild]:
        """Guild where command was invoked."""

    @property
    def channel(self) -> Messageable:
        """Channel where command was invoked."""

    @property
    def me(self) -> Union[Member, ClientUser]:
        """Bot's member object in guild."""

    @property
    def voice_client(self) -> Optional[VoiceProtocol]:
        """Voice client for the guild."""

    @property
    def valid(self) -> bool:
        """Whether context is valid for command invocation."""

    @property
    def clean_prefix(self) -> str:
        """Cleaned command prefix."""

    @property
    def cog(self) -> Optional[Cog]:
        """Cog of the invoked command."""

    async def invoke(
        self,
        command: Command,
        *args,
        **kwargs
    ) -> None:
        """
        Invoke another command.
        
        Parameters:
        - command: Command to invoke
        - args: Command arguments
        - kwargs: Command keyword arguments
        """

    async def reinvoke(self, *, call_hooks: bool = False, restart: bool = True) -> None:
        """
        Reinvoke the current command.
        
        Parameters:
        - call_hooks: Whether to call before/after hooks
        - restart: Whether to restart from beginning
        """

    async def send(
        self,
        content: str = None,
        *,
        tts: bool = False,
        embed: Embed = None,
        embeds: List[Embed] = None,
        file: File = None,
        files: List[File] = None,
        allowed_mentions: AllowedMentions = None,
        reference: Union[Message, MessageReference, PartialMessage] = None,
        mention_author: bool = None,
        view: View = None,
        components: Union[ActionRow, List[ActionRow]] = None,
        delete_after: float = None,
        suppress_embeds: bool = False,
        flags: MessageFlags = None,
        ephemeral: bool = False
    ) -> Message:
        """
        Send a message to the context channel.
        
        Parameters:
        - content: Message content
        - tts: Text-to-speech
        - embed: Single embed
        - embeds: List of embeds
        - file: Single file
        - files: List of files
        - allowed_mentions: Mention configuration
        - reference: Message to reply to
        - mention_author: Whether to mention author in reply
        - view: UI components view
        - components: Raw components
        - delete_after: Auto-delete after seconds
        - suppress_embeds: Suppress embeds
        - flags: Message flags
        - ephemeral: Send as ephemeral (slash command contexts only)
        
        Returns:
        Sent message
        """

    async def reply(self, content: str = None, **kwargs) -> Message:
        """
        Reply to the context message.
        
        Parameters:
        - content: Reply content
        - kwargs: Additional send parameters
        
        Returns:
        Sent reply message
        """

    def typing(self) -> Typing:
        """
        Context manager for typing indicator.
        
        Returns:
        Typing context manager
        """

    def history(self, **kwargs) -> AsyncIterator[Message]:
        """
        Get channel message history.
        
        Parameters:
        - kwargs: History parameters
        
        Yields:
        Messages from channel history
        """

    async def fetch_message(self, id: int) -> Message:
        """
        Fetch a message by ID from context channel.
        
        Parameters:
        - id: Message ID
        
        Returns:
        Message object
        """

    def get_parameter(self, name: str) -> Optional[Parameter]:
        """
        Get command parameter by name.
        
        Parameters:
        - name: Parameter name
        
        Returns:
        Parameter if found
        """

class GuildContext(Context):
    """Guild-specific context with additional guild properties."""
    
    author: Member
    guild: Guild
    me: Member
    
    @property
    def permissions(self) -> Permissions:
        """Author's permissions in channel."""
    
    @property
    def bot_permissions(self) -> Permissions:
        """Bot's permissions in channel."""

Cog System

Modular command organization system for grouping related functionality.

class Cog:
    """Base class for command cogs."""
    
    def __init_subclass__(cls, **kwargs):
        """Initialize cog subclass."""

    @classmethod
    def listener(cls, name: str = None):
        """
        Decorator for event listeners in cogs.
        
        Parameters:
        - name: Event name (optional)
        """

    def get_commands(self) -> List[Command]:
        """
        Get all commands in this cog.
        
        Returns:
        List of cog commands
        """

    def walk_commands(self) -> Generator[Command, None, None]:
        """
        Walk all commands in cog.
        
        Yields:
        All cog commands
        """

    def get_listeners(self) -> List[Tuple[str, Callable]]:
        """
        Get all event listeners in this cog.
        
        Returns:
        List of (event_name, callback) tuples
        """

    @property
    def qualified_name(self) -> str:
        """Qualified cog name."""

    @property
    def description(self) -> Optional[str]:
        """Cog description."""

    def cog_load(self) -> None:
        """Called when cog is loaded."""

    def cog_unload(self) -> None:
        """Called when cog is unloaded."""

    async def cog_check(self, ctx: Context) -> bool:
        """
        Global check for all commands in cog.
        
        Parameters:
        - ctx: Command context
        
        Returns:
        True if commands can run
        """

    async def cog_command_error(self, ctx: Context, error: Exception) -> None:
        """
        Error handler for cog commands.
        
        Parameters:
        - ctx: Command context
        - error: Exception raised
        """

    async def cog_before_invoke(self, ctx: Context) -> None:
        """
        Called before any cog command is invoked.
        
        Parameters:
        - ctx: Command context
        """

    async def cog_after_invoke(self, ctx: Context) -> None:
        """
        Called after any cog command is invoked.
        
        Parameters:
        - ctx: Command context
        """

def command(name: str = None, **attrs):
    """
    Decorator for creating commands.
    
    Parameters:
    - name: Command name
    - attrs: Command attributes
    """

def group(name: str = None, **attrs):
    """
    Decorator for creating command groups.
    
    Parameters:
    - name: Group name
    - attrs: Group attributes
    """

async def setup(bot: Bot):
    """
    Setup function for extension modules.
    
    Parameters:
    - bot: Bot instance
    """

Parameter System

Advanced parameter parsing, type conversion, and validation for command arguments.

class Parameter:
    """Command parameter information."""
    
    def __init__(
        self,
        name: str,
        kind: inspect.Parameter.kind,
        *,
        default: Any = inspect.Parameter.empty,
        annotation: Any = inspect.Parameter.empty,
        converter: Converter = None,
        description: str = None,
        displayed_default: str = None
    ):
        """
        Initialize parameter.
        
        Parameters:
        - name: Parameter name
        - kind: Parameter kind
        - default: Default value
        - annotation: Type annotation
        - converter: Type converter
        - description: Parameter description
        - displayed_default: Default value display
        """

    name: str
    default: Any
    annotation: Any
    converter: Converter
    kind: inspect.Parameter.kind
    description: Optional[str]
    displayed_default: Optional[str]

class Greedy:
    """Greedy converter for consuming multiple arguments."""
    
    def __init__(self, converter: Converter):
        """
        Initialize greedy converter.
        
        Parameters:
        - converter: Converter for individual arguments
        """

def param(
    default: Any = ...,
    *,
    converter: Converter = None,
    description: str = None,
    displayed_default: str = None,
    name: str = None
) -> Any:
    """
    Configure command parameter.
    
    Parameters:
    - default: Default value
    - converter: Type converter
    - description: Parameter description
    - displayed_default: Default display value
    - name: Parameter name override
    
    Returns:
    Configured parameter
    """

# Built-in converters
class MemberConverter:
    """Convert argument to Member."""
    
    async def convert(self, ctx: Context, argument: str) -> Member:
        """Convert string to Member."""

class UserConverter:
    """Convert argument to User."""
    
    async def convert(self, ctx: Context, argument: str) -> User:
        """Convert string to User."""

class GuildConverter:
    """Convert argument to Guild."""
    
    async def convert(self, ctx: Context, argument: str) -> Guild:
        """Convert string to Guild."""

class RoleConverter:
    """Convert argument to Role."""
    
    async def convert(self, ctx: Context, argument: str) -> Role:
        """Convert string to Role."""

class TextChannelConverter:
    """Convert argument to TextChannel."""
    
    async def convert(self, ctx: Context, argument: str) -> TextChannel:
        """Convert string to TextChannel."""

class VoiceChannelConverter:
    """Convert argument to VoiceChannel."""
    
    async def convert(self, ctx: Context, argument: str) -> VoiceChannel:
        """Convert string to VoiceChannel."""

class CategoryChannelConverter:
    """Convert argument to CategoryChannel."""
    
    async def convert(self, ctx: Context, argument: str) -> CategoryChannel:
        """Convert string to CategoryChannel."""

class EmojiConverter:
    """Convert argument to Emoji."""
    
    async def convert(self, ctx: Context, argument: str) -> Emoji:
        """Convert string to Emoji."""

class PartialEmojiConverter:
    """Convert argument to PartialEmoji."""
    
    async def convert(self, ctx: Context, argument: str) -> PartialEmoji:
        """Convert string to PartialEmoji."""

class ColourConverter:
    """Convert argument to Colour."""
    
    async def convert(self, ctx: Context, argument: str) -> Colour:
        """Convert string to Colour."""

class MessageConverter:
    """Convert argument to Message."""
    
    async def convert(self, ctx: Context, argument: str) -> Message:
        """Convert string to Message."""

class GameConverter:
    """Convert argument to Game activity."""
    
    async def convert(self, ctx: Context, argument: str) -> Game:
        """Convert string to Game."""

class InviteConverter:
    """Convert argument to Invite."""
    
    async def convert(self, ctx: Context, argument: str) -> Invite:
        """Convert string to Invite."""

class GuildStickerConverter:
    """Convert argument to GuildSticker."""
    
    async def convert(self, ctx: Context, argument: str) -> GuildSticker:
        """Convert string to GuildSticker."""

class ScheduledEventConverter:
    """Convert argument to GuildScheduledEvent."""
    
    async def convert(self, ctx: Context, argument: str) -> GuildScheduledEvent:
        """Convert string to GuildScheduledEvent."""

class ThreadConverter:
    """Convert argument to Thread."""
    
    async def convert(self, ctx: Context, argument: str) -> Thread:
        """Convert string to Thread."""

# Union converters
typing.Union[Member, User]  # Tries Member first, then User
typing.Optional[Member]     # Optional Member (can be None)
typing.Literal['option1', 'option2']  # Literal choices

Checks and Permissions

Permission checking system for command access control and security.

def check(predicate: Callable[[Context], bool]):
    """
    Decorator for custom permission checks.
    
    Parameters:
    - predicate: Check function
    """

def check_any(*checks: Check):
    """
    Decorator requiring any of the provided checks to pass.
    
    Parameters:
    - checks: Check decorators
    """

def has_role(name: Union[str, int]):
    """
    Check if user has specific role.
    
    Parameters:
    - name: Role name or ID
    """

def has_any_role(*names: Union[str, int]):
    """
    Check if user has any of the specified roles.
    
    Parameters:
    - names: Role names or IDs
    """

def has_permissions(**perms: bool):
    """
    Check if user has specific permissions.
    
    Parameters:
    - perms: Permission flags
    """

def has_guild_permissions(**perms: bool):
    """
    Check if user has guild permissions.
    
    Parameters:
    - perms: Permission flags
    """

def bot_has_permissions(**perms: bool):
    """
    Check if bot has specific permissions.
    
    Parameters:
    - perms: Permission flags
    """

def bot_has_guild_permissions(**perms: bool):
    """
    Check if bot has guild permissions.
    
    Parameters:
    - perms: Permission flags
    """

def is_owner():
    """Check if user is bot owner."""

def is_nsfw():
    """Check if channel is NSFW."""

def guild_only():
    """Check if command is in a guild."""

def dm_only():
    """Check if command is in DMs."""

def cooldown(rate: int, per: float, type: BucketType = BucketType.default):
    """
    Apply cooldown to command.
    
    Parameters:
    - rate: Number of uses allowed
    - per: Time period in seconds
    - type: Cooldown bucket type
    """

def dynamic_cooldown(cooldown: Callable[[Context], Optional[Cooldown]], type: BucketType = BucketType.default):
    """
    Apply dynamic cooldown to command.
    
    Parameters:
    - cooldown: Function returning cooldown configuration
    - type: Cooldown bucket type
    """

def max_concurrency(number: int, *, per: BucketType = BucketType.default, wait: bool = False):
    """
    Limit concurrent command usage.
    
    Parameters:
    - number: Maximum concurrent uses
    - per: Concurrency bucket type
    - wait: Whether to wait for slot
    """

class BucketType(enum.Enum):
    """Cooldown bucket types."""
    
    default = 0
    user = 1
    guild = 2
    channel = 3
    member = 4
    category = 5
    role = 6

Help System

Configurable help command system for documenting bot commands and usage.

class HelpCommand:
    """Base class for help commands."""
    
    def __init__(
        self,
        *,
        verify_checks: bool = True,
        command_attrs: Dict[str, Any] = None,
        sort_commands: bool = True,
        show_hidden: bool = False,
        dm_help: Optional[bool] = None,
        dm_help_threshold: Optional[int] = 1000
    ):
        """
        Initialize help command.
        
        Parameters:
        - verify_checks: Check command permissions
        - command_attrs: Help command attributes
        - sort_commands: Sort commands alphabetically
        - show_hidden: Show hidden commands
        - dm_help: Send help in DMs
        - dm_help_threshold: Character threshold for DMing
        """

    context: Optional[Context]
    verify_checks: bool
    command_attrs: Dict[str, Any]
    sort_commands: bool
    show_hidden: bool
    dm_help: Optional[bool]
    dm_help_threshold: Optional[int]

    def add_indented_commands(
        self,
        commands: List[Command],
        *,
        heading: str,
        max_size: Optional[int] = None
    ) -> None:
        """
        Add indented command list to paginator.
        
        Parameters:
        - commands: Commands to add
        - heading: Section heading
        - max_size: Maximum name length
        """

    def get_opening_note(self) -> str:
        """
        Get help opening note.
        
        Returns:
        Opening note text
        """

    def get_ending_note(self) -> str:
        """
        Get help ending note.
        
        Returns:
        Ending note text
        """

    def add_bot_commands_formatting(self, commands: List[Command], heading: str) -> None:
        """
        Add bot commands to help.
        
        Parameters:
        - commands: Commands to format
        - heading: Section heading
        """

    def add_subcommand_formatting(self, command: Command) -> None:
        """
        Add subcommand information.
        
        Parameters:
        - command: Subcommand to format
        """

    def add_aliases_formatting(self, aliases: List[str]) -> None:
        """
        Add command aliases.
        
        Parameters:
        - aliases: Command aliases
        """

    def add_command_formatting(self, command: Command) -> None:
        """
        Add single command information.
        
        Parameters:
        - command: Command to format
        """

    def get_destination(self) -> Messageable:
        """
        Get help destination channel.
        
        Returns:
        Destination for help message
        """

    async def filter_commands(
        self,
        commands: Iterable[Command],
        *,
        sort: bool = False,
        key: Optional[Callable[[Command], Any]] = None
    ) -> List[Command]:
        """
        Filter commands based on checks.
        
        Parameters:
        - commands: Commands to filter
        - sort: Whether to sort commands
        - key: Sort key function
        
        Returns:
        Filtered command list
        """

    def get_max_size(self, commands: List[Command]) -> int:
        """
        Get maximum command name length.
        
        Parameters:
        - commands: Commands to check
        
        Returns:
        Maximum name length
        """

    def get_command_signature(self, command: Command) -> str:
        """
        Get command signature.
        
        Parameters:
        - command: Command to get signature for
        
        Returns:
        Command signature string
        """

    async def send_bot_help(self, mapping: Dict[Optional[Cog], List[Command]]) -> None:
        """
        Send bot-wide help.
        
        Parameters:
        - mapping: Cog to commands mapping
        """

    async def send_cog_help(self, cog: Cog) -> None:
        """
        Send cog-specific help.
        
        Parameters:
        - cog: Cog to get help for
        """

    async def send_group_help(self, group: Group) -> None:
        """
        Send group command help.
        
        Parameters:
        - group: Command group
        """

    async def send_command_help(self, command: Command) -> None:
        """
        Send single command help.
        
        Parameters:
        - command: Command to get help for
        """

    async def prepare_help_command(self, ctx: Context, command: Optional[str] = None) -> None:
        """
        Prepare help command for execution.
        
        Parameters:
        - ctx: Command context
        - command: Specific command help requested
        """

    async def command_not_found(self, string: str) -> str:
        """
        Handle command not found.
        
        Parameters:
        - string: Command name that wasn't found
        
        Returns:
        Error message
        """

    async def subcommand_not_found(self, command: Command, string: str) -> str:
        """
        Handle subcommand not found.
        
        Parameters:
        - command: Parent command
        - string: Subcommand name that wasn't found
        
        Returns:
        Error message
        """

    async def send_error_message(self, error: str) -> None:
        """
        Send error message.
        
        Parameters:
        - error: Error message to send
        """

    async def on_help_command_error(self, ctx: Context, error: CommandError) -> None:
        """
        Handle help command errors.
        
        Parameters:
        - ctx: Command context
        - error: Error that occurred
        """

class DefaultHelpCommand(HelpCommand):
    """Default help command implementation."""
    
    def __init__(
        self,
        *,
        paginator: Optional[Paginator] = None,
        **options
    ):
        """
        Initialize default help command.
        
        Parameters:
        - paginator: Custom paginator
        - options: Base class options
        """

class MinimalHelpCommand(HelpCommand):
    """Minimal help command implementation."""
    
    def __init__(self, **options):
        """Initialize minimal help command."""

class Paginator:
    """Text paginator for long help content."""
    
    def __init__(
        self,
        prefix: str = '```',
        suffix: str = '```',
        max_size: int = 2000,
        linesep: str = '\n'
    ):
        """
        Initialize paginator.
        
        Parameters:
        - prefix: Page prefix
        - suffix: Page suffix
        - max_size: Maximum page size
        - linesep: Line separator
        """

    @property
    def pages(self) -> List[str]:
        """Paginated pages."""

    def add_line(self, line: str = '', *, empty: bool = False) -> None:
        """
        Add line to paginator.
        
        Parameters:
        - line: Line content
        - empty: Whether to add empty line
        """

    def close_page(self) -> None:
        """Close current page."""

Usage Examples

Basic Command Bot Setup

import disnake
from disnake.ext import commands

# Create bot with command prefix
bot = commands.Bot(
    command_prefix='!',
    description='A helpful bot',
    intents=disnake.Intents.all(),
    help_command=commands.DefaultHelpCommand(),
    case_insensitive=True
)

@bot.event
async def on_ready():
    print(f'Bot ready: {bot.user}')

@bot.event
async def on_command_error(ctx, error):
    """Global command error handler."""
    if isinstance(error, commands.CommandNotFound):
        return  # Ignore unknown commands
    
    elif isinstance(error, commands.MissingRequiredArgument):
        await ctx.send(f"Missing argument: `{error.param}`")
    
    elif isinstance(error, commands.BadArgument):
        await ctx.send(f"Invalid argument: {error}")
    
    elif isinstance(error, commands.CheckFailure):
        await ctx.send("You don't have permission to use this command.")
    
    elif isinstance(error, commands.CommandOnCooldown):
        await ctx.send(f"Command on cooldown. Try again in {error.retry_after:.2f} seconds.")
    
    else:
        print(f'Command error: {error}')
        await ctx.send("An error occurred while processing the command.")

# Basic commands
@bot.command()
async def ping(ctx):
    """Check bot latency."""
    latency = round(bot.latency * 1000)
    await ctx.send(f'Pong! Latency: {latency}ms')

@bot.command()
async def echo(ctx, *, message):
    """Echo a message."""
    await ctx.send(message)

@bot.command()
async def userinfo(ctx, user: disnake.User = None):
    """Get information about a user."""
    if user is None:
        user = ctx.author
    
    embed = disnake.Embed(title=f"User Info: {user}", color=0x00ff00)
    embed.set_thumbnail(url=user.display_avatar.url)
    embed.add_field(name="ID", value=user.id, inline=True)
    embed.add_field(name="Created", value=f"<t:{int(user.created_at.timestamp())}:F>", inline=True)
    
    if isinstance(user, disnake.Member):
        embed.add_field(name="Joined", value=f"<t:{int(user.joined_at.timestamp())}:F>", inline=True)
        embed.add_field(name="Roles", value=len(user.roles) - 1, inline=True)
    
    await ctx.send(embed=embed)

bot.run('YOUR_BOT_TOKEN')

Command Groups and Subcommands

@bot.group(invoke_without_subcommand=True, case_insensitive=True)
async def config(ctx):
    """Configuration commands."""
    if ctx.invoked_subcommand is None:
        await ctx.send("Available config options: prefix, welcome, autorole")

@config.command()
@commands.has_permissions(administrator=True)
async def prefix(ctx, new_prefix: str = None):
    """View or change bot prefix."""
    if new_prefix is None:
        current_prefix = await bot.get_prefix(ctx.message)
        await ctx.send(f"Current prefix: `{current_prefix[0]}`")
    else:
        # In a real bot, save to database
        bot.command_prefix = new_prefix
        await ctx.send(f"Prefix changed to: `{new_prefix}`")

@config.command()
@commands.has_permissions(manage_guild=True)
async def welcome(ctx, channel: disnake.TextChannel = None):
    """Set welcome channel."""
    if channel is None:
        await ctx.send("Please specify a channel.")
        return
    
    # Save to database in real implementation
    await ctx.send(f"Welcome channel set to {channel.mention}")

@bot.group()
@commands.has_permissions(manage_roles=True)
async def role(ctx):
    """Role management commands."""
    if ctx.invoked_subcommand is None:
        await ctx.send_help(ctx.command)

@role.command()
async def create(ctx, *, name: str):
    """Create a new role."""
    role = await ctx.guild.create_role(name=name, reason=f"Created by {ctx.author}")
    await ctx.send(f"Created role: {role.mention}")

@role.command()
async def delete(ctx, role: disnake.Role):
    """Delete a role."""
    if role >= ctx.author.top_role:
        return await ctx.send("You cannot delete this role.")
    
    await role.delete(reason=f"Deleted by {ctx.author}")
    await ctx.send(f"Deleted role: {role.name}")

@role.command()
async def give(ctx, member: disnake.Member, role: disnake.Role):
    """Give a role to a member."""
    if role >= ctx.author.top_role:
        return await ctx.send("You cannot assign this role.")
    
    if role in member.roles:
        return await ctx.send(f"{member} already has the {role.name} role.")
    
    await member.add_roles(role, reason=f"Added by {ctx.author}")
    await ctx.send(f"Gave {role.name} to {member.mention}")

@role.command()
async def remove(ctx, member: disnake.Member, role: disnake.Role):
    """Remove a role from a member."""
    if role >= ctx.author.top_role:
        return await ctx.send("You cannot manage this role.")
    
    if role not in member.roles:
        return await ctx.send(f"{member} doesn't have the {role.name} role.")
    
    await member.remove_roles(role, reason=f"Removed by {ctx.author}")
    await ctx.send(f"Removed {role.name} from {member.mention}")

Advanced Parameter Handling

from typing import Union, Optional, Literal

@bot.command()
async def kick(
    ctx, 
    member: disnake.Member, 
    *, 
    reason: Optional[str] = "No reason provided"
):
    """Kick a member from the server."""
    if not ctx.author.guild_permissions.kick_members:
        return await ctx.send("You don't have permission to kick members.")
    
    if member.top_role >= ctx.author.top_role:
        return await ctx.send("You cannot kick this member.")
    
    await member.kick(reason=reason)
    await ctx.send(f"Kicked {member} for: {reason}")

@bot.command()
async def ban(
    ctx,
    user: Union[disnake.Member, disnake.User],
    delete_days: Optional[int] = 1,
    *,
    reason: Optional[str] = "No reason provided"
):
    """Ban a user from the server."""
    if not ctx.author.guild_permissions.ban_members:
        return await ctx.send("You don't have permission to ban members.")
    
    if isinstance(user, disnake.Member) and user.top_role >= ctx.author.top_role:
        return await ctx.send("You cannot ban this member.")
    
    if not 0 <= delete_days <= 7:
        return await ctx.send("Delete days must be between 0 and 7.")
    
    await ctx.guild.ban(user, delete_message_days=delete_days, reason=reason)
    await ctx.send(f"Banned {user} for: {reason}")

@bot.command()
async def purge(
    ctx,
    limit: int = 10,
    target: Union[disnake.Member, disnake.User, str, None] = None
):
    """Purge messages from channel."""
    if not ctx.author.guild_permissions.manage_messages:
        return await ctx.send("You don't have permission to purge messages.")
    
    if limit > 100:
        return await ctx.send("Cannot purge more than 100 messages at once.")
    
    def message_check(message):
        if target is None:
            return True
        elif isinstance(target, (disnake.Member, disnake.User)):
            return message.author == target
        elif isinstance(target, str):
            return target.lower() in message.content.lower()
        return False
    
    deleted = await ctx.channel.purge(limit=limit, check=message_check)
    await ctx.send(f"Purged {len(deleted)} messages.", delete_after=5)

@bot.command()
async def remind(
    ctx,
    time: str,
    *,
    reminder: str
):
    """Set a reminder (e.g., !remind 1h Take break)."""
    import re
    from datetime import datetime, timedelta
    
    # Parse time string
    time_regex = re.compile(r'(\d+)([smhd])')
    matches = time_regex.findall(time.lower())
    
    if not matches:
        return await ctx.send("Invalid time format. Use: 1s, 1m, 1h, 1d")
    
    total_seconds = 0
    for amount, unit in matches:
        amount = int(amount)
        if unit == 's':
            total_seconds += amount
        elif unit == 'm':
            total_seconds += amount * 60
        elif unit == 'h':
            total_seconds += amount * 3600
        elif unit == 'd':
            total_seconds += amount * 86400
    
    if total_seconds > 86400 * 30:  # 30 days max
        return await ctx.send("Reminder cannot be longer than 30 days.")
    
    # Schedule reminder (in real bot, use a task scheduler)
    reminder_time = datetime.utcnow() + timedelta(seconds=total_seconds)
    
    await ctx.send(f"Reminder set for <t:{int(reminder_time.timestamp())}:F>")
    
    # Simple sleep for demo (use proper task scheduling in production)
    await asyncio.sleep(total_seconds)
    
    try:
        await ctx.author.send(f"⏰ Reminder: {reminder}")
    except disnake.Forbidden:
        await ctx.send(f"⏰ {ctx.author.mention}, reminder: {reminder}")

# Custom converter example
class ColorConverter(commands.Converter):
    async def convert(self, ctx, argument):
        # Try hex color
        if argument.startswith('#'):
            try:
                return disnake.Color(int(argument[1:], 16))
            except ValueError:
                pass
        
        # Try color name
        try:
            return getattr(disnake.Color, argument.lower())()
        except AttributeError:
            pass
        
        # Try RGB values
        if ',' in argument:
            try:
                r, g, b = map(int, argument.split(','))
                return disnake.Color.from_rgb(r, g, b)
            except ValueError:
                pass
        
        raise commands.BadArgument(f"Could not convert '{argument}' to a color.")

@bot.command()
async def color(ctx, color: ColorConverter):
    """Test color conversion."""
    embed = disnake.Embed(title="Color Test", color=color)
    embed.add_field(name="RGB", value=f"{color.r}, {color.g}, {color.b}")
    embed.add_field(name="Hex", value=f"#{color.value:06x}")
    await ctx.send(embed=embed)

# Flag system example
class ModFlags(commands.FlagConverter):
    silent: bool = commands.flag(default=False, description="Don't send notification")
    reason: Optional[str] = commands.flag(default=None, description="Reason for action")
    duration: Optional[str] = commands.flag(default=None, description="Duration for temporary actions")

@bot.command()
async def tempban(ctx, member: disnake.Member, **flags: ModFlags):
    """Temporarily ban a member with flags."""
    if not ctx.author.guild_permissions.ban_members:
        return await ctx.send("You don't have permission to ban members.")
    
    duration = flags.duration or "1d"
    reason = flags.reason or "No reason provided"
    silent = flags.silent
    
    # Parse duration and implement temp ban logic
    await ctx.send(f"Temp banned {member} for {duration}. Reason: {reason}. Silent: {silent}")

Cog System Implementation

# cogs/moderation.py
class Moderation(commands.Cog):
    """Moderation commands and features."""
    
    def __init__(self, bot):
        self.bot = bot
        self.muted_members = set()  # In production, use database
    
    async def cog_check(self, ctx):
        """Check if user has moderation permissions."""
        return ctx.author.guild_permissions.manage_messages
    
    async def cog_command_error(self, ctx, error):
        """Handle cog command errors."""
        if isinstance(error, commands.CheckFailure):
            await ctx.send("You need moderation permissions to use this command.")
        else:
            # Re-raise for global handler
            raise error
    
    @commands.Cog.listener()
    async def on_message(self, message):
        """Monitor messages for auto-moderation."""
        if message.author.bot or not message.guild:
            return
        
        # Auto-delete messages with too many mentions
        if len(message.mentions) > 5:
            await message.delete()
            await message.channel.send(
                f"{message.author.mention}, please don't spam mentions.",
                delete_after=5
            )
    
    @commands.Cog.listener()
    async def on_member_join(self, member):
        """Auto-mute members if they were previously muted."""
        if member.id in self.muted_members:
            mute_role = disnake.utils.get(member.guild.roles, name="Muted")
            if mute_role:
                await member.add_roles(mute_role)
    
    @commands.command()
    async def warn(self, ctx, member: disnake.Member, *, reason):
        """Warn a member."""
        # In production, save to database
        embed = disnake.Embed(
            title="Member Warned",
            description=f"{member.mention} has been warned.",
            color=0xffaa00
        )
        embed.add_field(name="Reason", value=reason)
        embed.add_field(name="Moderator", value=ctx.author.mention)
        
        await ctx.send(embed=embed)
        
        try:
            await member.send(f"You have been warned in {ctx.guild.name}: {reason}")
        except disnake.Forbidden:
            pass
    
    @commands.command()
    async def mute(self, ctx, member: disnake.Member, duration: str = "10m", *, reason="No reason"):
        """Mute a member."""
        mute_role = disnake.utils.get(ctx.guild.roles, name="Muted")
        
        if not mute_role:
            # Create mute role
            mute_role = await ctx.guild.create_role(
                name="Muted",
                permissions=disnake.Permissions(send_messages=False, speak=False)
            )
            
            # Set permissions for all channels
            for channel in ctx.guild.channels:
                await channel.set_permissions(
                    mute_role,
                    send_messages=False,
                    speak=False
                )
        
        await member.add_roles(mute_role, reason=reason)
        self.muted_members.add(member.id)
        
        await ctx.send(f"Muted {member} for {duration}. Reason: {reason}")
        
        # Schedule unmute (simplified - use proper task scheduler)
        # parse_duration(duration) would return seconds
        # await asyncio.sleep(seconds)
        # await member.remove_roles(mute_role)
    
    @commands.command()
    async def unmute(self, ctx, member: disnake.Member):
        """Unmute a member."""
        mute_role = disnake.utils.get(ctx.guild.roles, name="Muted")
        
        if not mute_role or mute_role not in member.roles:
            return await ctx.send("Member is not muted.")
        
        await member.remove_roles(mute_role)
        self.muted_members.discard(member.id)
        await ctx.send(f"Unmuted {member}")
    
    @commands.group()
    async def automod(self, ctx):
        """Auto-moderation settings."""
        if ctx.invoked_subcommand is None:
            await ctx.send_help(ctx.command)
    
    @automod.command()
    async def spam(self, ctx, enabled: bool):
        """Toggle spam protection."""
        # Save setting to database
        await ctx.send(f"Spam protection {'enabled' if enabled else 'disabled'}.")

# cogs/fun.py
class Fun(commands.Cog):
    """Fun and entertainment commands."""
    
    def __init__(self, bot):
        self.bot = bot
    
    @commands.command()
    @commands.cooldown(1, 5, commands.BucketType.user)
    async def roll(self, ctx, dice: str = "1d6"):
        """Roll dice (e.g., 1d6, 2d20)."""
        import random
        import re
        
        match = re.match(r'(\d+)d(\d+)', dice)
        if not match:
            return await ctx.send("Invalid dice format. Use format like: 1d6, 2d20")
        
        count, sides = map(int, match.groups())
        
        if count > 10 or sides > 100:
            return await ctx.send("Too many dice or sides!")
        
        rolls = [random.randint(1, sides) for _ in range(count)]
        result = sum(rolls)
        
        embed = disnake.Embed(title=f"🎲 Dice Roll: {dice}")
        embed.add_field(name="Rolls", value=" + ".join(map(str, rolls)))
        embed.add_field(name="Total", value=result)
        
        await ctx.send(embed=embed)
    
    @commands.command()
    async def choose(self, ctx, *choices):
        """Choose randomly from options."""
        if len(choices) < 2:
            return await ctx.send("Please provide at least 2 choices.")
        
        choice = random.choice(choices)
        await ctx.send(f"I choose: **{choice}**")
    
    @commands.command()
    async def coinflip(self, ctx):
        """Flip a coin."""
        result = random.choice(["Heads", "Tails"])
        emoji = "🟡" if result == "Heads" else "⚫"
        await ctx.send(f"{emoji} **{result}**!")

# cogs/utility.py
class Utility(commands.Cog):
    """Utility commands."""
    
    def __init__(self, bot):
        self.bot = bot
    
    @commands.command()
    async def serverinfo(self, ctx):
        """Show server information."""
        guild = ctx.guild
        
        embed = disnake.Embed(title=guild.name, color=0x00ff00)
        embed.set_thumbnail(url=guild.icon.url if guild.icon else None)
        
        embed.add_field(name="Owner", value=guild.owner.mention)
        embed.add_field(name="Created", value=f"<t:{int(guild.created_at.timestamp())}:F>")
        embed.add_field(name="Members", value=guild.member_count)
        embed.add_field(name="Channels", value=len(guild.channels))
        embed.add_field(name="Roles", value=len(guild.roles))
        embed.add_field(name="Boost Level", value=guild.premium_tier)
        
        await ctx.send(embed=embed)
    
    @commands.command()
    async def avatar(self, ctx, user: disnake.User = None):
        """Show user avatar."""
        user = user or ctx.author
        
        embed = disnake.Embed(title=f"{user}'s Avatar")
        embed.set_image(url=user.display_avatar.url)
        await ctx.send(embed=embed)
    
    @commands.command()
    async def poll(self, ctx, question, *options):
        """Create a poll with reactions."""
        if len(options) > 10:
            return await ctx.send("Too many options! Maximum 10.")
        
        if len(options) < 2:
            return await ctx.send("Need at least 2 options!")
        
        reactions = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟']
        
        embed = disnake.Embed(title=f"📊 {question}", color=0x0099ff)
        
        for i, option in enumerate(options):
            embed.add_field(
                name=f"{reactions[i]} Option {i+1}",
                value=option,
                inline=False
            )
        
        message = await ctx.send(embed=embed)
        
        for i in range(len(options)):
            await message.add_reaction(reactions[i])

# Load cogs
async def setup(bot):
    await bot.add_cog(Moderation(bot))
    await bot.add_cog(Fun(bot))
    await bot.add_cog(Utility(bot))

# In main bot file
async def load_extensions():
    initial_extensions = [
        'cogs.moderation',
        'cogs.fun',
        'cogs.utility'
    ]
    
    for extension in initial_extensions:
        try:
            await bot.load_extension(extension)
            print(f'Loaded {extension}')
        except Exception as e:
            print(f'Failed to load {extension}: {e}')

# Extension management commands
@bot.command()
@commands.is_owner()
async def load(ctx, extension):
    """Load an extension."""
    try:
        await bot.load_extension(f'cogs.{extension}')
        await ctx.send(f'✅ Loaded {extension}')
    except Exception as e:
        await ctx.send(f'❌ Failed to load {extension}: {e}')

@bot.command()
@commands.is_owner()
async def unload(ctx, extension):
    """Unload an extension."""
    try:
        await bot.unload_extension(f'cogs.{extension}')
        await ctx.send(f'✅ Unloaded {extension}')
    except Exception as e:
        await ctx.send(f'❌ Failed to unload {extension}: {e}')

@bot.command()
@commands.is_owner()
async def reload(ctx, extension):
    """Reload an extension."""
    try:
        await bot.reload_extension(f'cogs.{extension}')
        await ctx.send(f'🔄 Reloaded {extension}')
    except Exception as e:
        await ctx.send(f'❌ Failed to reload {extension}: {e}')

# Setup hook
async def main():
    await load_extensions()
    await bot.start('YOUR_BOT_TOKEN')

if __name__ == '__main__':
    asyncio.run(main())

Install with Tessl CLI

npx tessl i tessl/pypi-disnake

docs

application-commands.md

automod.md

channels-messaging.md

client-bot.md

command-framework.md

error-handling.md

events-gateway.md

guild-management.md

index.md

interactions-ui.md

localization-i18n.md

permissions-security.md

polls.md

users-members.md

voice-audio.md

tile.json