Skip to content

Commit 351a994

Browse files
bump version (#6)
* bump version * bump version and black formatter
1 parent 01ef2e9 commit 351a994

33 files changed

+198
-164
lines changed

examples/aws-lambda/main.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88
arate_limit = ARateLimit(ARedis.from_env(allow_telemetry=False))
99
afixed_window = arate_limit.fixed_window(max_number_of_requests=1, window=10, unit="s")
1010

11+
1112
async def main():
12-
res = await afixed_window.block_until_ready('timeout_1', 10)
13+
res = await afixed_window.block_until_ready("timeout_1", 10)
1314
print(f"res: {res}")
1415

16+
1517
def lambda_handler(event, context):
1618
asyncio.run(main())
17-
19+
1820
rate_limit = RateLimit(prefix="test")
1921

2022
fixed_window = rate_limit.fixed_window(max_number_of_requests=2, window=5, unit="s")
2123

22-
res = fixed_window.block_until_ready('timeout_sync', 10)
24+
res = fixed_window.block_until_ready("timeout_sync", 10)
2325
print(f"sync res: {res}")
24-
25-

examples/flask-server/hello.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88

99
app = Flask(__name__)
1010

11+
1112
@app.route("/")
1213
def hello_world():
1314
return "<p>Hello, World!</p>"
1415

16+
1517
@app.route("/request")
1618
def request():
1719
asyncio.run(fixed_window.limit("timeout_1"))
18-
res = asyncio.run(fixed_window.block_until_ready('timeout_1', 10))
20+
res = asyncio.run(fixed_window.block_until_ready("timeout_1", 10))
1921
return f"<p>{res}</p>"

examples/vercel-basic/api/index.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,23 @@
66

77

88
rate_limit = RateLimit(Redis.from_env(allow_telemetry=False))
9-
fixed_window = rate_limit.fixed_window(
10-
max_number_of_requests=5,
11-
window=5,
12-
unit="s"
13-
)
9+
fixed_window = rate_limit.fixed_window(max_number_of_requests=5, window=5, unit="s")
10+
1411

1512
class handler(BaseHTTPRequestHandler):
16-
1713
async def do_GET(self):
18-
1914
limited: RateLimitResponse = await fixed_window.limit("global")
20-
self.send_header('Content-type','text/plain')
21-
self.send_header('X-Ratelimit-Limit', limited["limit"])
22-
self.send_header('X-Ratelimit-Remaining', limited["remaining"])
23-
self.send_header('X-Ratelimit-Reset', limited["reset"])
15+
self.send_header("Content-type", "text/plain")
16+
self.send_header("X-Ratelimit-Limit", limited["limit"])
17+
self.send_header("X-Ratelimit-Remaining", limited["remaining"])
18+
self.send_header("X-Ratelimit-Reset", limited["reset"])
2419

2520
self.end_headers()
2621
if not limited["is_allowed"]:
2722
self.send_response(429)
28-
self.wfile.write('Come back later!'.encode('utf-8'))
23+
self.wfile.write("Come back later!".encode("utf-8"))
2924
else:
3025
self.send_response(200)
31-
self.wfile.write('Hello!'.encode('utf-8'))
26+
self.wfile.write("Hello!".encode("utf-8"))
3227

33-
34-
return
28+
return

examples/vercel/api/index.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88

99
app = Flask(__name__)
1010

11-
@app.route('/')
11+
12+
@app.route("/")
1213
def home():
13-
return 'Hello, World!'
14+
return "Hello, World!"
15+
1416

1517
@app.route("/request")
1618
def request():
1719
asyncio.run(fixed_window.limit("timeout_1"))
18-
res = asyncio.run(fixed_window.block_until_ready('timeout_1', 10))
20+
res = asyncio.run(fixed_window.block_until_ready("timeout_1", 10))
1921
return f"<p>{res}</p>"

poetry.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "upstash_ratelimit"
3-
version = "0.3.6"
3+
version = "0.4.0"
44
description = "Serverless ratelimiting package from Upstash"
55
authors = ["Upstash <support@upstash.com>", "Zgîmbău Tudor <tudor.zgimbau@gmail.com>"]
66
readme = "README.md"
@@ -10,7 +10,7 @@ packages = [{include = "upstash_ratelimit"}]
1010
python = "^3.8"
1111
pytest = "^7.3.0"
1212
pytest-asyncio = "^0.21.0"
13-
upstash-redis = "^0.13.2"
13+
upstash-redis = "^0.14.4"
1414

1515
[build-system]
1616
requires = ["poetry-core"]

tests/algorithm/limiting/test_fixed_window_limiting.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,24 @@
22
from tests.client import rate_limit
33
from pytest import mark
44

5-
fixed_window = rate_limit.fixed_window(max_number_of_requests=1, window=10000, unit="ms")
5+
fixed_window = rate_limit.fixed_window(
6+
max_number_of_requests=1, window=10000, unit="ms"
7+
)
8+
69

710
def test_below_max() -> None:
811
assert (fixed_window.limit("fixed_window_1"))["is_allowed"] is True
912

1013

11-
1214
def test_above_max() -> None:
1315
fixed_window.limit("fixed_window_2")
1416

1517
sleep(2)
16-
18+
1719
assert (fixed_window.limit("fixed_window_2"))["is_allowed"] is False
1820
assert (fixed_window.limit("fixed_window_2"))["is_allowed"] is False
1921

2022

21-
2223
def test_after_window() -> None:
2324
# Exhaust the request limit.
2425
fixed_window.limit("fixed_window_3")
@@ -34,19 +35,13 @@ def test_with_non_ms_unit() -> None:
3435
max_number_of_requests=1, window=10, unit="s"
3536
)
3637

37-
assert (fixed_window_with_seconds.limit("fixed_window_4"))[
38-
"is_allowed"
39-
] is True
38+
assert (fixed_window_with_seconds.limit("fixed_window_4"))["is_allowed"] is True
4039

4140
sleep(1)
4241

4342
# Exhaust the request limit.
44-
assert (fixed_window_with_seconds.limit("fixed_window_4"))[
45-
"is_allowed"
46-
] is False
43+
assert (fixed_window_with_seconds.limit("fixed_window_4"))["is_allowed"] is False
4744

4845
sleep(10)
4946

50-
assert (fixed_window_with_seconds.limit("fixed_window_4"))[
51-
"is_allowed"
52-
] is True
47+
assert (fixed_window_with_seconds.limit("fixed_window_4"))["is_allowed"] is True

tests/algorithm/limiting/test_token_bucket_limiting.py

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@
66
max_number_of_tokens=1, refill_rate=1, interval=3000, unit="ms"
77
)
88

9+
910
def test_below_max() -> None:
1011
assert (token_bucket.limit("token_bucket_1"))["is_allowed"] is True
1112

13+
1214
def test_above_max() -> None:
1315
token_bucket.limit("token_bucket_2")
1416

1517
assert (token_bucket.limit("token_bucket_2"))["is_allowed"] is False
1618
assert (token_bucket.limit("token_bucket_2"))["is_allowed"] is False
1719

20+
1821
def test_after_window() -> None:
1922
# Exhaust the request limit.
2023
token_bucket.limit("token_bucket_3")
@@ -24,33 +27,29 @@ def test_after_window() -> None:
2427

2528
assert (token_bucket.limit("token_bucket_3"))["is_allowed"] is True
2629

30+
2731
def test_with_non_ms_unit() -> None:
2832
token_bucket_with_seconds = rate_limit.token_bucket(
2933
max_number_of_tokens=1, refill_rate=1, interval=3, unit="s"
3034
)
3135

3236
# Exhaust the request limit.
33-
assert (token_bucket_with_seconds.limit("token_bucket_4"))[
34-
"is_allowed"
35-
] is True
37+
assert (token_bucket_with_seconds.limit("token_bucket_4"))["is_allowed"] is True
3638

37-
assert (token_bucket_with_seconds.limit("token_bucket_4"))[
38-
"is_allowed"
39-
] is False
39+
assert (token_bucket_with_seconds.limit("token_bucket_4"))["is_allowed"] is False
4040

4141
# Wait for the refill.
4242
sleep(3)
4343

44-
assert (token_bucket_with_seconds.limit("token_bucket_4"))[
45-
"is_allowed"
46-
] is True
44+
assert (token_bucket_with_seconds.limit("token_bucket_4"))["is_allowed"] is True
4745

4846

4947
# Use a client that has different maximum number of tokens and refill rate.
5048
burst_token_bucket = rate_limit.token_bucket(
5149
max_number_of_tokens=2, refill_rate=1, interval=2000, unit="ms"
5250
)
5351

52+
5453
def test_burst() -> None:
5554
# Exhaust the request limit.
5655
burst_token_bucket.limit("burst_token_bucket_1")
@@ -59,15 +58,10 @@ def test_burst() -> None:
5958
# Wait for the refill.
6059
sleep(2)
6160

62-
assert (burst_token_bucket.limit("burst_token_bucket_1"))[
63-
"is_allowed"
64-
] is True
65-
assert (burst_token_bucket.limit("burst_token_bucket_1"))[
66-
"is_allowed"
67-
] is False
68-
assert (burst_token_bucket.limit("burst_token_bucket_1"))[
69-
"is_allowed"
70-
] is False
61+
assert (burst_token_bucket.limit("burst_token_bucket_1"))["is_allowed"] is True
62+
assert (burst_token_bucket.limit("burst_token_bucket_1"))["is_allowed"] is False
63+
assert (burst_token_bucket.limit("burst_token_bucket_1"))["is_allowed"] is False
64+
7165

7266
def test_with_positive_number_of_tokens_before_the_refill() -> None:
7367
burst_token_bucket.limit("burst_token_bucket_2")
@@ -78,15 +72,10 @@ def test_with_positive_number_of_tokens_before_the_refill() -> None:
7872
"""
7973
sleep(2)
8074

81-
assert (burst_token_bucket.limit("burst_token_bucket_2"))[
82-
"is_allowed"
83-
] is True
84-
assert (burst_token_bucket.limit("burst_token_bucket_2"))[
85-
"is_allowed"
86-
] is True
87-
assert (burst_token_bucket.limit("burst_token_bucket_2"))[
88-
"is_allowed"
89-
] is False
75+
assert (burst_token_bucket.limit("burst_token_bucket_2"))["is_allowed"] is True
76+
assert (burst_token_bucket.limit("burst_token_bucket_2"))["is_allowed"] is True
77+
assert (burst_token_bucket.limit("burst_token_bucket_2"))["is_allowed"] is False
78+
9079

9180
def test_multiple_refills() -> None:
9281
# Exhaust the request limit.
@@ -96,14 +85,6 @@ def test_multiple_refills() -> None:
9685
# Wait for 2 refills.
9786
sleep(4)
9887

99-
assert (burst_token_bucket.limit("burst_token_bucket_3"))[
100-
"is_allowed"
101-
] is True
102-
assert (burst_token_bucket.limit("burst_token_bucket_3"))[
103-
"is_allowed"
104-
] is True
105-
assert (burst_token_bucket.limit("burst_token_bucket_3"))[
106-
"is_allowed"
107-
] is False
108-
109-
88+
assert (burst_token_bucket.limit("burst_token_bucket_3"))["is_allowed"] is True
89+
assert (burst_token_bucket.limit("burst_token_bucket_3"))["is_allowed"] is True
90+
assert (burst_token_bucket.limit("burst_token_bucket_3"))["is_allowed"] is False

tests/algorithm/remaining/test_fixed_window_remaining.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33

44
fixed_window = rate_limit.fixed_window(max_number_of_requests=1, window=3000, unit="ms")
55

6+
67
def test_before_the_first_request() -> None:
78
assert fixed_window.remaining("fixed_window_remaining_1") == 1
89

10+
911
def test_after_the_first_request() -> None:
1012
fixed_window.limit("fixed_window_remaining_2")
1113

tests/algorithm/remaining/test_token_bucket_remaining.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
max_number_of_tokens=1, refill_rate=1, interval=3000, unit="ms"
77
)
88

9+
910
def test_before_the_first_request() -> None:
1011
assert token_bucket.remaining("token_bucket_remaining_1") == 1
1112

13+
1214
def test_after_the_first_request() -> None:
1315
token_bucket.limit("token_bucket_remaining_2")
1416

@@ -22,6 +24,7 @@ def test_after_the_first_request() -> None:
2224
max_number_of_tokens=2, refill_rate=1, interval=2000, unit="ms"
2325
)
2426

27+
2528
def test_after_burst() -> None:
2629
# Exhaust the request limit.
2730
burst_token_bucket.limit("burst_token_bucket_remaining_1")
@@ -32,6 +35,7 @@ def test_after_burst() -> None:
3235

3336
assert burst_token_bucket.remaining("burst_token_bucket_remaining_1") == 1
3437

38+
3539
def test_after_burst_with_positive_number_of_tokens_before_the_refill() -> None:
3640
burst_token_bucket.limit("burst_token_bucket_remaining_2")
3741

tests/algorithm/reset/test_fixed_window_reset.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66

77
fixed_window = rate_limit.fixed_window(max_number_of_requests=1, window=3000, unit="ms")
88

9+
910
def test_before_the_first_request() -> None:
1011
assert fixed_window.reset("fixed_window_reset_1") == -1
1112

13+
1214
def test_after_the_first_request() -> None:
1315
fixed_window.limit("fixed_window_reset_2")
1416

1517
sleep(0.3)
1618

17-
assert pytest.approx(floor((time_ns() / 1000000) / 3000) * 3000 + 3000, 0.1) == fixed_window.reset("fixed_window_reset_2")
19+
assert pytest.approx(
20+
floor((time_ns() / 1000000) / 3000) * 3000 + 3000, 0.1
21+
) == fixed_window.reset("fixed_window_reset_2")

tests/algorithm/reset/test_token_bucket_reset.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@
66
max_number_of_tokens=1, refill_rate=1, interval=3000, unit="ms"
77
)
88

9+
910
def test_before_the_first_request() -> None:
1011
assert token_bucket.reset("token_bucket_reset_1") == -1
1112

13+
1214
def test_after_the_first_request() -> None:
1315
token_bucket.limit("token_bucket_reset_2")
1416

1517
now: int = int(time_ns() / 1000000)
1618

1719
assert now + 3000 - token_bucket.reset("token_bucket_reset_2") <= 500
1820

21+
1922
def test_after_multiple_refills() -> None:
2023
token_bucket.limit("token_bucket_reset_3")
2124

0 commit comments

Comments
 (0)