-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathratelimit.py
49 lines (41 loc) · 1.59 KB
/
ratelimit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#
# code based on https://github.com/nirtayeb/rate-limiter/blob/master/ratelimit.py
#
import redis
import functools
g_redis = redis.StrictRedis(db = 0)
class RateLimitType:
def __init__(self, name, amount, expire, identity = lambda h : None, on_exceed = lambda h : None):
self.name = name
self.amount = amount
self.expire_within = expire
self.identity = identity
self.on_exceed = on_exceed
def server_name(self, identity_arg):
return "l_%s:%s" % (self.name, self.identity(identity_arg))
def check(self, identity_arg):
amount = g_redis.get(self.server_name(identity_arg))
return amount != None and int(amount) >= self.amount
def update_amount(self, amount, identity_arg, reset_ex=False):
name = self.server_name(identity_arg)
if (reset_ex):
g_redis.set(name, amount, self.expire_within)
else:
expire_within = g_redis.ttl(name)
g_redis.set(name, amount, expire_within)
def increase_amount(self, amount, identity_arg):
name = self.server_name(identity_arg)
current = g_redis.get(name)
if current is not None:
g_redis.incr(name, amount)
else:
g_redis.set(name, amount, self.expire_within)
def limit_by(limiter):
def rate_limiter_decorator(func):
@functools.wraps(func)
def func_wrapper(self, *args, **kargs):
if not limiter.check(self):
return func(self, *args, **kargs)
limiter.on_exceed(self)
return func_wrapper
return rate_limiter_decorator