1212
1313
1414class RateLimit (metaclass = ABCMeta ):
15+ """
16+ Abstract class for varying implementations/types of rate limits.
17+ All methods in this class are overriden in every implementation.
18+ However, different implementations may have additional functions not present in this parent abstract class.
19+
20+ A class implementing RateLimit functions without any external threads.
21+ When the first increment request is recieved (after a counter reset or a new instaniciation)
22+ a reset_after variable is set detailing when the rate limit(s) reset.
23+
24+ Upon each function invokation, the reset_after variable is checked and the timer is automatically reset if the reset_after time has passed.
25+ """
26+
1527 @abstractmethod
1628 def get_counter (self ) -> int :
29+ # Docstrings are defined in child classes due to their differing implementations.
1730 pass
1831
1932 @abstractmethod
2033 def get_reset_after (self ) -> Union [datetime , None ]:
34+ # Docstrings are defined in child classes due to their differing implementations.
2135 pass
2236
2337 @abstractmethod
2438 def is_exceeded (self ) -> bool :
39+ # Docstrings are defined in child classes due to their differing implementations.
2540 pass
2641
2742 @abstractmethod
2843 def increment (self ) -> IncrementResult :
44+ """
45+ The increment function adds one to the rate limit request counter.
46+
47+ If the reset_after time has passed, the counter will first be reset before counting the request.
48+
49+ When the counter hits 1, the reset_after time is calculated and stored.
50+
51+ This function returns an `IncrementResult` object, containing the keys `counter: int` and `exceeded: bool`.
52+ This can be used by the caller to determine the current state of the rate-limit object without making an additional function call.
53+ """
54+
2955 pass
3056
3157
3258class SingleRateLimit (RateLimit ):
59+ """
60+ A rate limit implementation for a single rate limit, such as a burst or sustain limit.
61+ This class is mainly used by the CombinedRateLimit class.
62+ """
63+
3364 def __init__ (self , time_period : TimePeriod , type : LimitType , limit : int ):
3465 self .__time_period = time_period
3566 self .__type = type
@@ -41,6 +72,10 @@ def __init__(self, time_period: TimePeriod, type: LimitType, limit: int):
4172 self .__reset_after : Union [datetime , None ] = None
4273
4374 def get_counter (self ) -> int :
75+ """
76+ This function returns the current request counter variable.
77+ """
78+
4479 return self .__counter
4580
4681 def get_time_period (self ) -> "TimePeriod" :
@@ -53,9 +88,21 @@ def get_limit_type(self) -> "LimitType":
5388 return self .__type
5489
5590 def get_reset_after (self ) -> Union [datetime , None ]:
91+ """
92+ This getter returns the current state of the reset_after counter.
93+
94+ If the counter in use, it's corresponding `datetime` object is returned.
95+
96+ If the counter is not in use, `None` is returned.
97+ """
98+
5699 return self .__reset_after
57100
58101 def is_exceeded (self ) -> bool :
102+ """
103+ This functions returns `True` if the rate limit has been exceeded.
104+ """
105+
59106 self .__reset_counter_if_required ()
60107 return self .__exceeded
61108
@@ -101,6 +148,11 @@ def __set_reset_after(self):
101148
102149
103150class CombinedRateLimit (RateLimit ):
151+ """
152+ A rate limit implementation for multiple rate limits, such as burst and sustain.
153+
154+ """
155+
104156 def __init__ (self , * parsed_limits : ParsedRateLimit , type : LimitType ):
105157 # *parsed_limits is a tuple
106158
@@ -123,6 +175,12 @@ def __init__(self, *parsed_limits: ParsedRateLimit, type: LimitType):
123175 )
124176
125177 def get_counter (self ) -> int :
178+ """
179+ This function returns the request counter with the **highest** value.
180+
181+ A `CombinedRateLimit` consists of multiple different rate limits, which may have differing counter values.
182+ """
183+
126184 # Map self.__limits to (limit).get_counter()
127185 counter_map = map (lambda limit : limit .get_counter (), self .__limits )
128186 counters = list (counter_map )
@@ -137,6 +195,16 @@ def get_counter(self) -> int:
137195 # We don't want a datetime response for a limit that has not been exceeded.
138196 # Otherwise eg. 10 burst requests -> 300s timeout (should be 30 (burst exceeded), 300s (not exceeded)
139197 def get_reset_after (self ) -> Union [datetime , None ]:
198+ """
199+ This getter returns either a `datetime` object or `None` object depending on the status of the rate limit.
200+
201+ If the counter is in use, the rate limit with the **latest** reset_after is returned.
202+
203+ This is so that this function can reliably be used as a indicator of when all rate limits have been reset.
204+
205+ If the counter is not in use, `None` is returned.
206+ """
207+
140208 # Get a list of limits that *have been exceeded*
141209 dates_exceeded_only = filter (lambda limit : limit .is_exceeded (), self .__limits )
142210
@@ -185,6 +253,10 @@ def get_limits_by_period(self, period: TimePeriod) -> List[SingleRateLimit]:
185253 return list (matches )
186254
187255 def is_exceeded (self ) -> bool :
256+ """
257+ This function returns `True` if **any** rate limit has been exceeded.
258+ """
259+
188260 # Map self.__limits to (limit).is_exceeded()
189261 is_exceeded_map = map (lambda limit : limit .is_exceeded (), self .__limits )
190262 is_exceeded_list = list (is_exceeded_map )
0 commit comments