diff --git a/docs/examples.md b/docs/examples.md index 1ee072e..e7f5fae 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -29,10 +29,11 @@ The tests show a lot of different use cases that are not all covered here. ## Exempt a route from the global limit ```python - @app.route("/someroute") - @limiter.exempt def t(request: Request): return PlainTextResponse("I'm unlimited") + + limiter.exempt(t) + app.add_route("/someroute", t) ``` ## Disable the limiter entirely @@ -44,10 +45,11 @@ Simply pass `enabled=False` to the constructor. ```python limiter = Limiter(key_func=get_remote_address, enabled=False) - @app.route("/someroute") - @limiter.exempt def t(request: Request): return PlainTextResponse("I'm unlimited") + + limiter.exempt(t) + app.add_route("/someroute", t) ``` You can always switch this during the lifetime of the limiter: @@ -76,10 +78,11 @@ Define a function which takes a request as parameter and returns a cost and pass def get_hit_cost(request: Request) -> int: return len(request) - @app.route("/someroute") @limiter.limit("100/minute", cost=get_hit_cost) def t(request: Request): return PlainTextResponse("I'm limited by the request size") + + app.add_route("/someroute", t) ``` ## WSGI vs ASGI Middleware @@ -107,9 +110,10 @@ app.add_middleware(SlowAPIASGIMiddleware) Let's use this route as an example: ```python -@app.route("/some_route/{some_param}") def my_func(some_param): ... + +app.add_route("/someroute/{some_param}", my_func) ``` ```python diff --git a/tests/test_starlette_extension.py b/tests/test_starlette_extension.py index 0e26baa..c086f75 100644 --- a/tests/test_starlette_extension.py +++ b/tests/test_starlette_extension.py @@ -175,15 +175,17 @@ def test_headers_no_breach(self, build_starlette_app): headers_enabled=True, key_func=get_remote_address ) - @app.route("/t1") @limiter.limit("10/minute") def t1(request: Request): return PlainTextResponse("test") + + app.add_route("/t1", t1) - @app.route("/t2") @limiter.limit("2/second; 5 per minute; 10/hour") def t2(request: Request): return PlainTextResponse("test") + + app.add_route("/t2", t2) with hiro.Timeline().freeze(): with TestClient(app) as cli: @@ -208,10 +210,11 @@ def test_headers_breach(self, build_starlette_app): headers_enabled=True, key_func=get_remote_address ) - @app.route("/t1") @limiter.limit("2/second; 10 per minute; 20/hour") def t(request: Request): return PlainTextResponse("test") + + app.add_route("/t1", t) with hiro.Timeline().freeze() as timeline: with TestClient(app) as cli: @@ -233,10 +236,11 @@ def test_retry_after(self, build_starlette_app): headers_enabled=True, key_func=get_remote_address ) - @app.route("/t1") @limiter.limit("1/minute") def t(request: Request): return PlainTextResponse("test") + + app.add_route("/t1", t) with hiro.Timeline().freeze() as timeline: with TestClient(app) as cli: @@ -254,9 +258,10 @@ def test_exempt_decorator(self, build_starlette_app): default_limits=["1/minute"], ) - @app.route("/t1") def t1(request: Request): return PlainTextResponse("test") + + app.add_route("/t1", t1) with TestClient(app) as cli: resp = cli.get("/t1", headers={"X_FORWARDED_FOR": "127.0.0.10"}) @@ -264,11 +269,12 @@ def t1(request: Request): resp2 = cli.get("/t1", headers={"X_FORWARDED_FOR": "127.0.0.10"}) assert resp2.status_code == 429 - @app.route("/t2") - @limiter.exempt def t2(request: Request): """Exempt a sync route""" return PlainTextResponse("test") + + limiter.exempt(t2) + app.add_route("/t2", t2) with TestClient(app) as cli: resp = cli.get("/t2", headers={"X_FORWARDED_FOR": "127.0.0.10"}) @@ -276,11 +282,12 @@ def t2(request: Request): resp2 = cli.get("/t2", headers={"X_FORWARDED_FOR": "127.0.0.10"}) assert resp2.status_code == 200 - @app.route("/t3") - @limiter.exempt async def t3(request: Request): """Exempt an async route""" return PlainTextResponse("test") + + limiter.exempt(t3) + app.add_route("/t3", t3) with TestClient(app) as cli: resp = cli.get("/t3", headers={"X_FORWARDED_FOR": "127.0.0.10"})