Open In App

How to throttle API with Django Rest Framework

Improve
Improve
Like Article
Like
Save
Share
Report

Have you ever passed through an overbridge and noticed the sign stating the bridge weight restriction? Those restrictions are put in place to ensure public safety. Django REST Framework uses a similar process named throttling that controls the rate of requests that the client can make to an API. This rate limit restriction can ensure scalability, protection against slow performance and denial-of-service (DoS) attacks, and improve overall user experience. 

The Django REST Framework has three throttling classes in the rest_framework.throttling module — AnonRate, UserRate, and ScopedRate throttle. All these classes specify throttling rules that signify the maximum number of requests in a given time within the scope. These classes have different mechanisms to specify the scope – to compare previous information with the new request. Let’s dig deep into the DRF throttling feature.

  • AnonRateThrottle
  • UserRateThrottle
  • ScopedRateThrottle

Note: Please refer to Adding Permission in API – Django REST Framework and Customizing Object Level Permissions – Django REST Framework to make use of permission with throttling

AnonRateThrottle

AnonRateThrottle will throttle unauthenticated users. Using the IP address of the incoming request, a unique key is generated to throttle against. The allowed request rate is determined from any of the following:

  • The rate property on the class – provided by overriding AnonRateThrottle and setting the property.
  • The DEFAULT_THROTTLE_RATES[‘anon’] setting.

Let’s set the throttling policy globally. You can open the settings.py file and mention the throttle class and throttle rate  as below:

Python3




REST_FRAMEWORK = {
  
    'DEFAULT_AUTHENTICATION_CLASSES'🙁
        'rest_framework.authentication.BasicAuthentication',
        )
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
  
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '2/day'
    }
}


You can include second, minute, hour, or day as the throttle period (THROTTLE RATES). 

Let’s try the HTTPie command to retrieve the robots. Here, we retrieve the list without providing any credentials.

http GET :8000/robot/

Output

HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Language: en
Content-Length: 2106
Content-Type: application/json
Date: Sat, 02 Oct 2021 14:29:40 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Accept-Language
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

[
    {
        "currency": "USD",
        "currency_name": "US Dollar",
        "manufacturer": "ABB",
        "manufacturing_date": "2020-05-10T00:00:00Z",
        "name": "IRB 1100",
        "owner": "sonu",
        "price": 25000,
        "robot_category": "Articulated Robots",
        "url": "http://localhost:8000/robot/7/"
    },
    {
        "currency": "USD",
        "currency_name": "US Dollar",
        "manufacturer": "ABB",
        "manufacturing_date": "2020-08-10T00:00:00Z",
        "name": "IRB 120",
        "owner": "sonu",
        "price": 35000,
        "robot_category": "Articulated Robots",
        "url": "http://localhost:8000/robot/8/"
    },
 ]

Here, the anon throttle rate is set as 2 API requests per day. So, it doesn’t allow more than two requests. You will get below output if your request rate exceeds 2 requests.

UserRateThrottle

UserRateThrottle controls the rate of requests send by both authenticated and unauthenticated users. The user id is the unique cache key for authenticated requests, and the IP address is the unique cache key for unauthenticated requests. 

The allowed request rate is determined from any of the following:

  • The rate property on the class – provided by overriding UserRateThrottle and setting the property.
  • The DEFAULT_THROTTLE_RATES[‘user’] setting.

You can edit the REST_FRAMEWORK dictionary as follows:

Python3




REST_FRAMEWORK = {
  
    'DEFAULT_AUTHENTICATION_CLASSES'🙁
        'rest_framework.authentication.BasicAuthentication',
        )
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '2/day',
        'user': '5/day'
    }
}


The throttling rules in our REST_FRAMEWORK dictionary are as below:

  • A maximum of 2 requests per day for unauthenticated users
  • A maximum of 5 requests per day for authenticated users

The below authenticated HTTPie command allows 5 requests per day.

http -a “sonu”:”sn@pswrd” GET :8000/robot/

The restful web service raises too many requests for more than 5 requests per day.

ScopedRateThrottle

The ScopedRateThrottle class controls the rate of requests for specific features in our RESTFul web service. Here the view that is being accessed should include the .throttle_scope property. Let’s add a throttle scope to our RobotDetail class and mention the throttle rate for the scope.

First, let’s import the ScopedRateThrottle.

from rest_framework.throttling import ScopedRateThrottle

Now add the below lines of code 

throttle_scope = 'robots'
throttle_classes = (ScopedRateThrottle,)

Our RobotDetail class looks as follows:

Python3




class RobotDetail(generics.RetrieveUpdateDestroyAPIView):
    throttle_scope = 'robots'
    throttle_classes = (ScopedRateThrottle,)
      
    permission_classes = (
        permissions.IsAuthenticatedOrReadOnly,
        custompermission.IsCurrentUserOwnerOrReadOnly,
    )
      
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-detail'


Next, let’s add the throttle rate for the scope ‘robots’.

Python3




REST_FRAMEWORK = {
  
    'DEFAULT_AUTHENTICATION_CLASSES'🙁
        'rest_framework.authentication.BasicAuthentication',
        )
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '2/day',
        'user': '5/day',
        'robots': '3/day'
    }
}


Let’s try the authenticated HTTPie request to retrieve the robot based on the id, which makes use of RobotDetail class to fetch the robot based on the id. The command is as follows:

http -a “sonu”:”sn@pswrd” GET :8000/robot/2/

Output

Here, our scope rate is 3 requests per day. We will get too many requests if it exceeds 3 requests. The output for the 4th request is as follows:



Last Updated : 17 Oct, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads