starlight-dpy
starlight-dpy copied to clipboard
A utility library that she uses for discord.py
starlight-dpy
A utility library that she uses for discord.py
This 'library' is still in pre-alpha. This is still actively being develop and major changes may be made :3
Feel free to open an issue if you found any bugs!🌷
Do not use this in production.
Installation
pip install git+https://github.com/InterStella0/starlight-dpy
Help Command
Menu Help Command
Easily paginate your help command with little effort.
import starlight
import discord
from discord.ext import commands
bot = commands.Bot(
command_prefix="??",
help_command=starlight.MenuHelpCommand(
per_page=10,
accent_color=0xffcccb,
error_color=discord.Color.red()
),
intents=discord.Intents.all(),
description="Demonstration bot"
)
Output

Customizing
You can easily customize your help command by overriding format_* methods!
Format methods:
format_command_brief(cmd: commands.Command)format_cog_page(view: HelpMenuCog, data: List[commands.Command])format_bot_page(view: HelpMenuBot, mapping: Dict[Optional[commands.Cog], List[commands.Command]])format_group_detail(view: HelpMenuGroup)format_command_detail(view: HelpMenuCommand)format_error_detail(view: HelpMenuError)
Note:page suffix meant the View inherits SimplePaginationView
Example:
import starlight
import discord
from discord.ext import commands
class MyMenuHelpCommand(starlight.MenuHelpCommand):
async def format_bot_page(self, view, mapping):
return discord.Embed(
title="Help",
description="Choose a category to display your help command!",
color=self.accent_color
)
bot = commands.Bot(
command_prefix="??",
help_command=MyMenuHelpCommand(
per_page=10,
accent_color=0xffcccb,
error_color=discord.Color.red(),
pagination_buttons={
"start_button": discord.ui.Button(emoji="⏪", row=1),
"previous_button": discord.ui.Button(emoji="◀️", style=discord.ButtonStyle.blurple, row=1),
"stop_button": discord.ui.Button(emoji="⏹️", style=discord.ButtonStyle.red, row=1),
"next_button": discord.ui.Button(emoji="▶️", style=discord.ButtonStyle.blurple, row=1),
"end_button": discord.ui.Button(emoji="⏩", row=1)
}
),
intents=discord.Intents.all(),
description="Demonstration bot"
)
Output

Paginate Help Command
Uses buttons for navigation.
import starlight
import discord
from discord.ext import commands
bot = commands.Bot(
command_prefix="??",
help_command=starlight.PaginateHelpCommand(),
intents=discord.Intents.all()
)
Output

Help Hybrid Command
Hybrid is a term to implement both text and slash command in discord.py.
Injection
HelpCommand was explicitly only a text command.
For existing HelpCommand implementation, you can
change it to a hybrid, you can use starlight.convert_help_hybrid.
import starlight
from discord.ext import commands
my_help_command = commands.DefaultHelpCommand()
hybrid_help_command = starlight.convert_help_hybrid(my_help_command)
bot = commands.Bot(..., help_command=hybrid_help_command)
Once you sync your command. You can now use help command in slash command.
Note: convert_help_hybrid second argument is directly transfered to
the AppCommand parameters.
Inherits
For new implementation of helpcommand, you can directly inherits
starlight.HelpHybridCommand. This will have several helpful feature
to integrate with app command. with_app_command should also be
set to True
import starlight
from discord.ext import commands
class MyHelp(starlight.HelpHybridCommand):
async def send_bot_help(self, mapping, /) -> None:
no_command = len([c for cog in mapping.values() for c in cog])
response = f'I have `{no_command:,}` commands!'
await self.get_destination().send(response)
bot = commands.Bot(..., help_command=MyHelp(with_app_command=True))
Once you sync your command. You can now use help command in slash command.
Output

Views
Inline View
A shortcut for view handling.
Create inline view for distinct behaviours with `starlight.inline_view`.import starlight
import discord
@bot.command()
async def my_command(ctx):
view = discord.ui.View()
hi_button = discord.ui.Button(label="hi")
view.add_item(hi_button)
await ctx.send("hi", view=view)
async for interaction, item in starlight.inline_view(view):
if item is hi_button:
response = "hi"
else:
response = "unknown"
await interaction.response.send_message(response, ephemeral=True)
You can specify a discord.ui.Item to listen for a single item.
Effective when you're expecting only a single interaction.
result = None
async for interaction, item in starlight.inline_view(view, item=hi_button):
result = await view.get_my_result(interaction)
view.stop() # ensure only a single sequence
print("My Result:", result)
Note:
- Interaction callbacks are sequential due to async iterator.
- Always go for View subclasses whenever you can.
Pagination View
A simple pagination interface.
This was designed to not rely on discord.ext.menus due to lack of support
for Interaction. Majority of code that was present in discord.ext.menus
was dedicated for Reaction which has made it not ideal to be inherited.
import starlight
import discord
class MyPagination(starlight.SimplePaginationView):
async def format_page(self, interaction, data):
return discord.Embed(
title=f"Simple display[{self.current_page + 1}/{self.max_pages}]",
description="\n".join(data)
)
@bot.command()
async def my_command(ctx):
my_data = [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]
view = MyPagination(my_data, cache_page=True)
await view.start(ctx)
Note: You're required to chunk your data on your own. Tips:discord.utils.as_chunks
Supports commands.Paginator with .from_paginator classmethod.
Output

Inline Pagination
Paginating can have distinct formats which could cause boilerplate code. Which leads to the creation of Inline Pagination.
It works similarly with Inline View. With a slight change, `InlinePaginationItem` are yielded for you to respond it to have an effect to the message through `.format()` method.import starlight
import discord
@bot.command()
async def my_command(ctx):
my_data = [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]
view = starlight.SimplePaginationView(my_data, cache_page=True)
async for item in starlight.inline_pagination(view, context=ctx):
embed = discord.Embed(
title=f"Simple display[{view.current_page + 1}/{view.max_pages}]",
description="\n".join(item.data)
)
item.format(embed=embed) # keyword arguments are passed to `Message.edit`
The output of this code is the equivalent of the Pagination View example.
General Utility
Search
An extended version of discord.utils.get().
However, it is a filter that returns a sequence. This also supports for fuzzy matching as they are relatively common to be used within a discord bot.from starlight import search, Contains
# Contains is alias of ContainsFilter class
items_with_my_value = search(items, my_attr=Contains('my_value'))
# Equivalent of
items_contains_value = [item for item in items if 'my_value' in item.my_attr]
Flatten
Flatten nested iterables.
from starlight import flatten
arr = [[1, 2], [3, [4, 5], 6], 7, [8]]
arr_flatten = flatten(arr)
print(arr_flatten) # -> [1, 2, 3, 4, 5, 6, 7, 8]
Converters
Separator
Greedy behaviour with a separator instead of spaces as delimiter.
By default, this is set to ',' as the delimiter. It can be configured by passing 'separator' keyword argument.from starlight import star_commands
@star_commands.command(bot=bot) # this is required for separators
async def my_command(ctx, colours: star_commands.Separator[discord.Color], *, the_rest: str):
await ctx.send(f"{colours} | '{the_rest}'")
Output
