Establishes initial documentation structure including introduction guide, API reference navigation, and MkDocs configuration with Material theme. Provides complete setup instructions, usage examples, and feature overview to help users get started with the Discord bot library.
Disagreement
A Python library for interacting with the Discord API, with a focus on bot development.
Features
- Asynchronous design using
aiohttp
- Gateway and HTTP API clients
- Slash command framework
- Message component helpers
- Built-in caching layer
- Experimental voice support
- Helpful error handling utilities
Installation
python -m pip install -U pip
pip install disagreement
# or install from source for development
pip install -e .
Requires Python 3.10 or newer.
To run the example scripts, you'll need the python-dotenv
package to load
environment variables. Install the development extras with:
pip install "disagreement[dev]"
Basic Usage
import asyncio
import os
import disagreement
from disagreement.ext import commands
from dotenv import load_dotenv
load_dotenv()
class Basics(commands.Cog):
def __init__(self, client: disagreement.Client) -> None:
super().__init__(client)
@commands.command()
async def ping(self, ctx: commands.CommandContext) -> None:
await ctx.reply(f"Pong! Gateway Latency: {self.client.latency_ms} ms.")
token = os.getenv("DISCORD_BOT_TOKEN")
if not token:
raise RuntimeError("DISCORD_BOT_TOKEN environment variable not set")
intents = disagreement.GatewayIntent.default() | disagreement.GatewayIntent.MESSAGE_CONTENT
client = disagreement.Client(token=token, command_prefix="!", intents=intents, mention_replies=True)
async def main() -> None:
client.add_cog(Basics(client))
await client.run()
if __name__ == "__main__":
asyncio.run(main())
Global Error Handling
To ensure unexpected errors don't crash your bot, you can enable the library's global error handler:
import disagreement
disagreement.setup_global_error_handler()
Call this early in your program to log unhandled exceptions instead of letting them terminate the process.
Configuring Logging
Use :func:disagreement.logging_config.setup_logging
to configure logging for
your bot. The helper accepts a logging level and an optional file path.
import logging
from disagreement.logging_config import setup_logging
setup_logging(logging.INFO)
# Or log to a file
setup_logging(logging.DEBUG, file="bot.log")
HTTP Session Options
Pass additional keyword arguments to aiohttp.ClientSession
using the
http_options
parameter when constructing :class:disagreement.Client
:
client = disagreement.Client(
token=token,
http_options={"proxy": "http://localhost:8080"},
)
These options are forwarded to HTTPClient
when it creates the underlying
aiohttp.ClientSession
. You can specify a custom connector
or any other
session parameter supported by aiohttp
.
Default Allowed Mentions
Specify default mention behaviour for all outgoing messages when constructing the client:
client = disagreement.Client(
token=token,
allowed_mentions={"parse": [], "replied_user": False},
)
This dictionary is used whenever send_message
is called without an explicit
allowed_mentions
argument.
Defining Subcommands with AppCommandGroup
from disagreement.ext.app_commands import AppCommandGroup, slash_command
from disagreement.ext.app_commands.context import AppCommandContext
settings_group = AppCommandGroup("settings", "Manage settings")
admin_group = AppCommandGroup("admin", "Admin settings", parent=settings_group)
@slash_command(name="show", description="Display a setting.", parent=settings_group)
async def show(ctx: AppCommandContext, key: str):
...
@slash_command(name="set", description="Update a setting.", parent=admin_group)
async def set_setting(ctx: AppCommandContext, key: str, value: str):
...
Fetching Guilds
Use Client.fetch_guild
to retrieve a guild from the Discord API if it
isn't already cached. This is useful when working with guild IDs from
outside the gateway events.
guild = await client.fetch_guild("123456789012345678")
roles = await client.fetch_roles(guild.id)
Sharding
To run your bot across multiple gateway shards, pass shard_count
when creating
the client:
client = disagreement.Client(token=BOT_TOKEN, shard_count=2)
If you want the library to determine the recommended shard count automatically,
use AutoShardedClient
:
client = disagreement.AutoShardedClient(token=BOT_TOKEN)
See examples/sharded_bot.py
for a full example.
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
See the docs directory for detailed guides on components, slash commands, caching, and voice features.
License
This project is licensed under the BSD 3-Clause license. See the LICENSE file for details.