Components¶
- clsComponent.guard
- clsComponent.listener
- asynccomponent_after_invoke
- asynccomponent_before_invoke
- asynccomponent_command_error
- asynccomponent_load
- asynccomponent_teardown
- defextras
- defguards
- class twitchio.ext.commands.Component(*args: Any, **Kwargs: Any)¶
TwitchIO Component class.
Components are a powerful class used to help organize and manage commands, events, guards and errors.
This class inherits from a special metaclass which implements logic to help manage other parts of the TwitchIO commands extension together.
The Component must be added to your bot via
commands.Bot.add_component()
. After this class has been added, all commands and event listeners contained within the component will also be added to your bot.You can remove this Component and all the commands and event listeners associated with it via
commands.Bot.remove_component()
.There are two built-in methods of components that aid in doing any setup or teardown, when they are added and removed respectfully.
Below are some special methods of Components which are designed to be overriden when needed:
Components also implement some special decorators which can only be used inside of Components. The decorators are class method decorators and won’t need an instance of a Component to use.
Commands can beed added to Components with their respected decorators, and don’t need to be added to the bot, as they will be added when you add the component.
@commands.command()
@commands.group()
Note
This version of TwitchIO has not yet implemented the
modules
implementation ofcommands.ext
. This part ofcommands.ext
will allow you to easily load and unload separate python files that could contain components.Important
Due to the implementation of Components, you shouldn’t make a call to
super().__init__()
if you implement an__init__
on this component.Examples
class Bot(commands.Bot): # Do your required __init__ etc first... # You can use setup_hook to add components... async def setup_hook(self) -> None: await self.add_component(MyComponent()) class MyComponent(commands.Component): # Some simple commands... @commands.command() async def hi(self, ctx: commands.Command) -> None: await ctx.send(f"Hello {ctx.chatter.mention}!") @commands.command() async def apple(self, ctx: commands.Command, *, count: int) -> None: await ctx.send(f"You have {count} apples?!") # An example of using an event listener in a component... @commands.Component.listener() async def event_message(self, message: twitchio.ChatMessage) -> None: print(f"Received Message in component: {message.content}") # An example of a before invoke hook that is executed directly before any command in this component... async def component_before_invoke(self, ctx: commands.Command) -> None: print(f"Processing command in component '{self.name}'.")
- property name: str¶
Property returning the name of this component, this is either the qualified name of the class or the custom provided name if set.
- async component_command_error(payload: CommandErrorPayload) bool | None ¶
Event called when an error occurs in a command in this Component.
Similar to
event_command_error()
except only catches errors from commands within this Component.This method is intended to be overwritten, by default it does nothing.
Note
Explicitly returning
False
in this function will stop it being dispatched to any other error handler.
- async component_load() None ¶
Hook called when the component is about to be loaded into the bot.
You should use this hook to do any async setup required when loading a component. See:
component_teardown()
for a hook called when a Component is unloaded from the bot.This method is intended to be overwritten, by default it does nothing.
Important
If this method raises or fails, the Component will NOT be loaded. Instead it will be cleaned up and removed and the error will propagate.
- async component_teardown() None ¶
Hook called when the component is about to be unloaded from the bot.
You should use this hook to do any async teardown/cleanup required on the component. See:
component_load()
for a hook called when a Component is loaded into the bot.This method is intended to be overwritten, by default it does nothing.
- async component_before_invoke(ctx: Context) None ¶
Hook called before a
Command
in this Component is invoked.Similar to
before_invoke()
but only applies to commands in this Component.
- async component_after_invoke(ctx: Context) None ¶
Hook called after a
Command
has successfully invoked in this Component.Similar to
after_invoke()
but only applies to commands in this Component.
- extras() mappingproxy[Any, Any] ¶
Property returning a
types.MappingProxyType
of the extras applied to every command in this Component.
- guards() list[Callable[..., bool] | Callable[..., CoroC]] ¶
Property returning the guards applied to every command in this Component.
See:
commands.guard()
for more information on guards and how to use them.See:
guard()
for a way to apply guards to every command in this Component.
- @ listener(name: str | None = None) Any ¶
This function is a decorator.
A decorator which adds an event listener similar to
listener()
but contained within this component.Event listeners in components can listen to any dispatched event, and don’t interfere with their base implementation. See:
listener()
for more information on event listeners.By default, listeners use the name of the function wrapped for the event name. This can be changed by passing the name parameter.
Note
You can have multiple of the same event listener per component, see below for an example.
Examples
# By default if no name parameter is passed, the name of the event listened to is the same as the function... class MyComponent(commands.Component): @commands.Component.listener() async def event_message(self, payload: twitchio.ChatMessage) -> None: ...
# You can listen to two or more of the same event in a single component... # The name parameter should have the "event_" prefix removed... class MyComponent(commands.Component): @commands.Component.listener("message") async def event_message_one(self, payload: twitchio.ChatMessage) -> None: ... @commands.Component.listener("message") async def event_message_two(self, payload: twitchio.ChatMessage) -> None: ...
- Parameters
name (str) – The name of the event to listen to, E.g.
"event_message"
or simply"message"
.
- @ guard() Any ¶
This function is a decorator.
A decorator which wraps a standard function or coroutine function which should return either
True
orFalse
, and applies a guard to everyCommand
in this component.The wrapped function should take in one parameter
Context
the context surrounding command invocation, and return a bool indicating whether a command should be allowed to run.If the wrapped function returns
False
, the chatter will not be able to invoke the command and an error will be raised. If the wrapped function returnsTrue
the chatter will be able to invoke the command, assuming all the other guards also pass their predicate checks.See:
guard()
for more information on guards, what they do and how to use them.See:
global_guard()
for a global guard, applied to every command the bot has added.Example
class NotModeratorError(commands.GuardFailure): ... class MyComponent(commands.Component): # The guard below will be applied to every command contained in your component... # This guard raises our custom exception for easily identifying the error in our handler... @commands.Component.guard() def is_moderator(self, ctx: commands.Context) -> bool: if not ctx.chatter.moderator: raise NotModeratorError return True @commands.command() async def test(self, ctx: commands.Context) -> None: await ctx.reply(f"You are a moderator of {ctx.channel}") async def component_command_error(self, payload: commands.CommandErrorPayload) -> bool | None: error = payload.exception ctx = payload.context if isinstance(error, NotModeratorError): await ctx.reply("Only moderators can use this command!") # This explicit False return stops the error from being dispatched anywhere else... return False
- Raises
GuardFailure – The guard predicate returned
False
and prevented the chatter from using the command.