bohea / sanic-limiter

Provides rate limiting features for Sanic. Supports in-memory, redis and memcache as storage.
MIT License
85 stars 14 forks source link

Throttling not work #5

Closed hustshawn closed 6 years ago

hustshawn commented 6 years ago

Hi,
I just tried your package and introduced in my sanic app, but find it's not work. Below are my envrionment and demo code.

# pip freeze | grep -i sanic
sanic==0.7.0
sanic-limiter==0.1.2
sanic-motor==0.2.8

# python --version
Python 3.6.1
from sanic import Sanic, Blueprint
from sanic.response import text

from sanic_limiter import Limiter, get_remote_address

app = Sanic('some_sanic')
limiter = Limiter(app, global_limits=['1 per hour', '10 per day'], key_func=get_remote_address)
# bp = Blueprint('some_bp')
# limiter.limit("2 per hour")(bp)

# @bp.route("/bp1")
# async def bp_t1(request):
#     return text("bp_t1")

@app.route("/t1")
@limiter.limit("1 per minute;5/hour")
async def t1(request):
    return text("t1")

@app.route("/t2")
async def t2(request):
    return text("t2")

@app.route("/t3")
@limiter.exempt
async def t3(request):
    return text("t3")

# app.blueprint(bp)

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000, debug=True)

If call /t1, it expected to be 1 per minute and 5 per hour, but it will always be sucessfully called.

[2018-02-01 12:16:36 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/favicon.ico  404 43
[2018-02-01 12:16:41 +0800] [5475] [INFO] KeepAlive Timeout. Closing connection.
[2018-02-01 12:16:43 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:45 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:46 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:46 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:46 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:47 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:47 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:47 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:47 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:47 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:48 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:48 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:48 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:48 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:48 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:49 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:49 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:49 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
[2018-02-01 12:16:49 +0800] - (sanic.access)[INFO][1:2]: GET http://0.0.0.0:5000/t1  200 2
...

Any idea what is wrong?

bohea commented 6 years ago

Hi hustshawn

It seems sanic-limiter0.1.2 is not adapt to sanic0.7, use sanic-limiter0.1.3 instead. pip install git+https://github.com/bohea/sanic-limiter

hustshawn commented 6 years ago

@bohea Thanks for your support. It works fine by using 0.13.

But may I know is it possible to make sanic just return a normal response object (eg. JSON output) with status code 429, instead of just throw a Sanic Exception. Since currently, it is like

Error: too many request

it's a string, and even if I can customize the error message, but it is also have the Error: some message here it would me more friendly if return a JSON response, like

{
  "status": 429,
  "message": "too many request"
}
bohea commented 6 years ago

@hustshawn

sanic_limiter can not return a normal response object, instead, sanic_limiter raise an exception

so you can handle it as you like, e.g:

from sanic_limiter import RateLimitExceeded
from sanic import response

@app.exception(RateLimitExceeded)
def handle_429(request, exception):
    print("catch 429")
    return response.json({
        "status": 429,
        "message": "too many request"
    })
hustshawn commented 6 years ago

It looks great. Thank you for your help.

bohea commented 6 years ago

close

psiofxt commented 6 years ago

Hi! I know this issue is closed but I'm wondering if there is a plan to update the pypi package to be 0.1.3?

Limiter is working great so far, but it would be great to be able to rely on pypi in my production installs.

Thanks!

bohea commented 6 years ago

@psiofxt you may install 0.1.3 via pip now

psiofxt commented 6 years ago

Thank you so much @bohea ! You've saved me a ton of time with this package, I appreciate it.