Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
25 changes: 16 additions & 9 deletions tests/test_starlette_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -254,33 +258,36 @@ 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"})
assert resp.status_code == 200
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"})
assert resp.status_code == 200
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"})
Expand Down