refactor(init): Consolidate module imports and exports

This commit refactors the `disagreement/__init__.py` file to import and export new models, enums, and components.

The primary changes are:
- Add imports and exports for `Member`, `Role`, `Attachment`, `Channel`, `ActionRow`, `Button`, `SelectOption`, `SelectMenu`, `Embed`, `PartialEmoji`, `Section`, `TextDisplay`, `Thumbnail`, `UnfurledMediaItem`, `MediaGallery`, `MediaGalleryItem`, `Container`, and `Guild` from `disagreement.models`.
- Add imports and exports for `ButtonStyle`, `ChannelType`, `MessageFlags`, `InteractionType`, `InteractionCallbackType`, and `ComponentType` from `disagreement.enums`.
- Add `Interaction` from `disagreement.interactions`.
- Add `ui` and `ext` as top-level modules.
- Update `disagreement.ext/__init__.py` to expose `app_commands`, `commands`, and `tasks`.

These changes consolidate the library's public API, making new features more accessible.
The example files were also updated to use the direct imports from the `disagreement` package or its `ext` subpackage, improving readability and consistency.
This commit is contained in:
Slipstreamm 2025-06-14 18:17:57 -06:00
parent f58ffe8321
commit b039b2e948
15 changed files with 150 additions and 95 deletions

View File

@ -15,7 +15,30 @@ __copyright__ = "Copyright 2025 Slipstream"
__version__ = "0.4.2"
from .client import Client, AutoShardedClient
from .models import Message, User, Reaction, AuditLogEntry
from .models import (
Message,
User,
Reaction,
AuditLogEntry,
Member,
Role,
Attachment,
Channel,
ActionRow,
Button,
SelectOption,
SelectMenu,
Embed,
PartialEmoji,
Section,
TextDisplay,
Thumbnail,
UnfurledMediaItem,
MediaGallery,
MediaGalleryItem,
Container,
Guild,
)
from .voice_client import VoiceClient
from .audio import AudioSource, FFmpegAudioSource
from .typing import Typing
@ -29,11 +52,22 @@ from .errors import (
)
from .color import Color
from .utils import utcnow, message_pager
from .enums import GatewayIntent, GatewayOpcode
from .enums import (
GatewayIntent,
GatewayOpcode,
ButtonStyle,
ChannelType,
MessageFlags,
InteractionType,
InteractionCallbackType,
ComponentType,
)
from .error_handler import setup_global_error_handler
from .hybrid_context import HybridContext
from .ext import tasks
from .interactions import Interaction
from .logging_config import setup_logging
from . import ui, ext
import logging
@ -45,6 +79,23 @@ __all__ = [
"User",
"Reaction",
"AuditLogEntry",
"Member",
"Role",
"Attachment",
"Channel",
"ActionRow",
"Button",
"SelectOption",
"SelectMenu",
"Embed",
"PartialEmoji",
"Section",
"TextDisplay",
"Thumbnail",
"UnfurledMediaItem",
"MediaGallery",
"MediaGalleryItem",
"Container",
"VoiceClient",
"AudioSource",
"FFmpegAudioSource",
@ -60,10 +111,18 @@ __all__ = [
"message_pager",
"GatewayIntent",
"GatewayOpcode",
"ButtonStyle",
"ChannelType",
"MessageFlags",
"InteractionType",
"InteractionCallbackType",
"ComponentType",
"setup_global_error_handler",
"HybridContext",
"tasks",
"Interaction",
"setup_logging",
"ui",
"ext",
]

View File

@ -1 +1,3 @@
from . import app_commands, commands, tasks
__all__ = ["app_commands", "commands", "tasks"]

View File

@ -27,9 +27,16 @@ if os.path.join(os.getcwd(), "examples") == os.path.dirname(os.path.abspath(__fi
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
try:
import disagreement
from disagreement.models import Guild
from disagreement.ext import commands # Import the new commands extension
from disagreement import (
Client,
GatewayIntent,
Message,
Guild,
ext,
AuthenticationError,
DisagreementException,
)
from disagreement.ext import commands
except ImportError:
print(
"Failed to import disagreement. Make sure it's installed or PYTHONPATH is set correctly."
@ -59,15 +66,15 @@ BOT_TOKEN = os.environ.get("DISCORD_BOT_TOKEN")
# --- Intents Configuration ---
# Define the intents your bot needs. For basic message reading and responding:
intents = (
disagreement.GatewayIntent.GUILDS
| disagreement.GatewayIntent.GUILD_MESSAGES
| disagreement.GatewayIntent.MESSAGE_CONTENT
GatewayIntent.GUILDS
| GatewayIntent.GUILD_MESSAGES
| GatewayIntent.MESSAGE_CONTENT
) # MESSAGE_CONTENT is privileged!
# If you don't need message content and only react to commands/mentions,
# you might not need MESSAGE_CONTENT intent.
# intents = disagreement.GatewayIntent.default() # A good starting point without privileged intents
# intents |= disagreement.GatewayIntent.MESSAGE_CONTENT # Add if needed
# intents = GatewayIntent.default() # A good starting point without privileged intents
# intents |= GatewayIntent.MESSAGE_CONTENT # Add if needed
# --- Initialize the Client ---
if not BOT_TOKEN:
@ -76,7 +83,7 @@ if not BOT_TOKEN:
sys.exit(1)
# Initialize Client with a command prefix
client = disagreement.Client(token=BOT_TOKEN, intents=intents, command_prefix="!")
client = Client(token=BOT_TOKEN, intents=intents, command_prefix="!")
# --- Define a Cog for example commands ---
@ -177,7 +184,7 @@ async def on_ready():
@client.event
async def on_message(message: disagreement.Message):
async def on_message(message: Message):
"""Called when a message is created and received."""
# Command processing is now handled by the CommandHandler via client._process_message_for_commands
# This on_message can be used for other message-related logic if needed,
@ -210,11 +217,11 @@ async def main():
# client.add_cog is synchronous, but it schedules cog.cog_load() if it's async.
await client.run()
except disagreement.AuthenticationError:
except AuthenticationError:
print(
"Authentication failed. Please check your bot token and ensure it's correct."
)
except disagreement.DisagreementException as e:
except DisagreementException as e:
print(f"A Disagreement library error occurred: {e}")
except KeyboardInterrupt:
print("Bot shutting down due to KeyboardInterrupt...")

View File

@ -1,8 +1,11 @@
import os
import asyncio
from typing import Union, Optional
from disagreement import Client, ui, HybridContext
from disagreement.models import (
from typing import Union
from disagreement import (
Client,
ui,
ext,
HybridContext,
Message,
SelectOption,
User,
@ -19,24 +22,14 @@ from disagreement.models import (
MediaGallery,
MediaGalleryItem,
Container,
)
from disagreement.enums import (
ButtonStyle,
GatewayIntent,
ChannelType,
MessageFlags,
InteractionCallbackType,
MessageFlags,
)
from disagreement.ext.commands.cog import Cog
from disagreement.ext.commands.core import CommandContext
from disagreement.ext.app_commands.decorators import hybrid_command, slash_command
from disagreement.ext.app_commands.context import AppCommandContext
from disagreement.interactions import (
Interaction,
InteractionResponsePayload,
InteractionCallbackData,
)
from disagreement.ext.commands import Cog, CommandContext
from disagreement.ext.app_commands import AppCommandContext, hybrid_command
try:
from dotenv import load_dotenv

View File

@ -7,13 +7,12 @@ import sys
if os.path.join(os.getcwd(), "examples") == os.path.dirname(os.path.abspath(__file__)):
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from disagreement.client import Client
from disagreement import Client, User, Message
from disagreement.ext.app_commands import (
user_command,
message_command,
AppCommandContext,
)
from disagreement.models import User, Message
try:
from dotenv import load_dotenv

View File

@ -4,7 +4,7 @@
import asyncio
import os
import disagreement
from disagreement import Client, GatewayIntent
from disagreement.ext import commands
from dotenv import load_dotenv
@ -12,7 +12,7 @@ load_dotenv()
class Basics(commands.Cog):
def __init__(self, client: disagreement.Client) -> None:
def __init__(self, client: Client) -> None:
super().__init__(client)
@commands.command()
@ -24,12 +24,8 @@ 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
)
intents = GatewayIntent.default() | GatewayIntent.MESSAGE_CONTENT
client = Client(token=token, command_prefix="!", intents=intents, mention_replies=True)
async def main() -> None:

View File

@ -3,32 +3,27 @@ import os
import logging
from typing import Any, Optional, Literal, Union
from disagreement import HybridContext
from disagreement.client import Client
from disagreement.ext.commands.cog import Cog
from disagreement.ext.commands.core import CommandContext
from disagreement.ext.app_commands.decorators import (
slash_command,
user_command,
message_command,
hybrid_command,
)
from disagreement.ext.app_commands.commands import (
AppCommandGroup,
) # For defining groups
from disagreement.ext.app_commands.context import AppCommandContext # Added
from disagreement.models import (
from disagreement import (
HybridContext,
Client,
User,
Member,
Role,
Attachment,
Message,
Channel,
) # For type hints
from disagreement.enums import (
ChannelType,
) # For channel option type hints, assuming it exists
)
from disagreement.ext import commands
from disagreement.ext.commands import Cog, CommandContext
from disagreement.ext.app_commands import (
AppCommandContext,
AppCommandGroup,
slash_command,
user_command,
message_command,
hybrid_command,
)
# from disagreement.interactions import Interaction # Replaced by AppCommandContext

View File

@ -8,7 +8,7 @@ import sys
if os.path.join(os.getcwd(), "examples") == os.path.dirname(os.path.abspath(__file__)):
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from disagreement.client import Client
from disagreement import Client, Channel
from disagreement.models import TextChannel
try:

View File

@ -9,10 +9,9 @@ except ImportError: # pragma: no cover - example helper
load_dotenv = None
print("python-dotenv is not installed. Environment variables will not be loaded")
from disagreement import Client, ui
from disagreement.enums import GatewayIntent, TextInputStyle
from disagreement.ext.app_commands.decorators import slash_command
from disagreement.ext.app_commands.context import AppCommandContext
from disagreement import Client, ui, GatewayIntent
from disagreement.enums import TextInputStyle
from disagreement.ext.app_commands import slash_command, AppCommandContext
if load_dotenv:
load_dotenv()

View File

@ -11,9 +11,8 @@ except ImportError: # pragma: no cover - example helper
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from disagreement import Client, GatewayIntent, ui # type: ignore
from disagreement.ext.app_commands.decorators import slash_command
from disagreement.ext.app_commands.context import AppCommandContext
from disagreement import Client, GatewayIntent, ui
from disagreement.ext.app_commands import slash_command, AppCommandContext
if load_dotenv:
load_dotenv()

View File

@ -9,9 +9,8 @@ from typing import Set
if os.path.join(os.getcwd(), "examples") == os.path.dirname(os.path.abspath(__file__)):
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
import disagreement
from disagreement import Client, GatewayIntent, Member, Message
from disagreement.ext import commands
from disagreement.models import Member, Message
try:
from dotenv import load_dotenv
@ -28,18 +27,18 @@ if not BOT_TOKEN:
sys.exit(1)
intents = (
disagreement.GatewayIntent.GUILDS
| disagreement.GatewayIntent.GUILD_MESSAGES
| disagreement.GatewayIntent.MESSAGE_CONTENT
GatewayIntent.GUILDS
| GatewayIntent.GUILD_MESSAGES
| GatewayIntent.MESSAGE_CONTENT
)
client = disagreement.Client(token=BOT_TOKEN, command_prefix="!", intents=intents)
client = Client(token=BOT_TOKEN, command_prefix="!", intents=intents)
# Simple list of banned words
BANNED_WORDS: Set[str] = {"badword1", "badword2"}
class ModerationCog(commands.Cog):
def __init__(self, bot: disagreement.Client) -> None:
def __init__(self, bot: Client) -> None:
super().__init__(bot)
@commands.command()

View File

@ -25,9 +25,16 @@ if os.path.join(os.getcwd(), "examples") == os.path.dirname(os.path.abspath(__fi
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
try:
import disagreement
from disagreement import (
Client,
GatewayIntent,
Reaction,
User,
Member,
HTTPException,
AuthenticationError,
)
from disagreement.ext import commands
from disagreement.models import Reaction, User, Member
except ImportError:
print(
"Failed to import disagreement. Make sure it's installed or PYTHONPATH is set correctly."
@ -50,10 +57,10 @@ BOT_TOKEN = os.environ.get("DISCORD_BOT_TOKEN")
# We need GUILDS for server context, GUILD_MESSAGES to receive messages,
# and GUILD_MESSAGE_REACTIONS to listen for reaction events.
intents = (
disagreement.GatewayIntent.GUILDS
| disagreement.GatewayIntent.GUILD_MESSAGES
| disagreement.GatewayIntent.GUILD_MESSAGE_REACTIONS
| disagreement.GatewayIntent.MESSAGE_CONTENT # For commands
GatewayIntent.GUILDS
| GatewayIntent.GUILD_MESSAGES
| GatewayIntent.GUILD_MESSAGE_REACTIONS
| GatewayIntent.MESSAGE_CONTENT # For commands
)
# --- Initialize the Client ---
@ -61,7 +68,7 @@ if not BOT_TOKEN:
print("Error: The DISCORD_BOT_TOKEN environment variable is not set.")
sys.exit(1)
client = disagreement.Client(token=BOT_TOKEN, intents=intents, command_prefix="!")
client = Client(token=BOT_TOKEN, intents=intents, command_prefix="!")
# --- Define a Cog for reaction-related commands ---
@ -76,7 +83,7 @@ class ReactionCog(commands.Cog):
# The emoji can be a standard Unicode emoji or a custom one in the format '<:name:id>'
await ctx.message.add_reaction("👍")
print(f"Reacted to command from {ctx.author.username}")
except disagreement.HTTPException as e:
except HTTPException as e:
print(f"Failed to add reaction: {e}")
await ctx.reply(
"I couldn't add the reaction. I might be missing permissions."
@ -133,7 +140,7 @@ async def main():
try:
client.add_cog(ReactionCog(client))
await client.run()
except disagreement.AuthenticationError:
except AuthenticationError:
print("Authentication failed. Check your bot token.")
except Exception as e:
print(f"An unexpected error occurred: {e}")

View File

@ -8,7 +8,7 @@ import sys
if os.path.join(os.getcwd(), "examples") == os.path.dirname(os.path.abspath(__file__)):
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
import disagreement
from disagreement import Client
try:
from dotenv import load_dotenv
@ -23,7 +23,7 @@ TOKEN = os.environ.get("DISCORD_BOT_TOKEN")
if not TOKEN:
raise RuntimeError("DISCORD_BOT_TOKEN environment variable not set")
client = disagreement.Client(token=TOKEN, shard_count=2)
client = Client(token=TOKEN, shard_count=2)
@client.event

View File

@ -24,7 +24,7 @@ if os.path.join(os.getcwd(), "examples") == os.path.dirname(os.path.abspath(__fi
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
try:
import disagreement
from disagreement import Client, GatewayIntent, HTTPException, AuthenticationError
from disagreement.ext import commands
except ImportError:
print(
@ -46,9 +46,9 @@ BOT_TOKEN = os.environ.get("DISCORD_BOT_TOKEN")
# --- Intents Configuration ---
intents = (
disagreement.GatewayIntent.GUILDS
| disagreement.GatewayIntent.GUILD_MESSAGES
| disagreement.GatewayIntent.MESSAGE_CONTENT
GatewayIntent.GUILDS
| GatewayIntent.GUILD_MESSAGES
| GatewayIntent.MESSAGE_CONTENT
)
# --- Initialize the Client ---
@ -56,7 +56,7 @@ if not BOT_TOKEN:
print("Error: The DISCORD_BOT_TOKEN environment variable is not set.")
sys.exit(1)
client = disagreement.Client(token=BOT_TOKEN, intents=intents, command_prefix="!")
client = Client(token=BOT_TOKEN, intents=intents, command_prefix="!")
# --- Define a Cog for the typing indicator command ---
@ -76,7 +76,7 @@ class TypingCog(commands.Cog):
await asyncio.sleep(5)
print("Typing indicator stopped.")
await ctx.send("Done!")
except disagreement.HTTPException as e:
except HTTPException as e:
print(f"Failed to send typing indicator: {e}")
await ctx.reply(
"I couldn't show the typing indicator. I might be missing permissions."
@ -104,7 +104,7 @@ async def main():
try:
client.add_cog(TypingCog(client))
await client.run()
except disagreement.AuthenticationError:
except AuthenticationError:
print("Authentication failed. Check your bot token.")
except Exception as e:
print(f"An unexpected error occurred: {e}")

View File

@ -16,7 +16,7 @@ except ImportError: # pragma: no cover - example helper
load_dotenv = None
print("python-dotenv is not installed. Environment variables will not be loaded")
import disagreement
from disagreement import Client
if load_dotenv:
load_dotenv()
@ -39,7 +39,7 @@ CHANNEL_ID = cast(str, _CHANNEL_ID)
async def main() -> None:
client = disagreement.Client(TOKEN)
client = Client(TOKEN)
await client.connect()
voice = await client.join_voice(GUILD_ID, CHANNEL_ID)
try: