CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-discord-py

A modern, feature-rich, and async-ready API wrapper for Discord written in Python

Pending
Overview
Eval results
Files

app-commands.mddocs/

Application Commands

Discord's native slash commands and context menus with built-in parameter validation, autocomplete, localization, and seamless UI integration. Application commands appear in Discord's interface and provide a modern alternative to prefix-based commands.

Capabilities

Command Tree Management

The CommandTree manages registration and syncing of application commands with Discord's API.

class CommandTree:
    """
    Manages application commands for a client.
    """
    def __init__(self, client: Client): ...
    
    client: Client  # Associated Discord client
    
    async def sync(self, *, guild: Optional[Guild] = None) -> List[AppCommand]:
        """
        Sync commands with Discord.
        
        Parameters:
        - guild: Guild to sync to (None for global commands)
        
        Returns:
        List of synced AppCommand objects
        """
    
    async def fetch_command(self, command_id: int, *, guild: Optional[Guild] = None) -> AppCommand:
        """Fetch a command by ID."""
    
    async def fetch_commands(self, *, guild: Optional[Guild] = None) -> List[AppCommand]:
        """Fetch all commands."""
    
    def command(
        self, 
        *, 
        name: str = None, 
        description: str = None,
        nsfw: bool = False,
        guild: Optional[Guild] = None,
        guilds: Optional[List[Guild]] = None,
        auto_locale_strings: bool = True
    ) -> Callable:
        """Decorator to register a slash command."""
    
    def context_menu(
        self,
        *,
        name: str = None,
        nsfw: bool = False,
        guild: Optional[Guild] = None,
        guilds: Optional[List[Guild]] = None,
        auto_locale_strings: bool = True
    ) -> Callable:
        """Decorator to register a context menu command."""
    
    def add_command(self, command: Union[Command, ContextMenu], *, guild: Optional[Guild] = None, guilds: Optional[List[Guild]] = None, override: bool = False) -> None:
        """Add a command to the tree."""
    
    def remove_command(self, command: Union[str, Command, ContextMenu], *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> Optional[Union[Command, ContextMenu]]:
        """Remove a command from the tree."""
    
    def get_command(self, name: str, *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> Optional[Union[Command, ContextMenu]]:
        """Get a command by name."""
    
    def get_commands(self, *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> List[Union[Command, ContextMenu]]:
        """Get all commands."""
    
    def walk_commands(self, *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> Iterator[Union[Command, ContextMenu]]:
        """Walk all commands."""
    
    def clear_commands(self, *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> None:
        """Clear all commands."""
    
    def copy_global_to(self, guild: Guild) -> None:
        """Copy global commands to a guild."""
    
    async def set_translator(self, translator: Translator) -> None:
        """Set command translator for localization."""
    
    def error(self, coro: Callable) -> Callable:
        """Decorator for global error handler."""
    
    def interaction_check(self, coro: Callable) -> Callable:
        """Decorator for global interaction check."""

Slash Commands

Slash commands provide native Discord UI integration with parameter validation and autocomplete.

class Command:
    """
    Represents a slash command.
    """
    def __init__(
        self,
        *,
        name: str,
        description: str,
        callback: Callable,
        nsfw: bool = False,
        parent: Optional[Group] = None,
        guild_ids: Optional[List[int]] = None,
        auto_locale_strings: bool = True,
        extras: Dict[Any, Any] = None
    ): ...
    
    name: str  # Command name
    description: str  # Command description
    callback: Callable  # Command function
    nsfw: bool  # Whether command is NSFW
    parent: Optional[Group]  # Parent group
    guild_ids: Optional[List[int]]  # Restricted guild IDs
    qualified_name: str  # Full command name including parent
    mention: str  # Command mention string
    parameters: List[Parameter]  # Command parameters
    checks: List[Callable]  # Command checks
    extras: Dict[Any, Any]  # Extra metadata
    
    async def __call__(self, interaction: Interaction, **parameters) -> Any:
        """Invoke the command."""
    
    def error(self, coro: Callable) -> Callable:
        """Decorator for command error handler."""
    
    def autocomplete(self, name: str) -> Callable:
        """Decorator for parameter autocomplete."""
    
    def describe(self, **parameters: str) -> Command:
        """Add parameter descriptions."""
    
    def rename(self, **parameters: str) -> Command:
        """Rename parameters."""
    
class Group(Command):
    """
    Slash command group containing subcommands.
    """
    def __init__(self, *, name: str, description: str, **kwargs): ...
    
    commands: Dict[str, Union[Command, Group]]  # Child commands
    
    def command(
        self,
        *,
        name: str = None,
        description: str = None,
        nsfw: bool = False,
        auto_locale_strings: bool = True,
        extras: Dict[Any, Any] = None
    ) -> Callable:
        """Decorator to add a subcommand."""
    
    def group(
        self,
        *,
        name: str = None,
        description: str = None,
        nsfw: bool = False,
        auto_locale_strings: bool = True,
        extras: Dict[Any, Any] = None
    ) -> Callable:
        """Decorator to add a subcommand group."""
    
    def add_command(self, command: Command) -> None:
        """Add a subcommand."""
    
    def remove_command(self, name: str) -> Optional[Command]:
        """Remove a subcommand."""
    
    def get_command(self, name: str) -> Optional[Command]:
        """Get a subcommand by name."""

# Command decorators
def command(
    *,
    name: str = None,
    description: str = None,
    nsfw: bool = False,
    guild: Optional[Guild] = None,
    guilds: Optional[List[Guild]] = None,
    auto_locale_strings: bool = True,
    extras: Dict[Any, Any] = None
) -> Callable:
    """Decorator to create a slash command."""

def context_menu(
    *,
    name: str = None,
    nsfw: bool = False,
    guild: Optional[Guild] = None,
    guilds: Optional[List[Guild]] = None,
    auto_locale_strings: bool = True,
    extras: Dict[Any, Any] = None
) -> Callable:
    """Decorator to create a context menu command."""

def describe(**parameters: str) -> Callable:
    """Decorator to add parameter descriptions."""

def rename(**parameters: str) -> Callable:
    """Decorator to rename parameters."""

def choices(**parameters: List[Choice]) -> Callable:
    """Decorator to add parameter choices."""

def autocomplete(**parameters: Callable) -> Callable:
    """Decorator to add parameter autocomplete."""

def guild_only() -> Callable:
    """Decorator to restrict command to guilds only."""

def guilds(*guild_ids: int) -> Callable:
    """Decorator to restrict command to specific guilds."""

def default_permissions(**permissions: bool) -> Callable:
    """Decorator to set default permissions."""

Context Menu Commands

Context menu commands appear in right-click menus for users and messages.

class ContextMenu:
    """
    Represents a context menu command.
    """
    def __init__(
        self,
        *,
        name: str,
        callback: Callable,
        nsfw: bool = False,
        guild_ids: Optional[List[int]] = None,
        auto_locale_strings: bool = True,
        extras: Dict[Any, Any] = None
    ): ...
    
    name: str  # Command name
    type: AppCommandType  # Command type (USER or MESSAGE)
    callback: Callable  # Command function
    nsfw: bool  # Whether command is NSFW
    guild_ids: Optional[List[int]]  # Restricted guild IDs
    qualified_name: str  # Command name
    mention: str  # Command mention string
    checks: List[Callable]  # Command checks
    extras: Dict[Any, Any]  # Extra metadata
    
    async def __call__(self, interaction: Interaction, target: Union[User, Member, Message]) -> Any:
        """Invoke the context menu command."""
    
    def error(self, coro: Callable) -> Callable:
        """Decorator for command error handler."""

Parameters & Validation

Command parameters with type validation, choices, and autocomplete support.

class Parameter:
    """
    Represents a command parameter.
    """
    def __init__(
        self,
        *,
        name: str,
        description: str,
        type: AppCommandOptionType,
        required: bool = True,
        default: Any = None,
        choices: Optional[List[Choice]] = None,
        autocomplete: Optional[Callable] = None,
        channel_types: Optional[List[ChannelType]] = None,
        min_value: Optional[Union[int, float]] = None,
        max_value: Optional[Union[int, float]] = None,
        min_length: Optional[int] = None,
        max_length: Optional[int] = None
    ): ...
    
    name: str  # Parameter name
    display_name: str  # Display name (localized)
    description: str  # Parameter description
    type: AppCommandOptionType  # Parameter type
    required: bool  # Whether parameter is required
    default: Any  # Default value
    choices: Optional[List[Choice]]  # Fixed choices
    autocomplete: Optional[Callable]  # Autocomplete function
    channel_types: Optional[List[ChannelType]]  # Allowed channel types
    min_value: Optional[Union[int, float]]  # Minimum numeric value
    max_value: Optional[Union[int, float]]  # Maximum numeric value
    min_length: Optional[int]  # Minimum string length
    max_length: Optional[int]  # Maximum string length

class Choice:
    """
    Represents a parameter choice.
    """
    def __init__(self, *, name: str, value: Union[str, int, float]): ...
    
    name: str  # Choice display name
    value: Union[str, int, float]  # Choice value

class Range:
    """
    Type annotation for numeric parameter ranges.
    
    Usage: value: app_commands.Range[int, 1, 100]
    """
    def __init__(self, annotation: Type, min: Any = None, max: Any = None): ...

# Parameter transformers
class Transform:
    """
    Transform parameter values with custom logic.
    
    Usage: value: app_commands.Transform[CustomType, CustomTransformer]
    """
    def __init__(self, annotation: Type, transformer: Type[Transformer]): ...

class Transformer:
    """
    Base class for parameter transformers.
    """
    async def transform(self, interaction: Interaction, value: Any) -> Any:
        """Transform parameter value."""
        raise NotImplementedError
    
    async def autocomplete(self, interaction: Interaction, value: Union[int, float, str]) -> List[Choice]:
        """Provide autocomplete choices."""
        return []

Interaction Handling

Interaction objects represent slash command invocations with response management.

class Interaction:
    """
    Represents a Discord interaction (slash command, button click, etc.).
    """
    id: int  # Interaction ID
    application_id: int  # Application ID
    type: InteractionType  # Interaction type
    data: Optional[InteractionData]  # Interaction data
    guild_id: Optional[int]  # Guild ID
    guild: Optional[Guild]  # Guild object
    channel_id: Optional[int]  # Channel ID
    channel: Optional[Union[GuildChannel, PartialMessageable]]  # Channel object
    user: User  # User who triggered interaction
    member: Optional[Member]  # Member object if in guild
    token: str  # Interaction token
    version: int  # Interaction version
    message: Optional[Message]  # Message for component interactions
    followup: Followup  # Followup webhook
    response: InteractionResponse  # Response manager
    command: Optional[Union[Command, ContextMenu]]  # Command object
    namespace: Optional[Namespace]  # Parameter namespace
    locale: str  # User locale
    guild_locale: Optional[str]  # Guild locale
    created_at: datetime  # Interaction creation time
    expires_at: datetime  # When interaction expires
    
    @property
    def client(self) -> Client:
        """Client that received the interaction."""
    
    def is_expired(self) -> bool:
        """Check if interaction has expired."""
    
    async def original_response(self) -> InteractionMessage:
        """Get the original response message."""
    
    async def edit_original_response(self, **kwargs) -> InteractionMessage:
        """Edit the original response."""
    
    async def delete_original_response(self) -> None:
        """Delete the original response."""
    
    async def translate(self, string: locale_str, locale: str = None, **kwargs) -> str:
        """Translate a localizable string."""

class InteractionResponse:
    """
    Manages interaction responses.
    """
    def __init__(self, parent: Interaction): ...
    
    is_done(self) -> bool:
        """Check if response has been sent."""
    
    async def send_message(
        self,
        content: str = None,
        *,
        embed: Embed = None,
        embeds: List[Embed] = None,
        file: File = None,
        files: List[File] = None,
        view: View = None,
        ephemeral: bool = False,
        tts: bool = False,
        allowed_mentions: AllowedMentions = None,
        suppress_embeds: bool = False
    ) -> None:
        """Send response message."""
    
    async def defer(self, *, ephemeral: bool = False, thinking: bool = False) -> None:
        """Defer response to send later."""
    
    async def pong(self) -> None:
        """Respond to ping interaction."""
    
    async def edit_message(
        self,
        *,
        content: str = None,
        embed: Embed = None,
        embeds: List[Embed] = None,
        attachments: List[Attachment] = None,
        view: View = None,
        allowed_mentions: AllowedMentions = None,
        suppress_embeds: bool = False
    ) -> None:
        """Edit original message."""
    
    async def autocomplete(self, *, choices: List[Choice]) -> None:
        """Respond with autocomplete choices."""

class Namespace:
    """
    Container for command parameters.
    """
    def __init__(self, interaction: Interaction, data: InteractionData): ...
    
    def __getattr__(self, name: str) -> Any:
        """Get parameter value by name."""
    
    def __getitem__(self, name: str) -> Any:
        """Get parameter value by name."""
    
    def __contains__(self, name: str) -> bool:
        """Check if parameter exists."""
    
    def __iter__(self) -> Iterator[str]:
        """Iterate parameter names."""
    
    def get(self, name: str, default: Any = None) -> Any:
        """Get parameter value with default."""

Command Checks & Permissions

Permission validation and custom checks for application commands.

# Check decorators
def check(predicate: Callable[[Interaction], Awaitable[bool]]) -> Callable:
    """Add a check to a command."""

# Permission checks
def has_role(role: Union[int, str]) -> Callable:
    """Check if user has a specific role."""

def has_any_role(*roles: Union[int, str]) -> Callable:
    """Check if user has any of the specified roles."""

def has_permissions(**permissions: bool) -> Callable:
    """Check if user has specific permissions."""

def bot_has_permissions(**permissions: bool) -> Callable:
    """Check if bot has specific permissions."""

def default_permissions(**permissions: bool) -> Callable:
    """Set default permissions for the command."""

# Cooldown system
class Cooldown:
    """
    Application command cooldown.
    """
    def __init__(self, rate: int, per: float): ...
    
    rate: int  # Number of uses allowed
    per: float  # Time period in seconds

def cooldown(rate: int, per: float) -> Callable:
    """Add cooldown to a command."""

def dynamic_cooldown(cooldown_func: Callable[[Interaction], Optional[Cooldown]]) -> Callable:
    """Add dynamic cooldown to a command."""

Error Handling

Comprehensive error handling for application commands with specific exception types.

# Base application command errors
class AppCommandError(DiscordException):
    """Base exception for application command errors."""
    pass

class CommandInvokeError(AppCommandError):
    """Exception occurred during command execution."""
    def __init__(self, command: Union[Command, ContextMenu], e: Exception): ...
    command: Union[Command, ContextMenu]
    original: Exception

# Parameter errors
class TransformerError(AppCommandError):
    """Parameter transformer failed."""
    def __init__(self, value: Any, type: AppCommandOptionType, transformer: Type[Transformer]): ...
    value: Any
    type: AppCommandOptionType
    transformer: Type[Transformer]

# Command management errors  
class CommandAlreadyRegistered(AppCommandError):
    """Command is already registered."""
    def __init__(self, name: str, guild_id: Optional[int]): ...
    name: str
    guild_id: Optional[int]

class CommandSignatureMismatch(AppCommandError):
    """Command signature doesn't match Discord's requirements."""
    pass

class CommandNotFound(AppCommandError):
    """Command was not found."""
    def __init__(self, name: str, parents: List[str]): ...
    name: str
    parents: List[str]

class CommandLimitReached(AppCommandError):
    """Maximum number of commands reached."""
    def __init__(self, guild_id: Optional[int], limit: int, type: AppCommandType): ...
    guild_id: Optional[int]
    limit: int
    type: AppCommandType

# Check failures
class CheckFailure(AppCommandError):
    """Command check failed."""
    pass

class NoPrivateMessage(CheckFailure):
    """Command cannot be used in private messages."""
    pass

class MissingRole(CheckFailure):
    """User is missing required role."""
    def __init__(self, missing_role: Union[str, int]): ...
    missing_role: Union[str, int]

class MissingAnyRole(CheckFailure):
    """User is missing any of the required roles."""
    def __init__(self, missing_roles: List[Union[str, int]]): ...
    missing_roles: List[Union[str, int]]

class MissingPermissions(CheckFailure):
    """User is missing required permissions."""
    def __init__(self, missing_permissions: List[str]): ...
    missing_permissions: List[str]

class BotMissingPermissions(CheckFailure):
    """Bot is missing required permissions."""
    def __init__(self, missing_permissions: List[str]): ...
    missing_permissions: List[str]

class CommandOnCooldown(CheckFailure):
    """Command is on cooldown."""
    def __init__(self, cooldown: Cooldown, retry_after: float): ...
    cooldown: Cooldown
    retry_after: float

# Sync errors
class CommandSyncFailure(AppCommandError):
    """Failed to sync commands with Discord."""
    pass

class MissingApplicationID(CommandSyncFailure):
    """Application ID is missing."""
    pass

# Translation errors
class TranslationError(AppCommandError):
    """Translation failed."""
    def __init__(self, message: str, key: locale_str, locale: str): ...
    message: str
    key: locale_str
    locale: str

Localization Support

Built-in localization system for command names, descriptions, and responses.

class locale_str:
    """
    Represents a localizable string.
    """
    def __init__(self, message: str, **kwargs): ...
    
    message: str  # Base message string
    extras: Dict[str, Any]  # Extra data for formatting

class Translator:
    """
    Base class for command translators.
    """
    async def translate(self, string: locale_str, locale: str, context: TranslationContext) -> Optional[str]:
        """Translate a localizable string."""
        raise NotImplementedError

class TranslationContext:
    """
    Context for translation requests.
    """
    location: TranslationContextLocation  # Where translation is used
    data: Any  # Context-specific data

class TranslationContextLocation(Enum):
    """Location where translation is being performed."""
    command_name = 1
    command_description = 2
    parameter_name = 3
    parameter_description = 4
    choice_name = 5
    other = 6

TranslationContextTypes = Union[
    Command,
    ContextMenu, 
    Parameter,
    Choice,
    Group
]

Usage Examples

Basic Slash Command

import discord
from discord.ext import commands

class MyBot(commands.Bot):
    def __init__(self):
        intents = discord.Intents.default()
        super().__init__(command_prefix='!', intents=intents)
    
    async def setup_hook(self):
        # Sync commands on startup
        await self.tree.sync()
        print(f"Synced {len(self.tree.get_commands())} commands")

bot = MyBot()

@bot.tree.command(name="hello", description="Say hello to someone")
@app_commands.describe(user="The user to greet")
async def hello(interaction: discord.Interaction, user: discord.Member):
    await interaction.response.send_message(f"Hello {user.mention}!")

bot.run('YOUR_TOKEN')

Slash Command with Choices and Validation

@bot.tree.command(name="roll", description="Roll dice")
@app_commands.describe(
    sides="Number of sides on the die",
    count="Number of dice to roll"
)
@app_commands.choices(sides=[
    app_commands.Choice(name="4-sided (d4)", value=4),
    app_commands.Choice(name="6-sided (d6)", value=6),
    app_commands.Choice(name="8-sided (d8)", value=8),
    app_commands.Choice(name="10-sided (d10)", value=10),
    app_commands.Choice(name="12-sided (d12)", value=12),
    app_commands.Choice(name="20-sided (d20)", value=20),
])
async def roll_dice(
    interaction: discord.Interaction, 
    sides: app_commands.Choice[int],
    count: app_commands.Range[int, 1, 10] = 1
):
    import random
    
    rolls = [random.randint(1, sides.value) for _ in range(count)]
    total = sum(rolls)
    
    embed = discord.Embed(title="🎲 Dice Roll Results", color=0x00ff00)
    embed.add_field(name="Rolls", value=" + ".join(map(str, rolls)), inline=False)
    embed.add_field(name="Total", value=str(total), inline=True)
    embed.add_field(name="Dice", value=f"{count}d{sides.value}", inline=True)
    
    await interaction.response.send_message(embed=embed)

Context Menu Command

@bot.tree.context_menu(name="Get User Info")
async def user_info(interaction: discord.Interaction, user: discord.Member):
    embed = discord.Embed(title=f"Info for {user.display_name}", color=user.color)
    embed.set_thumbnail(url=user.display_avatar.url)
    embed.add_field(name="ID", value=user.id, inline=True)
    embed.add_field(name="Joined", value=f"<t:{int(user.joined_at.timestamp())}:R>", inline=True)
    embed.add_field(name="Roles", value=len(user.roles) - 1, inline=True)
    
    await interaction.response.send_message(embed=embed, ephemeral=True)

Command Group with Subcommands

@bot.tree.command(name="config", description="Bot configuration commands")
async def config_group(interaction: discord.Interaction):
    # This won't be called as it has subcommands
    pass

@config_group.subcommand(name="prefix", description="Set bot prefix")
@app_commands.describe(new_prefix="New command prefix")
async def config_prefix(interaction: discord.Interaction, new_prefix: str):
    # Update prefix logic here
    await interaction.response.send_message(f"Prefix set to `{new_prefix}`")

@config_group.subcommand(name="channel", description="Set bot channel")
@app_commands.describe(channel="Channel for bot commands")
async def config_channel(interaction: discord.Interaction, channel: discord.TextChannel):
    # Update channel logic here
    await interaction.response.send_message(f"Bot channel set to {channel.mention}")

Autocomplete Example

# Simple autocomplete
@bot.tree.command(name="timezone", description="Set your timezone")
async def timezone_command(interaction: discord.Interaction, timezone: str):
    # Timezone setting logic here
    await interaction.response.send_message(f"Timezone set to {timezone}")

@timezone_command.autocomplete('timezone')
async def timezone_autocomplete(interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]:
    timezones = ["UTC", "US/Eastern", "US/Central", "US/Mountain", "US/Pacific", "Europe/London", "Europe/Berlin"]
    return [
        app_commands.Choice(name=tz, value=tz)
        for tz in timezones if current.lower() in tz.lower()
    ][:25]  # Discord limits to 25 choices

Install with Tessl CLI

npx tessl i tessl/pypi-discord-py

docs

app-commands.md

commands-framework.md

core-objects.md

event-handling.md

index.md

user-interface.md

utilities.md

voice-audio.md

webhooks.md

tile.json