1- """
2- Rate limiting.
3- """
1+ """Rate limiting."""
42
3+ import functools
54import time
65
76
7+ @functools .total_ordering
88class TokenBucket :
9- """
10- A token bucket.
9+ """A token bucket.
10+
11+ Args:
12+ rate: token refill rate (per second) of bucket
13+ limit: maximum number of tokens the bucket can contain
1114 """
1215
1316 __slots__ = [
@@ -19,25 +22,21 @@ class TokenBucket:
1922
2023 clock = staticmethod (time .time )
2124
22- def __init__ (self , rate , limit ):
23- """
24- Create a new token bucket.
25-
26- :param rate int: Token refill rate (per second) of bucket.
27- :param limit int: Maximum number of tokens the bucket can contain.
28- """
25+ def __init__ (self , rate : int , limit : int ) -> None :
2926 super ().__init__ ()
3027 self .ts = self .clock ()
3128 self .rate = rate
3229 self .limit = limit
3330 self ._available = limit
3431
35- def consume (self , tokens ):
36- """
37- Attempt to remove the given number of tokens from this bucket.
32+ def consume (self , tokens : int ) -> bool :
33+ """Attempt to remove the given number of tokens from this bucket.
34+
35+ Args:
36+ tokens: number of tokens to consume
3837
39- If there are enough tokens in the bucket to fulfil the request, we
40- return `True`, otherwise `False`.
38+ Returns:
39+ `True` if the requested number could be consumed , otherwise `False`.
4140 """
4241 if 0 <= tokens <= self .tokens :
4342 self ._available -= tokens
@@ -46,8 +45,10 @@ def consume(self, tokens):
4645
4746 @property
4847 def tokens (self ):
49- """
50- Gives the number of tokens available in this bucket.
48+ """Gives the number of tokens available in this bucket.
49+
50+ Returns:
51+ The number of available tokens.
5152 """
5253 ts = self .clock ()
5354 if self ._available < self .limit :
@@ -61,6 +62,9 @@ def __eq__(self, other):
6162 def __lt__ (self , other ):
6263 return self .ts < other .ts
6364
65+ def __hash__ (self ):
66+ return hash ((self ._available , self .limit , self .rate , self .ts ))
67+
6468 def __getstate__ (self ):
6569 return dict (zip (self .__slots__ , [getattr (self , attr ) for attr in self .__slots__ ]))
6670
0 commit comments