Utils API Reference#

Data Store#

class lightbulb.utils.data_store.DataStore[source]#

Data storage class allowing setting, retrieval and unsetting of custom attributes. This class subclasses dict so the data can be accessed the same as you would a dictionary as well as using dot notation.

Example

>>> d = DataStore()
>>> d.foo = "bar"
>>> d.foo
'bar'
>>> d["foo"]
'bar'
>>> d
DataStore(foo='bar')
>>> d.pop("foo")
'bar'
>>> d
DataStore()

A DataStore instance is attached to BotApp instances as bot.d for your convenience.

get_as(item: str, type: Type[T]) T[source]#

Helper method to allow type-complete getting of items from this DataStore.

Parameters:
  • item (str) – The name of the key that the item is stored at.

  • type (Type[T]) – The type to cast the item as.

Returns:

The item stored at key item, cast to the given type.

Return type:

T

Raises:

ValueError – If a key of name item has not been set.

Note

This does not verify types, it just performs a typing.cast() to fool the type system into thinking that the return value is of the correct type.

New in version 2.2.4.


Nav#

class lightbulb.utils.nav.ButtonNavigator(pages: Iterable[T] | Iterator[T], *, buttons: Sequence[ComponentButton] | None = None, timeout: float = 120)[source]#

A button navigator system for navigating through a list of items that can be sent through the content argument of hikari.Message.respond.

Parameters:

pages (Sequence[T]) – Pages to navigate through.

Keyword Arguments:
  • buttons (Sequence[ComponentButton]) – Buttons to use the navigator with. Uses the default buttons if not specified.

  • timeout (float) – The navigator timeout in seconds. After the timeout has expired, navigator buttons are disabled and will no longer work. Defaults to 120 (2 minutes).

Example

from lightbulb.utils import pag, nav

@bot.command()
async def foo(ctx):
    paginated_help = pag.StringPaginator()
    for l in thing_that_creates_a_lot_of_text.split("\n"):
        paginated_help.add_line(l)
    navigator = nav.ButtonNavigator(paginated_help.build_pages())
    await navigator.run(ctx)
async run(context: context_.base.Context) None[source]#

Run the navigator under the given context.

Parameters:

context (Context) – Context to run the navigator under.

Returns:

None

class lightbulb.utils.nav.ComponentButton(label: str, label_is_emoji: bool, style: ~typing.Literal[<ButtonStyle.PRIMARY: 1>] | ~typing.Literal[1] | ~typing.Literal[<ButtonStyle.SECONDARY: 2>] | ~typing.Literal[2] | ~typing.Literal[<ButtonStyle.SUCCESS: 3>] | ~typing.Literal[3] | ~typing.Literal[<ButtonStyle.DANGER: 4>] | ~typing.Literal[4], custom_id: str, callback: ~typing.Callable[[~lightbulb.utils.nav.ButtonNavigator[~lightbulb.utils.nav.T], ~hikari.events.interaction_events.InteractionCreateEvent], ~typing.Coroutine[~typing.Any, ~typing.Any, None]])[source]#

A component-based navigator button. Contains the custom_id linked to the button as well as the coroutine to be called when the button is pressed.

Parameters:
  • label (str) – The label of the button.

  • label_is_emoji (bool) – Whether the label is an emoji or not. This affects whether set_label or set_emoji is called when building the button.

  • style (hikari.InteractiveButtonTypesT) – The style of the button.

  • custom_id (str) – The custom ID of the button.

  • callback – The coroutine function to be called on button press.

build(container: MessageActionRowBuilder, disabled: bool = False) None[source]#

Build and add the button to the given container.

Parameters:
Returns:

None

is_pressed(event: InteractionCreateEvent) bool[source]#

Check if the button is pressed in a given event.

Parameters:

event (InteractionCreateEvent) – The event to check the button is pressed in.

Returns:

Whether or not the button is pressed in the given event.

Return type:

bool

press(nav: ButtonNavigator[T], event: InteractionCreateEvent) Coroutine[Any, Any, None][source]#

Call the button’s callback coroutine and return the awaitable.

Returns:

Returned awaitable from the coroutine call.

Return type:

Coroutine[Any, Any, None]

class lightbulb.utils.nav.ReactionButton(emoji: str | Emoji, callback: Callable[[ReactionNavigator[T], ReactionAddEvent], Coroutine[Any, Any, None]])[source]#

A reaction-based navigator button. Contains the emoji linked to the button as well as the coroutine to be called when the button is pressed.

Parameters:
  • emoji (Union[str, Emoji]) – The emoji linked to the button.

  • callback – The coroutine function to be called on button press.

is_pressed(event: ReactionAddEvent) bool[source]#

Check if the button is pressed in a given event.

Parameters:

event (MessageReactionEvent) – The event to check the button is pressed in.

Returns:

Whether the button is pressed in the given event.

Return type:

bool

press(nav: ReactionNavigator[T], event: ReactionAddEvent) Coroutine[Any, Any, None][source]#

Call the button’s callback coroutine and return the awaitable.

Returns:

Returned awaitable from the coroutine call.

Return type:

Coroutine[None, Any, None]

class lightbulb.utils.nav.ReactionNavigator(pages: Iterable[T] | Iterator[T], *, buttons: Sequence[ReactionButton] | None = None, timeout: float = 120)[source]#

A reaction navigator system for navigating through a list of items that can be sent through the content argument of hikari.Message.respond.

Default buttons:

  • \N{BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}\N{VARIATION SELECTOR-16} (Go to first page)

  • \N{BLACK LEFT-POINTING TRIANGLE}\N{VARIATION SELECTOR-16} (Go to previous page)

  • \N{BLACK SQUARE FOR STOP}\\N{VARIATION SELECTOR-16} (Stop navigation)

  • \N{BLACK RIGHT-POINTING TRIANGLE}\N{VARIATION SELECTOR-16} (Go to next page)

  • \N{BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}\N{VARIATION SELECTOR-16} (Go to last page)

Parameters:

pages (Sequence[T]) – Pages to navigate through.

Keyword Arguments:
  • buttons (Optional[Sequence[NavButton]]) – Buttons to use the navigator with. Uses the default buttons if not specified.

  • timeout (float) – The navigator timeout in seconds. After the timeout has expired, navigator reactions will no longer work. Defaults to 120 (2 minutes).

Example

from lightbulb.utils import pag, nav

@bot.command()
async def foo(ctx):
    paginated_help = pag.StringPaginator()
    for l in thing_that_creates_a_lot_of_text.split("\n"):
        paginated_help.add_line(l)
    navigator = nav.ReactionNavigator(paginated_help.build_pages())
    await navigator.run(ctx)
async run(context: context_.base.Context) None[source]#

Run the navigator under the given context.

Parameters:

context (Context) – Context to run the navigator under.

Returns:

None

Raises:

hikari.MissingIntentError – If the bot does not have the relevant reaction intent(s) for the navigator to function.

async lightbulb.utils.nav.first_page(nav: ReactionNavigator[T] | ButtonNavigator[T], _: Event) None[source]#

NavButton callback to make the navigator go to the first page.

async lightbulb.utils.nav.last_page(nav: ReactionNavigator[T] | ButtonNavigator[T], _: Event) None[source]#

NavButton callback to make the navigator go to the last page.

async lightbulb.utils.nav.next_page(nav: ReactionNavigator[T] | ButtonNavigator[T], _: Event) None[source]#

NavButton callback to make the ReactionNavigator go to the next page.

async lightbulb.utils.nav.prev_page(nav: ReactionNavigator[T] | ButtonNavigator[T], _: Event) None[source]#

NavButton callback to make the navigator go to the previous page.

async lightbulb.utils.nav.stop(nav: ReactionNavigator[T] | ButtonNavigator[T], _: Event) None[source]#

NavButton callback to make the navigator stop navigation.


Pag#

class lightbulb.utils.pag.EmbedPaginator(*, max_lines: int | None = None, max_chars: int = 2048, prefix: str = '', suffix: str = '', line_separator: str = '\n')[source]#

Creates embed pages from lines of text according to the given parameters.

Text is added to the paginator the same way as StringPaginator. The paginated text will be run though the defined embed_factory(), or if no embed factory is defined then it will be inserted into the description of a default embed.

Keyword Arguments:
  • max_lines (Optional[ int ]) – The maximum number of lines per page. Defaults to None, meaning pages will use the max_chars param instead.

  • max_chars (int) – The maximum number of characters per page. Defaults to 2048, the max character limit for a discord message.

  • prefix (str) – The string to prefix every page with. Defaults to an empty string.

  • suffix (str) – The string to suffix every page with. Defaults to an empty string.

embed_factory() Callable[[Callable[[int, str], Embed]], Callable[[int, str], Embed]][source]#

A decorator to mark a function as the paginator’s embed factory. The page index and page content will be passed to the function when a new page is to be created.

Example

The following code will give each embed created a random colour.

from random import randint
from lightbulb.utils.pag import EmbedPaginator
from hikari import Embed

pag = EmbedPaginator()

@pag.embed_factory()
def build_embed(page_index, page_content):
    return Embed(description=page_content, colour=randint(0, 0xFFFFFF))
set_embed_factory(func: Callable[[int, str], Embed]) None[source]#

Method to set a callable as the paginator’s embed factory. Alternative to embed_factory().

Parameters:

func (Callable[ [ int, str ], Embed ]) – The callable to set as the paginator’s embed factory.

Returns:

None

See also

embed_factory()

class lightbulb.utils.pag.Paginator(*, max_lines: int | None = None, max_chars: int = 2000, prefix: str = '', suffix: str = '', line_separator: str = '\n', page_factory: ~typing.Callable[[int, str], ~lightbulb.utils.pag.T] = <function Paginator.<lambda>>)[source]#
add_line(line: Any) None[source]#

Add a line to the paginator.

Parameters:

line (Any) – The line to add to the paginator. Will be converted to a str.

Returns:

None

build_pages(page_number_start: int = 1) Iterator[T][source]#

The current pages that have been created.

Parameters:

page_number_start (int) – The page number to start at. Defaults to 1.

Returns:

Lazy generator of each page.

Return type:

Iterator[ T ]

new_page() None[source]#

Start a new page.

Returns:

None

class lightbulb.utils.pag.StringPaginator(*, max_lines: int | None = None, max_chars: int = 2000, prefix: str = '', suffix: str = '', line_separator: str = '\n')[source]#

Creates pages from lines of text according to the given parameters.

Text should be added to the paginator using add_line(), which will then be split up into an appropriate number of pages, accessible through pages.

Keyword Arguments:
  • max_lines (Optional[ int ]) – The maximum number of lines per page. Defaults to None, meaning pages will use the max_chars param instead.

  • max_chars (int) – The maximum number of characters per page. Defaults to 2000, the max character limit for a discord message.

  • prefix (str) – The string to prefix every page with. Defaults to an empty string.

  • suffix (str) – The string to suffix every page with. Defaults to an empty string.

Example

An example command using pagination to display all the guilds the bot is in.

from lightbulb.utils.pag import StringPaginator

@bot.command()
async def guilds(ctx):
    guilds = await bot.rest.fetch_my_guilds()
    pag = StringPaginator(max_lines=10)
    for n, guild in enumerate(guilds, start=1):
        pag.add_line(f"**{n}.** {guild.name}")
    for page in pag.build_pages():
        await ctx.respond(page)

Permissions#

lightbulb.utils.permissions.permissions_for(member: Member) Permissions[source]#

Get the guild permissions for the given member.

Parameters:

member (hikari.Member) – Member to get permissions for.

Returns:

Member’s guild permissions.

Return type:

hikari.Permissions

Warning

This method relies on the cache to work. If the cache is not available then hikari.Permissions.NONE will be returned.

lightbulb.utils.permissions.permissions_in(channel: PermissibleGuildChannel, member: Member, include_guild_permissions: bool = True) Permissions[source]#

Get the permissions for the given member in the given guild channel.

Parameters:
  • channel (hikari.GuildChannel) – Channel to get the permissions in.

  • member (hikari.Member) – Member to get the permissions for.

  • include_guild_permissions (bool) – Whether or not to include the member’s guild permissions. If False, only permissions granted by overwrites will be included. Defaults to True.

Returns:

Member’s permissions in the given channel.

Return type:

hikari.Permissions


Search#

lightbulb.utils.search.find(sequence: Iterable[T], predicate: Callable[[T], bool]) T | None[source]#

Find the first item from an iterable that passes for the predicate specified, or return None if no matching item was found.

Parameters:
  • sequence (Iterable[ T ]) – Iterable to search through.

  • predicate (Callable[ [ T ], bool ]) – Function to evaluate if the item is the correct one or not. It should return a boolean or boolean-like result.

Example

Searching for a member with a specific username in the bot’s cached members.

members = bot.get_members_view_for_guild(ctx.guild_id)
member = lightbulb.utils.find(members.values(), lambda m: m.username == "foo")

See also

get

lightbulb.utils.search.get(sequence: Iterable[T], **attrs: Any) T | None[source]#

Get the first item from an iterable that matches all the parameters specified, or return None if no matching item was found.

Parameters:

sequence (Iterable[ T ]) – Iterable to search through.

Keyword Arguments:

**attrs – Attributes to match.

Example

Searching for a member with a specific username in the bot’s cached members.

members = bot.get_members_view_for_guild(ctx.guild_id)
member = lightbulb.utils.get(members.values(), username="foo")

See also

find