Plugins#

Plugins are structures that allow the grouping of multiple commands and listeners together. They could be considered synonymous to categories and will show up as such in the default help command.

Plugins can be added to and removed from the bot dynamically. When they are added, all of the commands and listeners contained within the plugin will be injected into the bot and will be usable.


Creating a Plugin#

To use plugins, you must first create a Plugin object and give it a name of your choice:

import lightbulb

plugin = lightbulb.Plugin("YourPluginName")

When you instantiate a plugin object, you can also include an option keyword argument include_datastore. When True this will create an instance of the lightbulb.utils.data_store.DataStore object inside the plugin, accessible through lightbulb.plugins.Plugin.d that you can use to store any state that you may want. If False, Plugin.d will be None.


Adding Items to Plugins#

The plugin class provides a method lightbulb.plugins.Plugin.command that allows you to register a command to the plugin object. This method can be used as a first or second order decorator, or called as a function with the command to add to the plugin.

import lightbulb

plugin = lightbulb.Plugin("ExamplePlugin")

# valid
@plugin.command
@lightbulb.command(...)
@lightbulb.implements(...)
async def foo(...):
    ...

# also valid
@plugin.command()
@lightbulb.command(...)
@lightbulb.implements(...)
async def foo(...):
    ...

# also valid
plugin.command(foo)

A similar method is provided to register listeners to the plugin: lightbulb.plugins.Plugin.listener. This method cannot be used as a first order decorator and must instead be used as a second order decorator or called as a function with the listener function to add to the plugin.

This method takes up to 3 arguments depending on how it is called. These are event (the event type to listen for), listener_func (this will be populated automatically if using as a decorator and can be ignored, otherwise this is the function to add to the plugin as a listener) and bind (this is a keyword argument and defines whether to bind the listener function to the plugin as a method or not, more on this later).

import hikari
import lightbulb

plugin = lightbulb.Plugin("ExamplePlugin")

# valid
@plugin.listener(hikari.Event)
async def foo(...):
    ...

# also valid
plugin.listener(hikari.Event, foo)

Plugin Checks#

The plugin class supplies a method lightbulb.plugins.Plugin.add_checks which allows you to register checks to the plugin instead of to commands. All checks added to a plugin will be run for every command defined within that plugin.

import lightbulb

plugin = lightbulb.Plugin("ExamplePlugin")
plugin.add_checks(lightbulb.owner_only, lightbulb.guild_only, ...)

Plugin Error Handling#

You can register a separate error handler function for all the commands within a given plugin using the supplied lightbulb.plugins.Plugin.set_error_handler method. This method can be used as a second order decorator or called as a normal function with the function to set the plugin’s error handler to. As with the listener and remove_hook methods, you can provide a bind kwarg to define whether or not the function should be bound to the plugin.

import lightbulb

plugin = lightbulb.Plugin("ExamplePlugin")

# valid
@plugin.set_error_handler()
async def foo(...):
    ...

# also valid
plugin.set_error_handler(foo)

Plugin Remove Hook#

You can register a hook function that will be run when the plugin is removed from the bot using the provided lightbulb.plugins.Plugin.remove_hook method. This can be used as a second order decorator or called as a function with the function to set the plugin’s remove hook to. This method also allows you to provide the bind kwarg to specify whether or not to bind the function to the plugin or not.

import lightbulb

plugin = lightbulb.Plugin("ExamplePlugin")

# valid
@plugin.remove_hook()
async def foo(...):
    ...

# also valid
plugin.remove_hook(foo)

Binding Functions to Plugins#

Some plugin methods allow you to bind a function to the plugin. This will call __get__ on the function you provide the method with before setting the appropriate plugin attribute. This will transform the function into a bound method, meaning it will be called with an additional argument (the equivalent of self, except outside of a class) which, when called will be the instance of the plugin that the function was bound to.

import hikari
import lightbulb

plugin = lightbulb.Plugin("ExamplePlugin")

# signature for unbound listener function
@plugin.listener(hikari.Event)
async def some_listener(event: hikari.Event) -> None:
    # this function is unbound, so will **only** be called with
    # the event instance that it was listening for
    ...

# signature for bound listener function
@plugin.listener(hikari.Event, bind=True)
async def some_listener(plugin: lightbulb.Plugin, event: hikari.Event) -> None
    # this function is **bound** so will be called with the plugin instance that it
    # was bound to when the event it is listening for is dispatched
    ...