Example Usage#

These can be used on any function or method marked with async, Nextcord is just used for the examples here.

Example bot usage#

Rate-limits the command to 1 call per person every 15 seconds in your main file.

 1import cooldowns
 2
 3...
 4
 5@bot.slash_command(
 6    description="Ping command",
 7)
 8@cooldowns.cooldown(1, 15, bucket=cooldowns.SlashBucket.author)
 9async def ping(interaction: nextcord.Interaction):
10    await interaction.response.send_message("Pong!")

Example cog usage#

Rate-limits the command to 1 call per guild every 30 seconds.

 1import cooldowns
 2
 3...
 4
 5@nextcord.slash_command(
 6    description="Ping command",
 7)
 8@cooldowns.cooldown(1, 30, bucket=cooldowns.SlashBucket.guild)
 9async def ping(self, interaction: nextcord.Interaction):
10    await interaction.response.send_message("Pong!")

Handling cooldown’s#

Here is an example error handler

 1from cooldowns import CallableOnCooldown
 2
 3...
 4
 5@bot.event
 6async def on_application_command_error(inter: nextcord.Interaction, error):
 7    error = getattr(error, "original", error)
 8
 9    if isinstance(error, CallableOnCooldown):
10        await inter.send(
11            f"You are being rate-limited! Retry in `{error.retry_after}` seconds."
12        )
13
14    else:
15        raise error

Get Remaining Calls#

1from cooldowns import get_remaining_calls, cooldown, SlashBucket
2
3@bot.slash_command()
4@cooldown(2, 10, SlashBucket.command)
5async def test(inter):
6    ...
7    calls_left = get_remaining_calls(test, inter)
8    await inter.send(f"You can call this {calls_left} times before getting rate-limited")

Reset a specific cooldown#

Only resets cooldowns for the given id.

1from cooldowns import cooldown, CooldownBucket, reset_cooldown
2
3@cooldown(1, 30, CooldownBucket.all, cooldown_id="my_cooldown")
4async def test(*args, **kwargs):
5    ...
6
7# Reset
8reset_cooldown("my_cooldown")

Reset all cooldowns on a callable#

Resets all cooldowns on the provided callable.

1from cooldowns import cooldown, CooldownBucket, reset_cooldowns
2
3@cooldown(1, 30, CooldownBucket.all)
4@cooldown(1, 15, CooldownBucket.args)
5async def test(*args, **kwargs):
6    ...
7
8# Reset
9reset_cooldowns(test)

Reset a specific bucket on a cooldown#

Resets only the given buckets on a cooldown.

 1from cooldowns import cooldown, CooldownBucket, reset_bucket
 2
 3@cooldown(1, 30, CooldownBucket.all)
 4async def test(*args, **kwargs):
 5    ...
 6
 7...
 8
 9# Reset the bucket with `1` as an argument
10reset_bucket(test, 1)

Cooldown checks#

Here’s an example check to only apply a cooldown if the first argument is equal to 1.

1@cooldown(
2    1, 1, bucket=CooldownBucket.args, check=lambda *args, **kwargs: args[0] == 1
3)
4async def test_func(*args, **kwargs) -> (tuple, dict):
5    return args, kwargs

Here’s one use an async check. Functionally its the same as the previous one.

1async def mock_db_check(*args, **kwargs):
2    # You can do database calls here or anything
3    # since this is an async context
4    return args[0] == 1
5
6@cooldown(1, 1, bucket=CooldownBucket.args, check=mock_db_check)
7async def test_func(*args, **kwargs) -> (tuple, dict):
8    return args, kwargs

Custom buckets#

All you need is an enum with the process method.

Heres an example which rate-limits based off of the first argument.

 1class CustomBucket(Enum):
 2    first_arg = 1
 3
 4    def process(self, *args, **kwargs):
 5        if self is CustomBucket.first_arg:
 6            # This bucket is based ONLY off
 7            # of the first argument passed
 8            return args[0]
 9
10# Then to use
11@cooldown(1, 1, bucket=CustomBucket.first_arg)
12async def test_func(*args, **kwargs):
13    .....

Stacking cooldown’s#

Stack as many cooldown’s as you want, just note Python starts from the bottom decor and works its way up.

1# Can call ONCE time_period second using the same args
2# Can call TWICE time_period second using the same kwargs
3@cooldown(1, 1, bucket=CooldownBucket.args)
4@cooldown(2, 1, bucket=CooldownBucket.kwargs)
5async def test_func(*args, **kwargs) -> (tuple, dict):
6    return args, kwargs

Shared cooldowns#

This allows you to use the same cooldown on multiple callables.

 1from cooldowns import define_shared_cooldown, shared_cooldown, CooldownBucket
 2
 3define_shared_cooldown(1, 5, CooldownBucket.all, cooldown_id="my_id")
 4
 5@shared_cooldown("my_id")
 6async def test_1(*args, **kwargs):
 7    return 1
 8
 9@shared_cooldown("my_id")
10async def test_2(*args, **kwargs):
11    return 2
12
13# These now both share the same cooldown

Manually using cooldowns#

How to use the Cooldown object without a decorator.

1from cooldowns import Cooldown, CooldownBucket
2
3cooldown = Cooldown(1, 5, CooldownBucket.args)
4
5async with cooldown(*args, **kwargs):
6    # This will apply the cooldown
7    ...
8    # Do things