Skip to content

Rate Limiting and Throttling

Here's a complete example of how to implement rate limiting and throttling in Django REST Framework (DRF):

  1. Install Django REST Framework

    • Make sure you have Django REST Framework installed. If not, you can install it using pip:

      pip install djangorestframework
      
  2. Configure Throttling in Django Settings

    • You can set global throttling rates in your settings.py file. DRF provides two built-in throttle classes: AnonRateThrottle (for anonymous users) and UserRateThrottle (for authenticated users).

      # settings.py
      
      REST_FRAMEWORK = {
          'DEFAULT_THROTTLE_CLASSES': [
              'rest_framework.throttling.AnonRateThrottle',
              'rest_framework.throttling.UserRateThrottle',
          ],
          'DEFAULT_THROTTLE_RATES': {
              'anon': '100/day',  # 100 requests per day for anonymous users
              'user': '1000/day',  # 1000 requests per day for authenticated users
          }
      }
      
  3. Implementing Throttling in Views

    • You can apply throttling to specific views or viewsets by using the throttle_classes attribute.

      from rest_framework.views import APIView
      from rest_framework.response import Response
      from rest_framework.throttling import AnonRateThrottle, UserRateThrottle
      
      class CustomAnonRateThrottle(AnonRateThrottle):
          rate = '10/min'  # Override global setting: 10 requests per minute for anonymous users
      
      class CustomUserRateThrottle(UserRateThrottle):
          rate = '100/min'  # Override global setting: 100 requests per minute for authenticated users
      
      class PublicAPIView(APIView):
          throttle_classes = [CustomAnonRateThrottle, CustomUserRateThrottle]
      
          def get(self, request):
              data = {"message": "This is a public API with rate limiting."}
              return Response(data)
      
    • In this example, the PublicAPIView applies custom throttling rates. Anonymous users are limited to 10 requests per minute, while authenticated users can make 100 requests per minute.

  4. Testing Throttling

    • You can test throttling by making multiple requests to the endpoint. Once the limit is reached, DRF will return a 429 Too Many Requests response.

      # Make requests to the API endpoint
      curl -X GET http://127.0.0.1:8000/api/public/
      
    • After exceeding the limit, the response will look like this:

      {
          "detail": "Request was throttled. Expected available in 60 seconds."
      }
      
  5. Custom Throttle Classes

    • You can also create custom throttle classes to apply different rules based on your needs.

      from rest_framework.throttling import BaseThrottle
      import time
      
      class BurstRateThrottle(BaseThrottle):
          THROTTLE_RATES = {
              'burst': '5/min'
          }
      
          def __init__(self):
              self.history = []
      
          def allow_request(self, request, view):
              self.history = [timestamp for timestamp in self.history if timestamp > time.time() - 60]
              if len(self.history) >= 5:
                  return False
              self.history.append(time.time())
              return True
      
          def wait(self):
              return 60 - (time.time() - self.history[-1])
      
    • Apply this custom throttle to your view:

      class CustomThrottledAPIView(APIView):
          throttle_classes = [BurstRateThrottle]
      
          def get(self, request):
              data = {"message": "This API has a custom burst rate throttle."}
              return Response(data)
      
  6. Logging and Monitoring Throttling

    • You can log throttling events for monitoring purposes:

      import logging
      from rest_framework.throttling import SimpleRateThrottle
      
      logger = logging.getLogger(__name__)
      
      class LoggedAnonRateThrottle(SimpleRateThrottle):
          scope = 'anon'
      
          def allow_request(self, request, view):
              if not super().allow_request(request, view):
                  logger.warning(f"Throttled request from IP: {self.get_ident(request)}")
                  return False
              return True
      
    • Use this custom throttle in your view to log any throttled requests.

Summary

This example demonstrates how to implement rate limiting and throttling in Django REST Framework. By configuring global throttle rates, applying custom throttle classes, and logging throttling events, you can effectively manage API usage and protect your public API from abuse.