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 .....
Example async custom buckets#
How to use async buckets to process data
All you need is an enum with the process
method which is async.
Here is an example which rate-limits based off of the first argument.
1class CustomBucket(Enum):
2 first_arg = 1
3
4 async 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
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