from dubious import callback as cb

dubious.callback.ta_CommandRet

A type alias that defines what a function stored in a Callback can return.

alias of ResponseMessage | ResponseAutocomplete | ResponseModal | None | Iterator[ResponseMessage | ResponseAutocomplete | ResponseModal | None]

dubious.callback.ps_CallbackArgs = ~ps_CallbackArgs

Represents the arguments for a function stored in a Callback.

class dubious.callback.t_CommandRet

Represents the return value for a function stored in a Callback.

alias of TypeVar(‘t_CommandRet’, bound=ResponseMessage | ResponseAutocomplete | ResponseModal | None | Iterator[ResponseMessage | ResponseAutocomplete | ResponseModal | None])

dubious.callback.do_callback(
callback: Callable[[ps_CallbackArgs], t_CommandRet],
ixn: Interaction,
data: ApplicationCommandData | MessageComponentData | ModalSubmitData | ApplicationCommandInteractionDataOption | None,
) t_CommandRet

Extracts options from an api.Interaction, and uses them as arguments to call a given callback function.

This is the “optionated” part of DubiousDiscord: The callback function’s signature can define keyword-specific arguments (i.e. arguments that come after *, in the signature) that do_callback() will take from the ixn api.Interaction object. Take an example callback function:

from dubious.discord import api
from dubious import pory

bot = pory.Pory("app id", "app key", "bot token")

@bot.on_command
def whereami(*, channel_id: api.Snowflake | None):
    if not channel_id:
        return api.ResponseMessage(content="We're nowhere! How's that possible?")
    else:
        return api.RepsonseMessage(content=f"We're in the <#{channel_id}> channel!")

The callback function asks for channel_id, which is a field on api.Interaction. do_callback() will find the channel_id field on the given ixn argument and give it to the callback function as a coresponding keyword argument.

Note that the api.Interaction.channel_id field has the type Snowflake | None. There’s no way to enforce this, but the callback function should reflect that type in the signature, as shown in the example. (Though, to be pedantic: In this particular example, the whereami function will never be called in response to a Modal Interaction, which is the only case in which channel_id could be None, so making channel_id in the signature None -able isn’t as big of a deal.)

class dubious.callback.Callback(name: str, __func__: Callable[[ps_CallbackArgs], t_CommandRet])

This dataclass holds a function along with an associated name.

The name allows it to be identified dynamically, so that it may be matched with e.g. a Discord interaction.

do(
ixn: Interaction,
data: ApplicationCommandData | MessageComponentData | ModalSubmitData | ApplicationCommandInteractionDataOption | None,
) ResponseMessage | ResponseAutocomplete | ResponseModal | None

Calls the wrapped function using data from an api.Interaction.

ixn and data are separate arguments because the api.Interaction.data field can be that of a subcommand group, whose options field has only one api.ApplicationCommandInteractionDataOption coresponding to the subcommand (or subcommand group) currently being called. do_callback() needs to have the api.ApplicationCommandInteractionDataOptions that corespond to the wrapped function’s arguments.

class dubious.callback.CallbackGroup(*, _options: dict[str, dubious.callback.Callback] = <factory>)
class dubious.callback.Command(name: str, __func__: ~typing.Callable[[~ps_CallbackArgs], ~dubious.callback.t_CommandRet], type: ApplicationCommandOptionType, description: str, default_member_permissions: str | None = None, guild_id: ~dubious.discord.disc.Snowflake | None = None, early_response: ~dubious.callback.t_CommandRet | None = None, *, name_localizations: dict[str, str] | None = None, description_localizations: dict[str, str] | None = None, required: bool | None = None, choices: list[ApplicationCommandOptionChoice] | None = None, options: list[ApplicationCommandOption] | None = None, channel_types: list[ChannelType] | None = None, min_value: int | float | None = None, max_value: int | float | None = None, min_length: int | None = None, max_length: int | None = None, autocomplete: bool | None = None, _options: dict[str, ~dubious.discord.api.ApplicationCommandOption] = <factory>)

This class contains a callback function to be matched against a Discord Interaction. It subclasses ApplicationCommandOption to vaguely match the structure of incoming commands.

Generally, this class isn’t meant to be instantiated manually. Instead, the right way to create an instance is to use a CommandGroup as a decorator around a callback function.

default_member_permissions: str | None = None

Defines the permissions required to use the command. This field comes from the api.ApplicationCommand class.

The API documentation marks it as a string, even though it’s mean to be a bitfield of api.Permission bits.

guild_id: Snowflake | None = None

Defining this can specify a guild in which to register the command to Discord.

class dubious.callback.CommandGroup(name: 'str', __func__: Callable[~ps_CallbackArgs, ~t_CommandRet], type: 'ApplicationCommandOptionType', description: 'str', default_member_permissions: str | None = None, guild_id: dubious.discord.disc.Snowflake | None = None, early_response: Optional[~t_CommandRet] = None, *, name_localizations: 'dict[str, str] | None' = None, description_localizations: 'dict[str, str] | None' = None, required: 'bool | None' = None, choices: 'list[ApplicationCommandOptionChoice] | None' = None, options: 'list[ApplicationCommandOption] | None' = None, channel_types: 'list[ChannelType] | None' = None, min_value: 'int | float | None' = None, max_value: 'int | float | None' = None, min_length: 'int | None' = None, max_length: 'int | None' = None, autocomplete: 'bool | None' = None, _options: dict[str, dubious.callback.Command] = <factory>)
group(name: str, desc: str, perms: Collection[Permission] | None = None, guild: Snowflake | None = None)

Adds a subcommand CommandGroup to this CommandGroup’s options and returns it.

do(
ixn: Interaction,
data: ApplicationCommandData | ApplicationCommandInteractionDataOption,
) ResponseMessage | ResponseAutocomplete | ResponseModal | None

Propagates an api.Interaction down to the subcommand callback it’s meant for.

In other words, this function extracts the appropriate subcommand Command object and calls the subcommand’s Callback.do(). If the subcommand is a CommandGroup, this function recurses by calling the subcommand’s CommandGroup.do().