class BaseThrottle: 	               def allow_request(self, request, view):                  raise NotImplementedError('.allow_request() must be overridden') 	          def get_ident(self, request):         """         Identify the machine making the request by parsing HTTP_X_FORWARDED_FOR         if present and number of proxies is > 0. If not use all of         HTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR.         """         xff = request.META.get('HTTP_X_FORWARDED_FOR')         remote_addr = request.META.get('REMOTE_ADDR')         num_proxies = api_settings.NUM_PROXIES
          if num_proxies is not None:             if num_proxies == 0 or xff is None:                 return remote_addr             addrs = xff.split(',')             client_addr = addrs[-min(num_proxies, len(addrs))]             return client_addr.strip()
          return ''.join(xff.split()) if xff else remote_addr 	               def wait(self):         return None
       class SimpleRateThrottle(BaseThrottle):     cache = default_cache     timer = time.time     cache_format = 'throttle_%(scope)s_%(ident)s'     scope = None     THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES 	          def __init__(self):         if not getattr(self, 'rate', None):             self.rate = self.get_rate()         self.num_requests, self.duration = self.parse_rate(self.rate)
      def get_cache_key(self, request, view):         """         Should return a unique cache-key which can be used for throttling.         Must be overridden.
          May return `None` if the request should not be throttled.         """         raise NotImplementedError('.get_cache_key() must be overridden')
      def get_rate(self):         """         Determine the string representation of the allowed request rate.         """         if not getattr(self, 'scope', None):             msg = ("You must set either `.scope` or `.rate` for '%s' throttle" %                    self.__class__.__name__)             raise ImproperlyConfigured(msg)
          try:             return self.THROTTLE_RATES[self.scope]         except KeyError:             msg = "No default throttle rate set for '%s' scope" % self.scope             raise ImproperlyConfigured(msg)
      def parse_rate(self, rate):         """         Given the request rate string, return a two tuple of:         <allowed number of requests>, <period of time in seconds>         """         if rate is None:             return (None, None)         num, period = rate.split('/')         num_requests = int(num)         duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]         return (num_requests, duration)
      def allow_request(self, request, view):                  if self.rate is None:             return True
          self.key = self.get_cache_key(request, view)         if self.key is None:             return True
          self.history = self.cache.get(self.key, [])         self.now = self.timer()
                   while self.history and self.history[-1] <= self.now - self.duration:             self.history.pop()         if len(self.history) >= self.num_requests:             return self.throttle_failure()         return self.throttle_success() 	     def throttle_success(self):                  self.history.insert(0, self.now)         self.cache.set(self.key, self.history, self.duration)         return True
      def throttle_failure(self):         """         Called when a request to the API has failed due to throttling.         """         return False
      def wait(self):         """         Returns the recommended next request time in seconds.         """         if self.history:             remaining_duration = self.duration - (self.now - self.history[-1])         else:             remaining_duration = self.duration
          available_requests = self.num_requests - len(self.history) + 1         if available_requests <= 0:             return None
          return remaining_duration / class BaseThrottle: 	               def allow_request(self, request, view):                  raise NotImplementedError('.allow_request() must be overridden') 	          def get_ident(self, request):         """         Identify the machine making the request by parsing HTTP_X_FORWARDED_FOR         if present and number of proxies is > 0. If not use all of         HTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR.         """         xff = request.META.get('HTTP_X_FORWARDED_FOR')         remote_addr = request.META.get('REMOTE_ADDR')         num_proxies = api_settings.NUM_PROXIES
          if num_proxies is not None:             if num_proxies == 0 or xff is None:                 return remote_addr             addrs = xff.split(',')             client_addr = addrs[-min(num_proxies, len(addrs))]             return client_addr.strip()
          return ''.join(xff.split()) if xff else remote_addr 	               def wait(self):         return None
       class SimpleRateThrottle(BaseThrottle):     cache = default_cache     timer = time.time     cache_format = 'throttle_%(scope)s_%(ident)s'     scope = None     THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES 	          def __init__(self):         if not getattr(self, 'rate', None):             self.rate = self.get_rate()         self.num_requests, self.duration = self.parse_rate(self.rate)
      def get_cache_key(self, request, view):         """         Should return a unique cache-key which can be used for throttling.         Must be overridden.
          May return `None` if the request should not be throttled.         """         raise NotImplementedError('.get_cache_key() must be overridden')
      def get_rate(self):         """         Determine the string representation of the allowed request rate.         """         if not getattr(self, 'scope', None):             msg = ("You must set either `.scope` or `.rate` for '%s' throttle" %                    self.__class__.__name__)             raise ImproperlyConfigured(msg)
          try:             return self.THROTTLE_RATES[self.scope]         except KeyError:             msg = "No default throttle rate set for '%s' scope" % self.scope             raise ImproperlyConfigured(msg)
      def parse_rate(self, rate):         """         Given the request rate string, return a two tuple of:         <allowed number of requests>, <period of time in seconds>         """         if rate is None:             return (None, None)         num, period = rate.split('/')         num_requests = int(num)         duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]         return (num_requests, duration)
      def allow_request(self, request, view):                  if self.rate is None:             return True
          self.key = self.get_cache_key(request, view)         if self.key is None:             return True
          self.history = self.cache.get(self.key, [])         self.now = self.timer()
                   while self.history and self.history[-1] <= self.now - self.duration:             self.history.pop()         if len(self.history) >= self.num_requests:             return self.throttle_failure()         return self.throttle_success() 	     def throttle_success(self):                  self.history.insert(0, self.now)         self.cache.set(self.key, self.history, self.duration)         return True
      def throttle_failure(self):         """         Called when a request to the API has failed due to throttling.         """         return False
      def wait(self):         """         Returns the recommended next request time in seconds.         """         if self.history:             remaining_duration = self.duration - (self.now - self.history[-1])         else:             remaining_duration = self.duration
          available_requests = self.num_requests - len(self.history) + 1         if available_requests <= 0:             return None
          return remaining_duration / float(available_requests)
 
   |