return user
-def limit(*, minutes, limit, key=None):
+def limit(*, minutes, limit, auth_limit=None, key=None):
"""
This decorator takes a limit of how many requests per minute can be processed.
"""
limiter = {
- "minutes" : minutes,
- "limit" : limit,
- "key" : key,
+ "minutes" : minutes,
+ "limit" : limit,
+ "auth_limit" : auth_limit,
+ "key" : key,
}
# Store the configuration with the handler
class RateLimiterRequest(object):
- def __init__(self, backend, request: fastapi.Request, *, minutes, limit, key=None):
+ def __init__(self, backend, request: fastapi.Request,
+ *, minutes, limit, auth_limit=None, key=None):
self.backend = backend
# Store the request
# Save the limits
self.minutes = minutes
- self.limit = limit
+ self.limit = limit
+ self.auth_limit = auth_limit
# Create a default key if none given
if key is None:
"""
Returns True if the request is prohibited by the rate limiter
"""
+ limit = self.limit
+
# Fetch the API key
if self.api_key:
# Fetch the API key
key = await self.backend.auth(api_key)
- # If the API key was found and is not ratelimited, we skip further checks
- if key and not key.is_ratelimited:
- return False
+ # Check if the user is actually properly authenticated
+ if key:
+ # If the API keyis not ratelimited, we skip further checks
+ if not key.is_ratelimited:
+ return False
+
+ # If authenticated users have a different limit set,
+ # we change the checked limit to that
+ if self.auth_limit:
+ limit = self.auth_limit
# Fetch the number of past requests
self.requests = await self.get_requests()
- # The client is rate-limited when more requests have been
- # received than allowed.
- if self.requests >= self.limit:
+ # Assert that some limit has been set
+ assert limit
+
+ # The client is rate-limited when more requests have been received than allowed
+ if self.requests >= limit:
return True
# Increment the request counter