-
Notifications
You must be signed in to change notification settings - Fork 0
Framework Extensions
Hunter edited this page Jan 15, 2026
·
3 revisions
This document describes the enhanced utilities and extensions available in the Wisp Framework to make bot development easier.
See also: Module-Development | Examples | API-Reference
Create common embed patterns easily:
from wisp_framework.utils.embeds import EmbedBuilder, create_success_embed
# Success embed (green)
embed = EmbedBuilder.success(
title="Operation Complete",
description="The task finished successfully",
fields=[
{"name": "Status", "value": "✅ Done", "inline": True}
]
)
# Error embed (red)
embed = EmbedBuilder.error(
title="Operation Failed",
description="Something went wrong"
)
# Info embed (blue)
embed = EmbedBuilder.info(
title="Information",
description="Here's some info"
)
# Warning embed (orange)
embed = EmbedBuilder.warning(
title="Warning",
description="Be careful!"
)
# List embed with pagination
embed = EmbedBuilder.list_embed(
title="Items",
items=["Item 1", "Item 2", "Item 3"],
page=1,
items_per_page=10
)
# Table embed
embed = EmbedBuilder.table_embed(
title="Data Table",
headers=["Name", "Value"],
rows=[["Item 1", "100"], ["Item 2", "200"]]
)Simplified response sending:
from wisp_framework.utils.responses import (
respond_success,
respond_error,
respond_info,
respond_embed
)
# Success response
await respond_success(
interaction,
"Operation completed!",
embed=embed,
ephemeral=True
)
# Error response
await respond_error(
interaction,
"Something went wrong",
ephemeral=True
)
# Info response
await respond_info(
interaction,
"Here's some information",
ephemeral=True
)
# Send embed
await respond_embed(interaction, embed, ephemeral=True)Paginate long lists of items:
from wisp_framework.utils.pagination import paginate_embeds
# Create multiple embeds
embeds = [
EmbedBuilder.list_embed(title="Page 1", items=items[:10], page=1),
EmbedBuilder.list_embed(title="Page 2", items=items[10:20], page=2),
]
# Paginate with buttons
await paginate_embeds(interaction, embeds, timeout=300.0, ephemeral=True)Add cooldowns to commands:
from wisp_framework.utils.cooldowns import cooldown
@tree.command(name="spam")
@cooldown(seconds=5.0, per_user=True)
async def spam_command(interaction: discord.Interaction):
await respond_success(interaction, "Command executed!")Useful decorators for commands:
from wisp_framework.utils.decorators import (
require_guild,
require_admin,
require_owner,
handle_errors
)
@tree.command(name="guild-only")
@require_guild
async def guild_command(interaction: discord.Interaction):
# Only works in servers
pass
@tree.command(name="admin-only")
@require_admin
async def admin_command(interaction: discord.Interaction):
# Requires admin permissions
pass
@tree.command(name="owner-only")
@require_owner(config) # Pass config
async def owner_command(interaction: discord.Interaction):
# Only bot owner
pass
@tree.command(name="safe")
@handle_errors
async def safe_command(interaction: discord.Interaction):
# Errors are caught and displayed to user
raise ValueError("This will be caught!")Confirmation dialogs for destructive actions:
from wisp_framework.utils.confirmations import confirm_action
async def delete_handler(interaction: discord.Interaction):
# Handle deletion
await respond_success(interaction, "Deleted!")
await confirm_action(
interaction,
"Are you sure you want to delete this?",
on_confirm=delete_handler,
timeout=60.0
)Organize commands into groups:
from wisp_framework.utils.command_groups import CommandGroup
# Create group
admin_group = CommandGroup("admin", "Admin commands", guild_only=True)
admin_group.create_group(bot.tree)
# Add commands to group
@admin_group.command(name="kick", description="Kick a user")
async def kick_command(interaction: discord.Interaction, user: discord.Member):
await respond_success(interaction, f"Kicked {user.mention}")Create interactive UI components:
from wisp_framework.utils.views import ButtonView
view = ButtonView(timeout=300.0)
view.add_button(
label="Click Me",
style=discord.ButtonStyle.primary,
callback=lambda i: respond_success(i, "Button clicked!")
)
await interaction.response.send_message("Choose an option:", view=view)Add middleware for cross-cutting concerns:
from wisp_framework.utils.middleware import (
MiddlewareChain,
LoggingMiddleware,
MetricsMiddleware
)
# Create middleware chain
chain = MiddlewareChain(
LoggingMiddleware(),
MetricsMiddleware(metrics_service)
)
# Use in command
@tree.command(name="test")
async def test_command(interaction: discord.Interaction):
await chain.execute(interaction, my_handler)Mock objects for testing:
from wisp_framework.utils.testing import (
create_mock_interaction,
create_mock_bot,
create_mock_context
)
# Create mocks
interaction = create_mock_interaction(user_id=123456)
bot = create_mock_bot()
ctx = create_mock_context()
# Use in tests
await my_module.setup(bot, ctx)Generate templates:
# Create a module template
wisp-framework-cli create-module my_module --output-dir modules/
# Create a bot template
wisp-framework-cli create-bot my_bot --output-dir .- Use embed builders for consistent styling
- Use response helpers for consistent responses
- Add cooldowns to prevent spam
- Use decorators for common checks
- Use pagination for long lists
- Use confirmations for destructive actions
- Use middleware for logging/metrics
- Use command groups to organize commands
from typing import Any
import discord
from wisp_framework.module import Module
from wisp_framework.utils.decorators import require_guild, handle_errors
from wisp_framework.utils.embeds import EmbedBuilder
from wisp_framework.utils.responses import respond_success
from wisp_framework.utils.cooldowns import cooldown
class MyModule(Module):
@property
def name(self) -> str:
return "my_module"
async def setup(self, bot: Any, ctx: Any) -> None:
@bot.tree.command(name="example")
@require_guild
@handle_errors
@cooldown(seconds=5.0)
async def example(interaction: discord.Interaction):
embed = EmbedBuilder.success(
title="Success",
description="Command executed!"
)
await respond_success(interaction, "Done!", embed=embed)