Repository: abersheeran/asgi-ratelimit (language: python)

Issue:
docs: custom block needs to be adapted
I think since the newest release 0.5.1 the https://github.com/abersheeran/asgi-ratelimit#custom-block-handler is not correct anymore. I'm not sure about it but it seems to me it has to be adapted to the new setup, at least I had to do it today at work on mine

I'll try to come up with a test and change docs when time permits if someone doesnt figure it out before L_)


Discussion / hints:
Ah, this is my negligence. Thanks for pointing out.

After you test and fix the document, if you think it is okay, you only need to publish a new tag 0.5.2, and the GitHub action will automatically push the new package to PyPi.
> if you think it is okay, you only need to publish a new tag 0.5.2, and the GitHub action will automatically push the new package to PyPi.

Supplement: You can use `python script/upload.py` to ensure that `__version__.py`, `pyproject.toml` and git tags are updated at the same time.

Fix patch:
diff --git a/README.md b/README.md
index 4f0d74d..e09adb3 100644
--- a/README.md
+++ b/README.md
@@ -136,10 +136,18 @@ Example: `Rule(second=5, block_time=60)`, this rule will limit the user to a max
 Just specify `on_blocked` and you can customize the asgi application that is called when blocked.
 
 ```python
-async def yourself_429(scope: Scope, receive: Receive, send: Send) -> None:
-    await send({"type": "http.response.start", "status": 429})
-    await send({"type": "http.response.body", "body": b"429 page", "more_body": False})
-
+def yourself_429(retry_after: int):
+    async def inside_yourself_429(scope: Scope, receive: Receive, send: Send) -> None:
+        await send({"type": "http.response.start", "status": 429})
+        await send(
+            {
+                "type": "http.response.body",
+                "body": b"custom 429 page",
+                "more_body": False,
+            }
+        )
+
+    return inside_yourself_429
 
 RateLimitMiddleware(..., on_blocked=yourself_429)
 ```


Test patch:
diff --git a/tests/test_core.py b/tests/test_core.py
index 9308c24..92c104b 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -4,6 +4,7 @@
 from ratelimit import RateLimitMiddleware, Rule
 from ratelimit.auths import EmptyInformation
 from ratelimit.backends.redis import RedisBackend
+from ratelimit.types import Receive, Scope, Send
 
 
 async def hello_world(scope, receive, send):
@@ -90,3 +91,39 @@ async def test_on_auth_error_with_handler():
         response = await client.get("/", headers=None)
         assert response.status_code == 401
         assert response.text == ""
+
+
+def yourself_429(retry_after: int):
+    async def inside_yourself_429(scope: Scope, receive: Receive, send: Send) -> None:
+        await send({"type": "http.response.start", "status": 429})
+        await send(
+            {
+                "type": "http.response.body",
+                "body": b"custom 429 page",
+                "more_body": False,
+            }
+        )
+
+    return inside_yourself_429
+
+
+@pytest.mark.asyncio
+async def test_custom_blocked():
+    rate_limit = RateLimitMiddleware(
+        hello_world,
+        authenticate=auth_func,
+        backend=RedisBackend(),
+        config={r"/": [Rule(second=1), Rule(group="admin")]},
+        on_blocked=yourself_429,
+    )
+
+    async with httpx.AsyncClient(
+        app=rate_limit, base_url="http://testserver"
+    ) as client:  # type: httpx.AsyncClient
+
+        response = await client.get("/", headers={"user": "user", "group": "default"})
+        assert response.status_code == 200
+
+        response = await client.get("/", headers={"user": "user", "group": "default"})
+        assert response.status_code == 429
+        assert response.content == b"custom 429 page"