diff --git a/rest_framework/throttling.py b/rest_framework/throttling.py index c0d6cf42f..90c8cd918 100644 --- a/rest_framework/throttling.py +++ b/rest_framework/throttling.py @@ -5,6 +5,7 @@ import time from django.core.cache import cache as default_cache from django.core.exceptions import ImproperlyConfigured +from utils.throttling_duration_parser import parse_quantity_and_unit from rest_framework.settings import api_settings @@ -94,7 +95,7 @@ class SimpleRateThrottle(BaseThrottle): msg = "No default throttle rate set for '%s' scope" % self.scope raise ImproperlyConfigured(msg) - def parse_rate(self, rate): + def parse_rate(self,rate): """ Given the request rate string, return a two tuple of: , @@ -102,9 +103,12 @@ class SimpleRateThrottle(BaseThrottle): if rate is None: return (None, None) num, period = rate.split('/') + quantity, unit = parse_quantity_and_unit(period).values() num_requests = int(num) - duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]] - return (num_requests, duration) + + duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[unit[0]] + total_duration = duration * int(quantity) + return (num_requests, total_duration) def allow_request(self, request, view): """ diff --git a/rest_framework/utils/throttling_duration_parser.py b/rest_framework/utils/throttling_duration_parser.py new file mode 100644 index 000000000..859fd432f --- /dev/null +++ b/rest_framework/utils/throttling_duration_parser.py @@ -0,0 +1,22 @@ +def parse_quantity_and_unit(quantity_unit_string): + """ + Parse a combined quantity and unit string and return a dictionary containing the parsed values. + + Args: + quantity_unit_string (str): A string that combines a numeric quantity and a unit, e.g., "5min", "10h". + + Returns: + dict: A dictionary containing the parsed quantity and unit, with keys 'quantity' and 'unit'. + If the input string contains only a unit (e.g., "ms"), quantity will be set to 1. + """ + i = 0 + quantity_unit_dict = {} + while i < len(quantity_unit_string) and quantity_unit_string[i].isnumeric(): + i += 1 + if i == 0: + quantity_unit_dict['quantity'] = 1 + quantity_unit_dict['unit'] = quantity_unit_string + else: + quantity_unit_dict['quantity'] = int(quantity_unit_string[:i]) + quantity_unit_dict['unit'] = quantity_unit_string[i:] + return quantity_unit_dict \ No newline at end of file