pythad
pythad

Reputation: 4267

Django REST how to set throttle period to allow one request in 10 minutes?

Documentation says that period should be one of: ('s', 'sec', 'm', 'min', 'h', 'hour', 'd', 'day'). I am curious if I can set period to something like 1/10min?

Upvotes: 7

Views: 2708

Answers (3)

Paul
Paul

Reputation: 21

You can define a custom method parse_custom_rate() specified below and then use a handy format rate = "1/10m". Works for me with djangorestframework==3.14.0. Make sure to use a single letter time interval inside rate variable s, m, h, d.

from rest_framework.throttling import AnonRateThrottle

def parse_custom_rate(custom_rate: str) -> tuple[int, int]:
    if custom_rate is None:
        raise ValueError
    num, period = custom_rate.split('/')
    num_requests = int(num)
    duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[-1]]
    seconds = int(period[:-1]) * duration
    return (num_requests, seconds)


class AnonOnceInTenMinutesThrottle(AnonRateThrottle):
    rate = "1/10m" # s, m, h, d

    def parse_rate(self, rate):
        return parse_custom_rate(self.rate)

Upvotes: 2

Henrik
Henrik

Reputation: 928

Basically what XY said is true but it might not work because you still have to put the rate like this:

from rest_framework.throttling import AnonRateThrottle

class AnonTenPerTenMinutesThrottle(AnonRateThrottle):
    

    rate = '1/s' # <<<<< This line is very important
    # You just can enter any rate you want it will directly be overwritten by parse_rate
    

    def parse_rate(self, rate):
        """
        Given the request rate string, return a two tuple of:
        <allowed number of requests>, <period of time in seconds>

        So we always return a rate for 10 request per 10 minutes.

        Args:
            string: rate to be parsed, which we ignore.

        Returns:
            tuple:  <allowed number of requests>, <period of time in seconds>
        """
        return (10, 600) # 10 Requests per 600 seconds (10 minutes)

Upvotes: 5

The Pjot
The Pjot

Reputation: 1859

Looking at the code and documentation you cannot do this 'out of the box'. But I do see the possibility described to make your own custom throttle based on one of the existing one's:

from rest_framework.throttling import AnonRateThrottle


class AnonTenPerTenMinutesThrottle(AnonRateThrottle):
    def parse_rate(self, rate):
        """
        Given the request rate string, return a two tuple of:
        <allowed number of requests>, <period of time in seconds>

        So we always return a rate for 10 request per 10 minutes.

        Args:
            string: rate to be parsed, which we ignore.

        Returns:
            tuple:  <allowed number of requests>, <period of time in seconds>
        """
        return (10, 600)

Upvotes: 11

Related Questions