Skip to content

Instantly share code, notes, and snippets.

@d6e
Created July 22, 2014 23:10
Show Gist options
  • Save d6e/5a5ce1590fd6b3412148 to your computer and use it in GitHub Desktop.
Save d6e/5a5ce1590fd6b3412148 to your computer and use it in GitHub Desktop.
A demonstration of the token bucket algorithm. Useful for rate limiting networking. https://en.wikipedia.org/wiki/Token_bucket (source: http://code.activestate.com/recipes/511490-implementation-of-the-token-bucket-algorithm/)
from time import time
class TokenBucket(object):
"""An implementation of the token bucket algorithm.
>>> bucket = TokenBucket(80, 0.5)
>>> print bucket.consume(10)
True
>>> print bucket.consume(90)
False
"""
def __init__(self, tokens, fill_rate):
"""tokens is the number of tokens in the bucket and the starting
capacity. fill_rate is the rate in tokens/second that the bucket
will be refilled."""
self.capacity = float(tokens)
self._tokens = float(tokens)
self.fill_rate = float(fill_rate)
self.timestamp = time()
def consume(self, tokens):
"""Consume tokens from the bucket. Returns True if there were
sufficient tokens otherwise False."""
if tokens <= self.tokens:
self._tokens -= tokens
else:
return False
return True
def get_tokens(self):
now = time()
if self._tokens < self.capacity:
delta = self.fill_rate * (now - self.timestamp)
self._tokens = min(self.capacity, self._tokens + delta)
self.timestamp = now
return self._tokens
tokens = property(get_tokens)
if __name__ == '__main__':
### Demonstration:
from time import sleep
fill_rate = 10 # The refill rate in tokens per sec
capacity = 80 # The capacity and starting size
bucket = TokenBucket(capacity, fill_rate)
print "tokens =", bucket.tokens
print "consume(10) =", bucket.consume(10)
print "consume(10) =", bucket.consume(70)
print "consume(10) =", bucket.consume(1)
sleep(1)
print "tokens =", bucket.tokens
sleep(1)
print "tokens =", bucket.tokens
print "consume(90) =", bucket.consume(90)
print "tokens =", bucket.tokens
sleep(5)
print "tokens =", bucket.tokens
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment