Skip to content

Commit

Permalink
Feature/ratelimiter update (#330)
Browse files Browse the repository at this point in the history
* updated request_is_limited algorithm
  • Loading branch information
russbiggs authored Feb 7, 2024
1 parent 67c8ff1 commit 26d9503
Showing 1 changed file with 17 additions and 20 deletions.
37 changes: 17 additions & 20 deletions openaq_api/openaq_api/middleware.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import time
from datetime import timedelta
from datetime import timedelta, datetime
from os import environ
from fastapi import Response, status
from fastapi.responses import JSONResponse
Expand Down Expand Up @@ -133,19 +133,16 @@ def __init__(
self.rate_time = rate_time

async def request_is_limited(self, key: str, limit: int, request: Request) -> bool:
if await self.redis_client.set(key, limit, nx=True):
await self.redis_client.expire(key, int(self.rate_time.total_seconds()))
count = await self.redis_client.get(key)
if count in ("-1", "-2"):
logger.error(
RedisErrorLog(
detail=f"redis has an invalid value for limit: {count} for key: {key}"
)
)
if count and int(count) > 0:
request.state.counter = await self.redis_client.decrby(key, 1)
return False
return True
now = datetime.now()
k = f"{key}:{now.year}{now.month}{now.day}{now.hour}{now.minute}"
value = await self.redis_client.get(k)
if value is None or int(value) < limit:
async with self.redis_client.pipeline() as pipe:
[incr, _] = await pipe.incr(k).expire(k, 60).execute()
request.state.counter = limit - incr
return False
else:
return True

async def check_valid_key(self, key: str) -> bool:
if await self.redis_client.sismember("keys", key):
Expand Down Expand Up @@ -214,11 +211,11 @@ async def dispatch(
response.headers["RateLimit-Reset"] = str(ttl)
rate_time_seconds = int(self.rate_time.total_seconds())
if auth:
response.headers[
"RateLimit-Policy"
] = f"{self.rate_amount_key};w={rate_time_seconds}"
response.headers["RateLimit-Policy"] = (
f"{self.rate_amount_key};w={rate_time_seconds}"
)
else:
response.headers[
"RateLimit-Policy"
] = f"{self.rate_amount};w={rate_time_seconds}"
response.headers["RateLimit-Policy"] = (
f"{self.rate_amount};w={rate_time_seconds}"
)
return response

0 comments on commit 26d9503

Please sign in to comment.