~sirn/fanboi2

ref: 834edf0edc5dd633c0ecea16231b6ed2d728476d fanboi2/fanboi2/services/rate_limiter.py -rw-r--r-- 1.4 KiB
834edf0eKridsada Thanabulpong Massive cleanup in preparation for 0.30 (#25) 3 years ago
                                                                                
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
class RateLimiterService(object):
    """Rate limiter service provides a service for querying whether
    the user given by a payload should be rate-limited.
    """

    def __init__(self, redis_conn):
        self.redis_conn = redis_conn

    def _get_key(self, **kwargs):
        return 'services.rate_limiter:%s' % (
            (','.join('%s=%s' % (k, v) for k, v in sorted(kwargs.items()))),)

    def limit_for(self, expiration=10, **kwargs):
        """Set the rate limited key for the user and expire at least
        the given :param:`expiration` in seconds.

        :param expiration: A number of seconds to rate limited for.
        :param kwargs: Payload to identify this rate limit.
        """
        key = self._get_key(**kwargs)
        self.redis_conn.set(key, 1)
        self.redis_conn.expire(key, expiration)

    def is_limited(self, **kwargs):
        """Returns :type:`True` if the given :param:`kwargs` is rate limited.

        :param kwargs: Payload to identify this rate limit.
        """
        key = self._get_key(**kwargs)
        return self.redis_conn.exists(key)

    def time_left(self, **kwargs):
        """Returns the number of seconds left until the given payload
        is no longer rate limited.

        :param kwargs: Payload to identify this rate limit
        """
        key = self._get_key(**kwargs)
        return self.redis_conn.ttl(key)