A rate limiting extension inspired by flask-limiter Provides rate limiting features for Sanic. Supports in-memory, redis and memcache as storage based on alisaifee/limits.
Demo for quickstart:
from sanic import Sanic, Blueprint
from sanic.response import text
from sanic_limiter import Limiter, get_remote_address
app = Sanic(__name__)
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("100 per hour;10/minute")
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)
app.run(host="0.0.0.0", port=5000, debug=True)
Aboved demo provides:
pip install sanic_limiter
There are two basic ways:
constructor:
from sanic_limiter import Limiter, get_remote_address
limiter = Limiter(app, key_func=get_remote_address)
init_app:
from sanic_limiter import Limiter, get_remote_address
limiter = Limiter(key_func=get_remote_address)
limiter.init_app(app)
key function is customizable, an reasonable example is rate limiting by userid:
def get_request_userid(request):
return request.args.get('userid', '')
@limiter.limit("50/minute", key_func=get_request_userid)
async def t1(request):
return text(t1)
basicly, customized key function would like to access sanic request instance(not necessarily although), sanic request instance will be injected if key function has only one positional argument.
if key function has more than one positional argument, an exception will be rasied.
Rate limits are specified as strings following the format:
[count] [per|/] [n (optional)] [second|minute|hour|day|month|year]
You can combine multiple rate limits by separating them with a delimiter of your choice.
Examples:
Flask-Limiter: http://flask-limiter.readthedocs.io/en/stable/recipes.html#keyfunc-customization