Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom throttling response in django rest framework

I am using DRF for rest apis so now i am applying throttling to my apis. For that I created following throttle scopes

  1. userRateThrottle

  2. anonRateThrottle

  3. burstRateThrottle

  4. perViewsThrottles (varies with view)

currently i getting below response:

{"detail":"Request was throttled. Expected available in 32.0 seconds."}

I want response something like this:

{"message":"request limit exceeded","availableIn":"32.0 seconds","throttleType":"type"}

There is nothing in DRF docs for customisation. How can i customise my response according to requirement?

like image 713
Ajeet Lakhani Avatar asked Oct 04 '15 10:10

Ajeet Lakhani


People also ask

What is throttling in Django REST?

Throttling is similar to permissions, in that it determines if a request should be authorized. Throttles indicate a temporary state, and are used to control the rate of requests that clients can make to an API. As with permissions, multiple throttles may be used.

What is REST API throttling?

API throttling is the process of limiting the number of API requests a user can make in a certain period. An application programming interface (API) functions as a gateway between a user and a software application.

How do I increase error in Django REST Framework?

The generic views use the raise_exception=True flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above. By default this exception results in a response with the HTTP status code "400 Bad Request".


2 Answers

To do that, you can implement a custom exception handler function that returns the custom response in case of a Throttled exceptions.

from rest_framework.views import exception_handler
from rest_framework.exceptions import Throttled

def custom_exception_handler(exc, context):
    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc, context)

    if isinstance(exc, Throttled): # check that a Throttled exception is raised
        custom_response_data = { # prepare custom response data
            'message': 'request limit exceeded',
            'availableIn': '%d seconds'%exc.wait
        }
        response.data = custom_response_data # set the custom response data on response object

  return response

Then, you need to add this custom exception handler to your DRF settings.

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}

I think it would be slightly difficult to know the throttleType without changing some DRF code as DRF raises a Throttled exception in case of any the Throttle classes throttling a request. No information is passed to the Throttled exception about which throttle_class is raising that exception.

like image 63
Rahul Gupta Avatar answered Oct 01 '22 01:10

Rahul Gupta


You can change message of throttled response by overriding throttled methods of your view. For example:

from rest_framework.exceptions import Throttled

class SomeView(APIView):
    def throttled(self, request, wait):
        raise Throttled(detail={
              "message":"request limit exceeded",
              "availableIn":f"{wait} seconds",
              "throttleType":"type"
        })
like image 45
Dima Kudosh Avatar answered Oct 01 '22 02:10

Dima Kudosh