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

core-objects.mddocs/

Core Discord Objects

Essential Discord entities that form the foundation of all bot interactions. These objects represent users, servers, channels, messages, and other core Discord concepts with comprehensive attribute access and methods for common operations.

Capabilities

Client & Connection

The main client class manages the bot's connection to Discord, handles events, and provides access to the HTTP API and gateway connection.

class Client:
    """
    Main Discord client for bot connections and API access.
    
    Parameters:
    - intents: Intents object specifying which events to receive
    - heartbeat_timeout: Seconds to wait for heartbeat response (default: 60.0)
    - guild_ready_timeout: Seconds to wait for guild data (default: 2.0)
    - max_messages: Maximum messages to cache (default: 1000)
    """
    def __init__(
        self, 
        *, 
        intents: Intents,
        heartbeat_timeout: float = 60.0,
        guild_ready_timeout: float = 2.0,
        max_messages: Optional[int] = 1000
    ): ...
    
    async def start(self, token: str) -> None:
        """Start the client connection with the provided bot token."""
    
    async def close(self) -> None:
        """Close the connection and cleanup resources."""
    
    async def connect(self, *, reconnect: bool = True) -> None:
        """Connect to Discord's gateway."""
    
    async def login(self, token: str) -> None:
        """Login with the provided token without connecting."""
    
    def run(
        self, 
        token: str, 
        *, 
        reconnect: bool = True,
        log_handler: Optional[logging.Handler] = None,
        log_formatter: logging.Formatter = None,
        log_level: int = logging.INFO,
        root_logger: bool = False
    ) -> None:
        """Convenience method to login and connect with logging setup."""
    
    async def wait_until_ready(self) -> None:
        """Wait until the client is ready to process events."""
    
    # Properties
    user: Optional[ClientUser]  # The bot user
    guilds: List[Guild]  # List of guilds the bot is in
    users: List[User]  # Cached users
    cached_messages: List[Message]  # Cached messages
    latency: float  # WebSocket latency in seconds
    is_ready: bool  # Whether the client is ready
    is_closed: bool  # Whether the connection is closed

Users

User objects represent Discord accounts, including both regular users and the bot itself.

class User:
    """
    Represents a Discord user account.
    """
    id: int  # User's unique snowflake ID
    name: str  # Username (without discriminator for new usernames)
    discriminator: str  # User discriminator (0000 for new usernames)
    global_name: Optional[str]  # Display name
    avatar: Optional[Asset]  # User's avatar asset
    bot: bool  # Whether the user is a bot
    system: bool  # Whether the user is a system user
    created_at: datetime  # Account creation timestamp
    default_avatar: Asset  # Default avatar asset
    display_avatar: Asset  # Avatar or default if none
    mention: str  # Mention string (<@user_id>)
    
    async def create_dm(self) -> DMChannel:
        """Create a DM channel with this user."""
    
    def mentioned_in(self, message: Message) -> bool:
        """Check if user is mentioned in a message."""

class ClientUser(User):
    """
    Represents the bot user account with additional properties.
    """
    email: Optional[str]  # Bot's email (if available)
    verified: bool  # Whether email is verified
    mfa_enabled: bool  # Whether 2FA is enabled
    
    async def edit(self, *, username: str = None, avatar: bytes = None) -> ClientUser:
        """Edit the bot's profile."""

Members

Member objects represent users within the context of a specific guild, including guild-specific data like roles and permissions.

class Member(User):
    """
    Represents a guild member (user + guild-specific data).
    """
    nick: Optional[str]  # Member's nickname in the guild
    roles: List[Role]  # Member's roles (includes @everyone)
    joined_at: Optional[datetime]  # When member joined the guild
    premium_since: Optional[datetime]  # When member started boosting
    guild: Guild  # The guild this member belongs to
    voice: Optional[VoiceState]  # Member's voice state
    activities: List[Activity]  # Member's activities/presence
    status: Status  # Member's status (online, idle, dnd, offline)
    raw_status: str  # Raw status string
    mobile_status: Status  # Mobile client status
    desktop_status: Status  # Desktop client status
    web_status: Status  # Web client status
    guild_permissions: Permissions  # Member's guild-wide permissions
    display_name: str  # Nick or global_name or name
    display_avatar: Asset  # Guild avatar or user avatar
    
    async def edit(
        self, 
        *, 
        nick: str = None, 
        roles: List[Role] = None,
        mute: bool = None,
        deafen: bool = None,
        voice_channel: Optional[VoiceChannel] = None,
        timeout_until: Optional[datetime] = None
    ) -> None:
        """Edit member properties (requires permissions)."""
    
    async def add_roles(self, *roles: Role, reason: str = None) -> None:
        """Add roles to the member."""
    
    async def remove_roles(self, *roles: Role, reason: str = None) -> None:
        """Remove roles from the member."""
    
    async def ban(self, *, reason: str = None, delete_message_days: int = 1) -> None:
        """Ban the member from the guild."""
    
    async def kick(self, *, reason: str = None) -> None:
        """Kick the member from the guild."""
    
    async def timeout(self, until: datetime, *, reason: str = None) -> None:
        """Timeout the member until the specified time."""
    
    def permissions_in(self, channel: GuildChannel) -> Permissions:
        """Calculate member's permissions in a specific channel."""

Guilds

Guild objects represent Discord servers with comprehensive access to channels, members, roles, and server settings.

class Guild:
    """
    Represents a Discord guild (server).
    """
    id: int  # Guild's unique snowflake ID
    name: str  # Guild name
    icon: Optional[Asset]  # Guild icon asset
    splash: Optional[Asset]  # Guild splash asset
    discovery_splash: Optional[Asset]  # Guild discovery splash
    banner: Optional[Asset]  # Guild banner asset
    description: Optional[str]  # Guild description
    owner_id: int  # Guild owner's user ID
    owner: Optional[Member]  # Guild owner member object
    region: str  # Voice region
    verification_level: VerificationLevel  # Verification level required
    default_notifications: NotificationLevel  # Default notification setting
    explicit_content_filter: ContentFilter  # Content filter level
    features: List[str]  # Guild feature flags
    premium_tier: int  # Server boost level (0-3)
    premium_subscription_count: int  # Number of boosts
    member_count: int  # Total member count
    large: bool  # Whether guild is considered large (>250 members)
    max_members: int  # Maximum member limit
    max_presences: Optional[int]  # Maximum presence limit
    vanity_url_code: Optional[str]  # Vanity URL code
    premium_progress_bar_enabled: bool  # Whether boost progress bar is enabled
    created_at: datetime  # Guild creation timestamp
    
    # Collections
    members: List[Member]  # Guild members
    channels: List[GuildChannel]  # Guild channels
    roles: List[Role]  # Guild roles
    emojis: List[Emoji]  # Custom emojis
    stickers: List[GuildSticker]  # Custom stickers
    voice_channels: List[VoiceChannel]  # Voice channels only
    text_channels: List[TextChannel]  # Text channels only
    categories: List[CategoryChannel]  # Category channels only
    
    # Useful properties
    system_channel: Optional[TextChannel]  # System messages channel
    rules_channel: Optional[TextChannel]  # Rules channel
    public_updates_channel: Optional[TextChannel]  # Community updates channel
    me: Member  # Bot's member object in this guild
    
    async def leave(self) -> None:
        """Leave the guild."""
    
    async def delete(self) -> None:
        """Delete the guild (bot must be owner)."""
    
    async def edit(self, *, name: str = None, description: str = None, icon: bytes = None) -> Guild:
        """Edit guild properties."""
    
    async def create_text_channel(self, name: str, **options) -> TextChannel:
        """Create a new text channel."""
    
    async def create_voice_channel(self, name: str, **options) -> VoiceChannel:
        """Create a new voice channel."""
    
    async def create_category(self, name: str, **options) -> CategoryChannel:
        """Create a new category channel."""
    
    async def create_role(self, *, name: str = None, permissions: Permissions = None, **options) -> Role:
        """Create a new role."""
    
    async def ban(self, user: User, *, reason: str = None, delete_message_days: int = 1) -> None:
        """Ban a user from the guild."""
    
    async def unban(self, user: User, *, reason: str = None) -> None:
        """Unban a user from the guild."""
    
    async def kick(self, user: Member, *, reason: str = None) -> None:
        """Kick a member from the guild."""
    
    async def fetch_member(self, user_id: int) -> Member:
        """Fetch a member by ID."""
    
    async def fetch_ban(self, user: User) -> BanEntry:
        """Fetch ban information for a user."""
    
    def get_member(self, user_id: int) -> Optional[Member]:
        """Get a cached member by ID."""
    
    def get_channel(self, channel_id: int) -> Optional[GuildChannel]:
        """Get a cached channel by ID."""
    
    def get_role(self, role_id: int) -> Optional[Role]:
        """Get a cached role by ID."""

Channels

Channel objects represent different types of Discord channels with specialized functionality for text, voice, and organizational purposes.

class TextChannel:
    """
    Represents a guild text channel.
    """
    id: int  # Channel's unique snowflake ID
    name: str  # Channel name
    guild: Guild  # Guild this channel belongs to
    position: int  # Channel position in the list
    category: Optional[CategoryChannel]  # Parent category
    topic: Optional[str]  # Channel topic
    slowmode_delay: int  # Slowmode delay in seconds
    nsfw: bool  # Whether channel is age-restricted
    permissions_synced: bool  # Whether permissions sync with category
    created_at: datetime  # Channel creation timestamp
    mention: str  # Channel mention string (<#channel_id>)
    
    async def send(
        self, 
        content: str = None, 
        *, 
        embed: Embed = None,
        embeds: List[Embed] = None,
        file: File = None,
        files: List[File] = None,
        view: View = None,
        tts: bool = False,
        ephemeral: bool = False,
        allowed_mentions: AllowedMentions = None,
        reference: MessageReference = None
    ) -> Message:
        """Send a message to the channel."""
    
    async def edit(self, *, name: str = None, topic: str = None, position: int = None) -> TextChannel:
        """Edit channel properties."""
    
    async def delete(self, *, reason: str = None) -> None:
        """Delete the channel."""
    
    async def purge(self, *, limit: int = 100, check: Callable = None) -> List[Message]:
        """Bulk delete messages."""
    
    async def create_webhook(self, *, name: str, avatar: bytes = None) -> Webhook:
        """Create a webhook in this channel."""
    
    def history(self, *, limit: int = 100, before: datetime = None) -> AsyncIterator[Message]:
        """Iterate through channel message history."""
    
    def permissions_for(self, obj: Union[Member, Role]) -> Permissions:
        """Calculate permissions for a member or role."""

class VoiceChannel:
    """
    Represents a guild voice channel.
    """
    id: int  # Channel's unique snowflake ID
    name: str  # Channel name
    guild: Guild  # Guild this channel belongs to
    position: int  # Channel position
    category: Optional[CategoryChannel]  # Parent category
    bitrate: int  # Voice bitrate
    user_limit: int  # User limit (0 = unlimited)
    rtc_region: Optional[str]  # Voice server region
    video_quality_mode: int  # Video quality mode
    members: List[Member]  # Connected members
    
    async def connect(self, *, timeout: float = 60.0, reconnect: bool = True) -> VoiceClient:
        """Connect to the voice channel."""
    
    async def edit(self, *, name: str = None, bitrate: int = None, user_limit: int = None) -> VoiceChannel:
        """Edit voice channel properties."""

class DMChannel:
    """
    Represents a direct message channel.
    """
    id: int  # Channel ID
    recipient: User  # The other user in the DM
    me: ClientUser  # The bot user
    
    async def send(self, content: str = None, **kwargs) -> Message:
        """Send a DM message."""

class CategoryChannel:
    """
    Represents a channel category for organization.
    """
    id: int  # Category ID
    name: str  # Category name
    guild: Guild  # Guild this category belongs to
    position: int  # Category position
    channels: List[GuildChannel]  # Channels in this category
    
    async def create_text_channel(self, name: str, **options) -> TextChannel:
        """Create a text channel in this category."""
    
    async def create_voice_channel(self, name: str, **options) -> VoiceChannel:
        """Create a voice channel in this category."""

Messages

Message objects represent Discord messages with comprehensive metadata, content access, and interaction methods.

class Message:
    """
    Represents a Discord message.
    """
    id: int  # Message's unique snowflake ID
    channel: Union[TextChannel, DMChannel, GroupChannel]  # Channel message was sent in
    guild: Optional[Guild]  # Guild if sent in a guild channel
    author: Union[User, Member]  # Message author
    content: str  # Message text content
    clean_content: str  # Content with mentions resolved
    created_at: datetime  # Message creation timestamp
    edited_at: Optional[datetime]  # Last edit timestamp
    tts: bool  # Whether message is text-to-speech
    mention_everyone: bool  # Whether message mentions @everyone
    mentions: List[Union[User, Member]]  # Mentioned users
    channel_mentions: List[GuildChannel]  # Mentioned channels
    role_mentions: List[Role]  # Mentioned roles
    attachments: List[Attachment]  # File attachments
    embeds: List[Embed]  # Rich embeds
    reactions: List[Reaction]  # Message reactions
    pinned: bool  # Whether message is pinned
    type: MessageType  # Message type (default, reply, etc.)
    system_content: Optional[str]  # System message content
    flags: MessageFlags  # Message flags
    reference: Optional[MessageReference]  # Reference to replied message
    components: List[Component]  # UI components attached
    
    async def edit(
        self, 
        *, 
        content: str = None, 
        embed: Embed = None,
        embeds: List[Embed] = None,
        attachments: List[Attachment] = None,
        view: View = None
    ) -> Message:
        """Edit the message (bot must be author)."""
    
    async def delete(self, *, delay: float = None) -> None:
        """Delete the message."""
    
    async def pin(self, *, reason: str = None) -> None:
        """Pin the message."""
    
    async def unpin(self, *, reason: str = None) -> None:
        """Unpin the message."""
    
    async def add_reaction(self, emoji: Union[Emoji, str]) -> None:
        """Add a reaction to the message."""
    
    async def remove_reaction(self, emoji: Union[Emoji, str], member: Member) -> None:
        """Remove a reaction from the message."""
    
    async def clear_reactions(self) -> None:
        """Clear all reactions from the message."""
    
    async def reply(self, content: str = None, **kwargs) -> Message:
        """Reply to the message."""
    
    def to_reference(self) -> MessageReference:
        """Create a message reference for replies."""

class Attachment:
    """
    Represents a message file attachment.
    """
    id: int  # Attachment ID
    filename: str  # Original filename
    description: Optional[str]  # Alt text description
    content_type: Optional[str]  # MIME type
    size: int  # File size in bytes
    url: str  # Attachment URL
    proxy_url: str  # Proxied URL
    height: Optional[int]  # Image/video height
    width: Optional[int]  # Image/video width
    ephemeral: bool  # Whether attachment is ephemeral
    
    async def save(self, fp: Union[str, bytes, os.PathLike], *, seek_begin: bool = True) -> int:
        """Save attachment to file."""
    
    async def read(self) -> bytes:
        """Read attachment data."""
    
    def to_file(self) -> File:
        """Convert to a File object for re-uploading."""

Roles & Permissions

Role and permission objects manage access control and user organization within guilds.

class Role:
    """
    Represents a guild role.
    """
    id: int  # Role's unique snowflake ID
    name: str  # Role name
    guild: Guild  # Guild this role belongs to
    colour: Colour  # Role color
    color: Colour  # Alias for colour
    hoist: bool  # Whether role is displayed separately
    position: int  # Role position in hierarchy
    managed: bool  # Whether role is managed by integration
    mentionable: bool  # Whether role can be mentioned
    permissions: Permissions  # Role permissions
    tags: Optional[RoleTags]  # Role tags (bot, premium subscriber, etc.)
    created_at: datetime  # Role creation timestamp
    mention: str  # Role mention string (<@&role_id>)
    members: List[Member]  # Members with this role
    
    async def edit(
        self, 
        *, 
        name: str = None, 
        permissions: Permissions = None,
        colour: Colour = None,
        hoist: bool = None,
        mentionable: bool = None,
        position: int = None
    ) -> Role:
        """Edit role properties."""
    
    async def delete(self, *, reason: str = None) -> None:
        """Delete the role."""
    
    def is_default(self) -> bool:
        """Check if this is the @everyone role."""
    
    def is_bot_managed(self) -> bool:
        """Check if role is managed by a bot."""
    
    def is_premium_subscriber(self) -> bool:
        """Check if role is the premium subscriber role."""

class Permissions:
    """
    Represents Discord permissions as a bitfield.
    """
    value: int  # Permission bitfield value
    
    def __init__(self, permissions: int = 0): ...
    
    @classmethod
    def none(cls) -> Permissions:
        """Create permissions with no flags set."""
    
    @classmethod
    def all(cls) -> Permissions:
        """Create permissions with all flags set."""
    
    @classmethod
    def all_channel(cls) -> Permissions:
        """Create permissions with all channel-specific flags."""
    
    @classmethod
    def general(cls) -> Permissions:
        """Create permissions with general flags."""
    
    @classmethod
    def text(cls) -> Permissions:
        """Create permissions with text channel flags."""
    
    @classmethod
    def voice(cls) -> Permissions:
        """Create permissions with voice channel flags."""
    
    @classmethod
    def stage(cls) -> Permissions:
        """Create permissions with stage channel flags."""
    
    # Permission properties (read/write)
    create_instant_invite: bool
    kick_members: bool
    ban_members: bool
    administrator: bool
    manage_channels: bool
    manage_guild: bool
    add_reactions: bool
    view_audit_log: bool
    priority_speaker: bool
    stream: bool
    read_messages: bool
    view_channel: bool  # Alias for read_messages
    send_messages: bool
    send_tts_messages: bool
    manage_messages: bool
    embed_links: bool
    attach_files: bool
    read_message_history: bool
    mention_everyone: bool
    external_emojis: bool
    use_external_emojis: bool  # Alias for external_emojis
    view_guild_insights: bool
    connect: bool
    speak: bool
    mute_members: bool
    deafen_members: bool
    move_members: bool
    use_voice_activation: bool
    change_nickname: bool
    manage_nicknames: bool
    manage_roles: bool
    manage_permissions: bool  # Alias for manage_roles
    manage_webhooks: bool
    manage_emojis: bool
    manage_emojis_and_stickers: bool
    use_application_commands: bool
    use_slash_commands: bool  # Alias for use_application_commands
    request_to_speak: bool
    manage_events: bool
    manage_threads: bool
    create_public_threads: bool
    create_private_threads: bool
    external_stickers: bool
    use_external_stickers: bool  # Alias for external_stickers
    send_messages_in_threads: bool
    start_embedded_activities: bool
    moderate_members: bool
    
    def update(self, **kwargs) -> None:
        """Update multiple permission flags."""
    
    def is_subset(self, other: Permissions) -> bool:
        """Check if permissions are a subset of another."""
    
    def is_superset(self, other: Permissions) -> bool:
        """Check if permissions are a superset of another."""
    
    def is_strict_subset(self, other: Permissions) -> bool:
        """Check if permissions are a strict subset."""
    
    def is_strict_superset(self, other: Permissions) -> bool:
        """Check if permissions are a strict superset."""

Emojis & Assets

Emoji and asset objects provide access to Discord's custom emojis and media assets like avatars and icons.

class Emoji:
    """
    Represents a custom guild emoji.
    """
    id: int  # Emoji's unique snowflake ID
    name: str  # Emoji name
    guild: Guild  # Guild this emoji belongs to
    animated: bool  # Whether emoji is animated
    managed: bool  # Whether emoji is managed by integration
    require_colons: bool  # Whether emoji requires colons
    roles: List[Role]  # Roles that can use this emoji
    user: Optional[User]  # User who created the emoji
    available: bool  # Whether emoji is available for use
    created_at: datetime  # Emoji creation timestamp
    url: str  # Emoji image URL
    
    async def edit(self, *, name: str = None, roles: List[Role] = None) -> Emoji:
        """Edit emoji properties."""
    
    async def delete(self, *, reason: str = None) -> None:
        """Delete the emoji."""
    
    def __str__(self) -> str:
        """Return emoji string for sending in messages."""

class PartialEmoji:
    """
    Represents a partial emoji (from reactions, etc.).
    """
    id: Optional[int]  # Emoji ID (None for unicode)
    name: str  # Emoji name or unicode character
    animated: bool  # Whether emoji is animated
    
    def __str__(self) -> str:
        """Return emoji string."""
    
    @property
    def url(self) -> Optional[str]:
        """Emoji URL if custom emoji."""

class Asset:
    """
    Represents a Discord CDN asset (avatar, icon, etc.).
    """
    url: str  # Asset URL
    key: str  # Asset key/hash
    
    def replace(self, *, size: int = None, format: str = None, static_format: str = None) -> Asset:
        """Create a new asset with different parameters."""
    
    def with_size(self, size: int) -> Asset:
        """Create asset with specific size."""
    
    def with_format(self, format: str) -> Asset:
        """Create asset with specific format."""
    
    def with_static_format(self, format: str) -> Asset:
        """Create asset with static format."""
    
    async def save(self, fp: Union[str, bytes, os.PathLike], *, seek_begin: bool = True) -> int:
        """Save asset to file."""
    
    async def read(self) -> bytes:
        """Read asset data."""

Error Handling

# Base Exceptions
class DiscordException(Exception):
    """Base exception for discord.py."""
    pass

class ClientException(DiscordException):
    """Exception for client-side errors."""
    pass

# Connection Exceptions
class GatewayNotFound(DiscordException):
    """Gateway URL could not be found."""
    pass

class ConnectionClosed(ClientException):
    """WebSocket connection was closed."""
    def __init__(self, socket, *, shard_id: int, code: int = None): ...
    shard_id: int
    code: Optional[int]

# HTTP Exceptions  
class HTTPException(DiscordException):
    """Exception for HTTP request errors."""
    def __init__(self, response, message: str): ...
    response: aiohttp.ClientResponse
    status: int
    code: int
    text: str

class Forbidden(HTTPException):
    """403 Forbidden HTTP error."""
    pass

class NotFound(HTTPException):
    """404 Not Found HTTP error."""
    pass

class DiscordServerError(HTTPException):
    """5xx server error."""
    pass

class RateLimited(HTTPException):
    """429 Rate Limited error."""
    retry_after: float

# Authentication Exceptions
class LoginFailure(ClientException):
    """Invalid authentication credentials."""
    pass

class PrivilegedIntentsRequired(ClientException):
    """Bot requires privileged intents."""
    pass

# Data Exceptions
class InvalidData(ClientException):
    """Invalid or unexpected data received."""
    pass

class InvalidArgument(ClientException):
    """Invalid argument passed to function."""
    pass

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