tanjun.annotations#
Parameter annotation based strategy for declaring slash and message command arguments.
Community Resources:
- An extended implementation of this which parses callback docstrings to get the descriptions for slash commands and their options can be found in https://github.com/FasterSpeeding/Tan-chan.
Attachment
module-attribute
#
Attachment = typing.Annotated[hikari.Attachment, _OptionMarker(hikari.Attachment)]
An argument which accepts a file.
Warning
This is currently only supported for slash commands.
Bool
module-attribute
#
Bool = typing.Annotated[bool, _OptionMarker(bool)]
An argument which takes a bool-like value.
Channel
module-attribute
#
Channel = typing.Annotated[hikari.PartialChannel, _OptionMarker(hikari.PartialChannel)]
An argument which takes a channel.
hikari.InteractionChannel will be passed for options typed as this when being called as a slash command.
Color
module-attribute
#
Color = typing.Annotated[hikari.Color, Converted(conversion.to_color)]
An argument which takes a color.
Datetime
module-attribute
#
Datetime = typing.Annotated[datetime.datetime, Converted(conversion.to_datetime)]
An argument which takes a datetime.
Float
module-attribute
#
Float = typing.Annotated[float, _OptionMarker(float)]
An argument which takes a floating point number.
Int
module-attribute
#
Int = typing.Annotated[int, _OptionMarker(int)]
An argument which takes an integer.
InteractionChannel
module-attribute
#
InteractionChannel = typing.Annotated[hikari.InteractionChannel, _OptionMarker(hikari.InteractionChannel)]
An argument which takes a channel with interaction specific metadata.
Warning
This is only supported for slash commands and will not work for message commands (unlike annotations.Channel).
InteractionMember
module-attribute
#
InteractionMember = typing.Annotated[hikari.InteractionMember, _OptionMarker(hikari.InteractionMember)]
An argument which takes a guild member with interaction specific metadata.
Warning
This is only supported for slash commands and will not work for message commands (unlike annotations.Member).
Member
module-attribute
#
Member = typing.Annotated[hikari.Member, _OptionMarker(hikari.Member)]
An argument which takes a guild member.
hikari.InteractionMember will be passed for options typed as this when being called as a slash command.
Mentionable
module-attribute
#
Mentionable = typing.Annotated[typing.Union[hikari.User, hikari.Role], _OptionMarker(_MentionableUnion)]
An argument which takes a user or role.
Role
module-attribute
#
Role = typing.Annotated[hikari.Role, _OptionMarker(hikari.Role)]
An argument which takes a role.
Snowflake
module-attribute
#
Snowflake = typing.Annotated[hikari.Snowflake, Converted(conversion.parse_snowflake)]
An argument which takes a snowflake.
Str
module-attribute
#
Str = typing.Annotated[str, _OptionMarker(str)]
An argument which takes string input.
User
module-attribute
#
User = typing.Annotated[hikari.User, _OptionMarker(hikari.User)]
An argument which takes a user.
Choices #
Bases: _ConfigIdentifier
Assign up to 25 choices for a slash command option.
Warning
This is currently ignored for message commands and is only valid for string, integer and float options.
Examples:
@with_annotated_args
@tanjun.as_slash_command("beep", "meow")
async def command(
ctx: tanjun.abc.Context,
location: Annotated[Int, "where do you live?", Choices("London", "Paradise", "Nowhere")],
) -> None:
raise NotImplementedError
choices
property
#
choices: collections.Mapping[str, _ChoiceUnion]
Mapping of up to 25 choices for the slash command option.
__init__ #
__init__(mapping=(), /, **kwargs)
Create a choices instance.
PARAMETER | DESCRIPTION |
---|---|
mapping |
Either a mapping of names to the choices values or a sequence
of
TYPE:
|
**kwargs |
Choice values.
TYPE:
|
Converted #
Bases: _ConfigIdentifier
Marked an argument as type Str with converters.
Examples:
@with_annotated_args
@tanjun.as_slash_command("beep", "boop")
async def command(
ctx: tanjun.abc.SlashContext,
argument: Annotated[OtherType, Converted(callback, other_callback), "description"]
other_argument: Annotated[Converted[callback, other_callback], "description"],
) -> None:
raise NotImplementedError
Where Converted[...]
follows the same semantics as Converted's __init__
.
converters
property
#
converters: collections.Sequence[_ConverterSig[typing.Any]]
A sequence of the converters.
__init__ #
__init__(converter, /, *other_converters)
Create a converted instance.
PARAMETER | DESCRIPTION |
---|---|
converter |
The first converter this argument should use to handle values passed to it during parsing. Only the first converter to pass will be used.
TYPE:
|
*other_converters |
Other first converter(s) this argument should use to handle values passed to it during parsing. Only the first converter to pass will be used.
TYPE:
|
Default #
Bases: _ConfigIdentifier
Explicitly configure an argument's default.
Examples:
@with_annotated_args
@tanjun.as_slash_command("name", "description")
async def command(
ctx: tanjun.abc.Context,
argument: Annotated[Str, Default(""), "description"],
other_argument: Annotated[Default[Str, ""], "description"],
) -> None:
raise NotImplementedError
@with_annotated_args
@tanjun.as_slash_command("name", "description")
async def command(
ctx: tanjun.abc.Context,
required_argument: Annotated[Default[Str], "description"] = "yeet",
other_required: Annotated[Int, Default(), "description"] = 123,
) -> None:
raise NotImplementedError
Passing an empty Default allows you to mark an argument that's optional in the signature as being a required option.
default
property
#
default: typing.Union[typing.Any, parsing.UndefinedT]
The option's default.
This will override the default in the signature for this parameter.
__init__ #
__init__(default=parsing.UNDEFINED)
Initialise a default.
PARAMETER | DESCRIPTION |
---|---|
default |
The argument's default. If left as tanjun.parsing.UNDEFINED then the argument will be required regardless of the signature default.
TYPE:
|
Flag #
Bases: _ConfigIdentifier
Mark an argument as a flag/option for message command parsing.
This indicates that the argument should be specified by name (e.g. --name
)
rather than positionally for message parsing and doesn't effect slash
command options.
Examples:
@with_annotated_args
@tanjun.as_message_command("message")
async def command(
ctx: tanjun.abc.MessageContext,
flag_value: Annotated[Bool, Flag(empty_value=True, aliases=("-f",))] = False,
) -> None:
raise NotImplementedError
aliases
property
#
aliases: typing.Optional[collections.Sequence[str]]
The aliases set for this flag.
These do not override the flag's name.
default
property
#
default: typing.Union[typing.Any, parsing.UndefinedT]
The flag's default.
If not specified then the default in the signature for this argument will be used.
empty_value
property
#
empty_value: typing.Union[parsing.UndefinedT, typing.Any]
The value to pass for the argument if the flag is provided without a value.
If this is undefined then a value will always need to be passed for the flag.
__init__ #
__init__(*, aliases=None, default=parsing.UNDEFINED, empty_value=parsing.UNDEFINED)
Create a flag instance.
PARAMETER | DESCRIPTION |
---|---|
aliases |
Other names the flag may be triggered by. This does not override the argument's name.
TYPE:
|
default |
Deprecated argument used to specify the option's default. Use Default instead.
TYPE:
|
empty_value |
Value to pass for the argument if the flag is provided without a value. If left undefined then an explicit value will always be needed.
TYPE:
|
Greedy #
Bases: _ConfigIdentifier
Mark an argument as "greedy" for message command parsing.
This means that it'll consume the rest of the positional arguments, can only be applied to one positional argument and is no-op for slash commands and flags.
Examples:
@with_annotated_args
@tanjun.as_message_command("message")
async def command(
ctx: tanjun.abc.MessageContext,
greedy_arg: Greedy[Str],
other_greedy_arg: Annotated[Str, Greedy()],
) -> None:
raise NotImplementedError
Length #
Bases: _ConfigIdentifier
Define length restraints for a string option.
Note
Length constraints are applied before conversion for slash commands but after conversion for message commands.
Examples:
@with_annotated_args
@tanjun.as_slash_command("meow", "blam")
async def command(
ctx: tanjun.abc.Context,
max_and_min: typing.Annotated[Str, Length(123, 321)],
max_only: typing.Annotated[Str, Length(123)],
generic_max_and_min: typing.Annotated[Length[5, 13], "meow"],
generic_max_only: typing.Annotated[Length[21], "meow"],
) -> None:
raise NotImplementedError
where Length[...]
follows the same semantics as Length's __init__
.
@with_annotated_args
@tanjun.as_slash_command("meow", "description")
async def command(
ctx: tanjun.abc.SlashContext,
argument: Annotated[Str, range(5, 100), "description"],
other_argument: Annotated[Str, 4:64, "description"],
) -> None:
raise NotImplementedError
Alternatively, the slice syntax and range
may be used to set the length
restraints for a string argument (where the start is inclusive and stop is
exclusive). These default to a min_length of 0
if the start isn't
specified and ignores any specified step.
__init__ #
__init__(min_or_max_length, max_length=None)
Initialise a length constraint.
PARAMETER | DESCRIPTION |
---|---|
min_or_max_length |
If
TYPE:
|
max_length |
The maximum length this string argument can be. If not specified then |
Max #
Bases: _ConfigIdentifier
Inclusive maximum value for a Float or Int argument.
Examples:
@with_annotated_args
@tanjun.as_slash_command("beep", "meow")
async def command(
ctx: tanjun.abc.Context,
age: Annotated[Int, Max(130), "How old are you?"],
number: Annotated[Max[130.2], "description"],
) -> None:
raise NotImplementedError
The option's type is inferred from the passed value when using
Max as a generic type hint (e.g. Max[18]
).
Min #
Bases: _ConfigIdentifier
Inclusive minimum value for a Float or Int argument.
Examples:
@with_annotated_args
@tanjun.as_slash_command("beep", "meow")
async def command(
ctx: tanjun.abc.Context,
age: Annotated[Int, Min(13), "How old are you?"],
number: Annotated[Min[13.9], "description"],
) -> None:
raise NotImplementedError
The option's type is inferred from the passed value when using
Min as a generic type hint (e.g. Min[69.4]
).
Name #
Bases: _ConfigIdentifier
Override the inferred name used to declare an option.
Examples:
@with_annotated_args(follow_wrapped=True)
@tanjun.as_slash_command("meow", "nyaa")
@tanjun.as_message_command("meow")
async def command(
ctx: tanjun.abc.Context,
resource_type: Annotated[Str, Name("type"), "The type of resource to get."],
) -> None:
raise NotImplementedError
message_name
property
#
message_name: typing.Optional[str]
The name to use for this option in message commands.
slash_name
property
#
slash_name: typing.Optional[str]
The name to use for this option in slash commands.
__init__ #
__init__(both=None, /, *, message=None, slash=None)
Create an argument name override.
PARAMETER | DESCRIPTION |
---|---|
both |
If provided, the name to use for this option in message and slash commands. This will be reformatted a bit for message commands (prefixed with
|
message |
The name to use for this option in message commands. This takes priority over |
slash |
The name to use for this option in slash commands. This takes priority over |
Positional #
Bases: _ConfigIdentifier
Mark an argument as being passed positionally for message command parsing.
Arguments will be positional by default (unless it has a default) and this allows for marking positional arguments as optional.
This only effects message option parsing.
Examples:
@with_annotated_args
@tanjun.as_message_command("message")
async def command(
ctx: tanjun.abc.MessageContext,
positional_arg: Positional[Str] = None,
other_positional_arg: Annotated[Str, Positional()] = None,
) -> None:
raise NotImplementedError
Ranged #
Bases: _ConfigIdentifier
Declare the range limit for an Int
or Float
argument.
Examples:
@with_annotated_args(follow_wrapped=True)
@tanjun.as_slash_command("meow", "nyaa")
@tanjun.as_message_command("meow")
async def command(
ctx: tanjun.abc.Context,
number_arg: Annotated[Int, Ranged(0, 69), "description"],
other_number_arg: Annotated[Ranged[13.69, 420.69], "description"],
) -> None:
raise NotImplementedError
The option's type is inferred from whether integers or floats are passed
when using Ranged as a generic type hint (e.g.
Ranged[123, 666]
).
@with_annotated_args
@tanjun.as_slash_command("meow", "description")
async def command(
ctx: tanjun.abc.SlashContext,
float_value: Annotated[Float, 1.5:101.5, "description"],
int_value: Annotated[Int, range(5, 100), "description"],
) -> None:
raise NotImplementedError
Alternatively, the slice syntax and range
may be used to set the range
for a float or integer argument (where the start is inclusive and stop is
exclusive). These default to a min_value of 0
if the start isn't
specified and ignores any specified step.
SnowflakeOr #
Bases: _ConfigIdentifier
Mark an argument as taking an object or its ID.
This allows for the argument to be declared as taking the object for slash commands without requiring that the message command equivalent fetch the object each time for the following types:
Examples:
@with_annotated_args(follow_wrapped=True)
@tanjun.as_slash_command("meow", "nyaa")
@tanjun.as_message_command("meow")
async def command(
ctx: tanjun.abc.Context,
user: Annotated[User, SnowflakeOr(parse_id=parse_user_id), "The user to target."],
# The `parse_id` callback is automatically set to the mention format for
# the passed type if applicable when using SnowflakeOr as a generic type-hint.
role: Annotated[Optional[SnowflakeOr[Role]], "The role to target."] = None,
) -> None:
user_id = hikari.Snowflake(user)
parse_id
property
#
parse_id: collections.Callable[[str], hikari.Snowflake]
Callback used to parse this argument's ID.
__init__ #
__init__(*, parse_id=conversion.parse_snowflake)
Create a snowflake or argument marker.
PARAMETER | DESCRIPTION |
---|---|
parse_id |
The function used to parse the argument's ID. This can be used to restrain this to only accepting certain mention formats.
TYPE:
|
TheseChannels #
Bases: _ConfigIdentifier
Restrain the type of channels a channel argument can target.
channel_types
property
#
channel_types: collections.Sequence[_ChannelTypeIsh]
Sequence of the channel types this is constrained by.
__init__ #
__init__(channel_type, /, *other_types)
Create a channel argument restraint.
PARAMETER | DESCRIPTION |
---|---|
channel_type |
A channel type to restrain this argument by.
TYPE:
|
*other_types |
Other channel types to restrain this argument by.
TYPE:
|
parse_annotated_args #
parse_annotated_args(command, /, *, descriptions=None, follow_wrapped=False)
Set a command's arguments based on its signature.
For more information on how this works see tanjun.annotations.with_annotated_args which acts as the decorator equivalent of this. The only difference is function allows passing a mapping of argument descriptions.
PARAMETER | DESCRIPTION |
---|---|
command |
The message or slash command to set the arguments for.
TYPE:
|
descriptions |
Mapping of descriptions to use for this command's slash command options. If an option isn't included here then this will default back to getting the description from its annotation.
TYPE:
|
follow_wrapped |
Whether this should also set the arguments on any other command objects this wraps in a decorator call chain.
TYPE:
|
with_annotated_args #
with_annotated_args(command=None, /, *, follow_wrapped=False)
Set a command's arguments based on its signature.
To declare arguments a you will have to do one of two things:
-
Using any of the following types as an argument's type-hint (this may be as the first argument to typing.Annotated) will mark it as injected:
- tanjun.annotations.Attachment*
- tanjun.annotations.Bool
- tanjun.annotations.Channel
- tanjun.annotations.InteractionChannel*
- tanjun.annotations.Color/tanjun.annotations.Colour
- tanjun.annotations.Datetime
- tanjun.annotations.Float
- tanjun.annotations.Int
- tanjun.annotations.Member
- tanjun.annotations.InteractionMember*
- tanjun.annotations.Mentionable
- tanjun.annotations.Role
- tanjun.annotations.Snowflake
- tanjun.annotations.Str
- tanjun.annotations.User
* These types are specific to slash commands and will raise an exception when set for a message command's parameter which has no real default.
@tanjun.with_annotated_args(follow_wrapped=True) @tanjun.as_message_command("name") @tanjun.as_slash_command("name", "description") async def command( ctx: tanjun.abc.SlashContext, # Here the option's description is passed as a string to Annotated: # this is necessary for slash commands but ignored for message commands. name: Annotated[Str, "The character's name"], # `= False` declares this field as optional, with it defaulting to `False` # if not specified. lawyer: Annotated[Bool, "Whether they're a lawyer"] = False, ) -> None: raise NotImplementedError
-
By assigning tanjun.annotations.Converted...
Either as one of the other arguments to typing.Annotated
@tanjun.with_annotated_args(follow_wrapped=True) @tanjun.as_message_command("e") @tanjun.as_slash_command("e", "description") async def command( ctx: tanjun.abc.SlashContext, value: Annotated[OtherType, Converted(parse_value), "description"], ) -> None: raise NotImplementedError
or as the type hint
@tanjun.with_annotated_args(follow_wrapped=True) @tanjun.as_message_command("e") @tanjun.as_slash_command("e", "description") async def command( ctx: tanjun.abc.SlashContext, value: Annotated[Converted[CustomType.from_str], "description"], ) -> None: raise NotImplementedError
It should be noted that wrapping in typing.Annotated isn't necessary for message commands options as they don't have descriptions.
async def message_command(
ctx: tanjun.abc.MessageContext,
name: Str,
converted: Converted[Type.from_str],
enable: typing.Optional[Bool] = None,
) -> None:
raise NotImplementedError
PARAMETER | DESCRIPTION |
---|---|
command |
The message or slash command to set the arguments for.
TYPE:
|
follow_wrapped |
Whether this should also set the arguments on any other command objects this wraps in a decorator call chain.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
tanjun.SlashCommand | tanjun.MessageCommand
|
The command object to enable using this as a decorator. |