I created an API using Django Rest Framework, now i'm working on a rate limiting system, to avoid spam. The built-in throttling system works great, and i managed to add multiple throttles:
REST_FRAMEWORK = {
# 'DEFAULT_AUTHENTICATION_CLASSES': (
# "xapi.authentication_backends.TokenBackend",
# ),
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '70/minute',
'user': '70/minute',
'user_sec': '2/second',
'user_min': '120/minute',
'user_hour': '7200/hour',
},
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
)
}
And in my views.py
:
class UserSecThrottle(UserRateThrottle):
scope = 'user_sec'
class UserMinThrottle(UserRateThrottle):
scope = 'user_min'
class UserHourThrottle(UserRateThrottle):
scope = 'user_hour'
So if some user performs more than 120 queries in a minute, that user will be blocked for a minute, if the hour limit is breached, the user is blocked for one hour. Is there some way to decide for how much is a user blocked? For example, if i want to block someone for 10 minutes if they perform more than 120 queries in a minute. Any advice is appreciated.
To create a custom throttle, override BaseThrottle
and implement .allow_request(self, request, view)
. The method should return True
if the request should be allowed, and False
otherwise.
Optionally you may also override the .wait()
method. If implemented, .wait()
should return a recommended number of seconds to wait before attempting the next request, or None. The .wait()
method will only be called if .allow_request()
has previously returned False
.
If the .wait()
method is implemented and the request is throttled, then a Retry-After header will be included in the response.
import random
class CustomThrottle(throttling.BaseThrottle):
def allow_request(self, request, view):
"""
Return `True` if the request should be allowed, `False` otherwise.
"""
return random.randint(1, 10) != 1
def wait(self):
"""
Optionally, return a recommended number of seconds to wait before
the next request.
"""
cu_second = 600
return cu_second
class UserSecThrottle(CustomThrottle,UserRateThrottle): # or AnonRateThrottle
scope = 'user_sec'
class ExampleView(APIView):
throttle_classes = [UserSecThrottle]
.......
Reference: https://www.django-rest-framework.org/api-guide/throttling/#custom-throttles
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With