Rate Limiter
Rate Limiting is an essential aspect of security. By providing unlimited requests, it could cause strain on servers and
may also lead to malicious activities as anyone can make calls to the website any number of times. We can reduce such
activities to some extent by limiting the number of requests a user can make to our extension via rate_limiter
module.
For example, if we are writing an Ardent extension, we can implement rate limiter in our extension as follows:
from q2_sdk.core.rate_limiter import RateLimiter
import ipaddress
class FooArdentHandler(Q2ArdentRequestHandler):
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
whitelist_networks = [ipaddress.ip_network('0.0.0.0/28')]
blacklist_networks = [ipaddress.ip_network('1.2.3.4/32')]
self.rate_limiters = [
RateLimiter(
self.logger,
5,
5,
3,
self.request,
whitelist_networks=whitelist_networks,
blacklist_networks=blacklist_networks)
]
RateLimiter
has the following instance variables:
max_tokens
- Total number of attempts allowed before denialrefill_period
- time in seconds after which token gets refilledrefill_amount
- Number of tokens that gets added each refill periodrequest
-HTTPServerRequest
reference IP and other infowhitelist_networks
- List of IPv4Networks that will be automatically allowed. i.e. ipaddress.IPv4Network(‘13.249.59.85/32’)blacklist_networks
- List of IPv4Networks that will be automatically denied. i.e. ipaddress.IPv4Network(‘13.249.59.85/32’)whitelist_regex
- (Deprecated) IP addresses that match this pattern will be automatically allowedblacklist_regex
- (Deprecated) IP addresses that match this pattern will be automatically deniedname
- Will be appended to the cache key for uniquenesssegment_by_ip
- If True, each IP address gets its own rate limiting bucket.
We can check which IP address is allowed or denied with is_allowed
method. Returns True
if the IP address is in the list of whitelist_networks
and returns False
if it is blacklist_networks
. If these networks are not listed then this method calculates the remaining tokens from cache and returns False
along with a warning message if there are no remaining tokens or else returns True
.
The RateLimiter
class also contains a decorator object allowing the setting or rate limits per function call .:
from q2_sdk.core.rate_limiter import rate_limit
import ipaddress
class FooArdentHandler(Q2ArdentRequestHandler):
...
@rate_limit(max_tokens=1000)
def submit():
...
@rate_limit(
max_tokens=5, refill_period=5, refill_amount=3,
whitelist_networks=[ipaddress.ip_network('0.0.0.0/28')],
blacklist_networks=[ipaddress.ip_network('1.2.3.4/32')]
)
def default():
...