Skip to content

tanjun.annotations#

Parameter annotation based strategy for declaring slash and message command arguments.

Community Resources:

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.

Colour module-attribute #

Colour = Color

An argument which takes a colour.

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 tuple[name, value] or a sequence of choice values.

TYPE: typing.Union[collections.Mapping[str, _ChoiceT], collections.Sequence[tuple[str, _ChoiceT]], collections.Sequence[_ChoiceT]] DEFAULT: ()

**kwargs

Choice values.

TYPE: _ChoiceT DEFAULT: {}

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: collections.abc.Callable[[str, ...], collections.Coroutine[Any, Any, Any] | Any]

*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: collections.abc.Callable[[str, ...], collections.Coroutine[Any, Any, Any] | Any] DEFAULT: ()

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: typing.Union[typing.Any, parsing.UndefinedT] DEFAULT: parsing.UNDEFINED

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: typing.Optional[collections.Sequence[str]] DEFAULT: None

default

Deprecated argument used to specify the option's default.

Use Default instead.

TYPE: typing.Union[typing.Any, parsing.UndefinedT] DEFAULT: parsing.UNDEFINED

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: typing.Union[parsing.UndefinedT, typing.Any] DEFAULT: parsing.UNDEFINED

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.

max_length property #

max_length: int

The maximum length of this string option.

min_length property #

min_length: int

The minimum length of this string option.

__init__ #

__init__(min_or_max_length, max_length=None)

Initialise a length constraint.

PARAMETER DESCRIPTION
min_or_max_length

If max_length is left as None then this will be used as the maximum length and the minimum length will be 0.

TYPE: int

max_length

The maximum length this string argument can be.

If not specified then min_or_max_length will be used as the max length.

TYPE: typing.Optional[int] DEFAULT: None

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]).

value property #

value: typing.Union[int, float]

The maximum allowed value.

__init__ #

__init__(value)

Create an argument maximum value.

PARAMETER DESCRIPTION
value

The maximum allowed value allowed for an argument.

TYPE: typing.Union[int, float]

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]).

value property #

value: typing.Union[int, float]

The minimum allowed value.

__init__ #

__init__(value)

Create an argument minimum value.

PARAMETER DESCRIPTION
value

The minimum value allowed for an argument.

TYPE: typing.Union[int, float]

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 -- and .replace("_", "-")) and is only used for message flag options.

TYPE: typing.Optional[str] DEFAULT: None

message

The name to use for this option in message commands.

This takes priority over both, is not reformatted and only is only used for flag options.

TYPE: typing.Optional[str] DEFAULT: None

slash

The name to use for this option in slash commands.

This takes priority over both.

TYPE: typing.Optional[str] DEFAULT: None

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.

max_value property #

max_value: typing.Union[int, float]

The maximum allowed value for this argument.

min_value property #

min_value: typing.Union[int, float]

The minimum allowed value for this argument.

__init__ #

__init__(min_value, max_value)

Create an argument range limit.

PARAMETER DESCRIPTION
min_value

The minimum allowed value for this argument.

TYPE: typing.Union[int, float]

max_value

The maximum allowed value for this argument.

TYPE: typing.Union[int, Float]

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: collections.Callable[[str], hikari.Snowflake] DEFAULT: conversion.parse_snowflake

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: _ChannelTypeIsh

*other_types

Other channel types to restrain this argument by.

TYPE: _ChannelTypeIsh DEFAULT: ()

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: typing.Union[slash.SlashCommand[typing.Any], message.MessageCommand[typing.Any]]

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: typing.Optional[collections.Mapping[str, str]] DEFAULT: None

follow_wrapped

Whether this should also set the arguments on any other command objects this wraps in a decorator call chain.

TYPE: bool DEFAULT: False

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:

  1. 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:

    * 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
    
  2. 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: tanjun.SlashCommand | tanjun.MessageCommand DEFAULT: None

follow_wrapped

Whether this should also set the arguments on any other command objects this wraps in a decorator call chain.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
tanjun.SlashCommand | tanjun.MessageCommand

The command object to enable using this as a decorator.