Add hourly decay limit

This commit is contained in:
Piero Toffanin 2023-11-16 15:43:47 -05:00
parent a4a67b2b79
commit 6d6202de83
4 changed files with 44 additions and 11 deletions

View file

@ -44,6 +44,22 @@ jobs:
env:
TAG: ${{ startsWith(github.ref, 'refs/tags/') && steps.get-variables.outputs.version || 'latest' }}
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tool-cache: false
# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: true
- name: Build and push Cuda Image
uses: docker/build-push-action@v5
with:

View file

@ -89,7 +89,7 @@ def get_remote_address():
return ip
def get_req_limits(default_limit, api_keys_db, multiplier=1):
def get_req_limits(default_limit, api_keys_db, db_multiplier=1, multiplier=1):
req_limit = default_limit
if api_keys_db:
@ -98,12 +98,13 @@ def get_req_limits(default_limit, api_keys_db, multiplier=1):
if api_key:
db_req_limit = api_keys_db.lookup(api_key)
if db_req_limit is not None:
req_limit = db_req_limit * multiplier
req_limit = db_req_limit * db_multiplier
return req_limit
return int(req_limit * multiplier)
def get_routes_limits(default_req_limit, hourly_req_limit, daily_req_limit, api_keys_db):
def get_routes_limits(args, api_keys_db):
default_req_limit = args.req_limit
if default_req_limit == -1:
# TODO: better way?
default_req_limit = 9999999999999
@ -111,18 +112,22 @@ def get_routes_limits(default_req_limit, hourly_req_limit, daily_req_limit, api_
def minute_limits():
return "%s per minute" % get_req_limits(default_req_limit, api_keys_db)
def hourly_limits():
return "%s per hour" % get_req_limits(hourly_req_limit, api_keys_db, int(os.environ.get("LT_HOURLY_REQ_LIMIT_MULTIPLIER", 60)))
def hourly_limits(n):
def func():
decay = (0.75 ** (n - 1))
return "{} per {} hour".format(get_req_limits(args.hourly_req_limit * n, api_keys_db, int(os.environ.get("LT_HOURLY_REQ_LIMIT_MULTIPLIER", 60) * n), decay), n)
return func
def daily_limits():
return "%s per day" % get_req_limits(daily_req_limit, api_keys_db, int(os.environ.get("LT_DAILY_REQ_LIMIT_MULTIPLIER", 1440)))
return "%s per day" % get_req_limits(args.daily_req_limit, api_keys_db, int(os.environ.get("LT_DAILY_REQ_LIMIT_MULTIPLIER", 1440)))
res = [minute_limits]
if hourly_req_limit > 0:
res.append(hourly_limits)
if args.hourly_req_limit > 0:
for n in range(1, args.hourly_req_limit_decay + 2):
res.append(hourly_limits(n))
if daily_req_limit > 0:
if args.daily_req_limit > 0:
res.append(daily_limits)
return res
@ -202,7 +207,7 @@ def create_app(args):
limiter = Limiter(
key_func=get_remote_address,
default_limits=get_routes_limits(
args.req_limit, args.hourly_req_limit, args.daily_req_limit, api_keys_db
args, api_keys_db
),
storage_uri=args.req_limit_storage,
default_limits_deduct_when=lambda req: True, # Force cost to be called after the request

View file

@ -66,6 +66,11 @@ _default_options_objects = [
'default_value': -1,
'value_type': 'int'
},
{
'name': 'HOURLY_REQ_LIMIT_DECAY',
'default_value': 0,
'value_type': 'int'
},
{
'name': 'DAILY_REQ_LIMIT',
'default_value': -1,

View file

@ -42,6 +42,13 @@ def get_args():
metavar="<number>",
help="Set the default maximum number of requests per hour per client, in addition to req-limit. (%(default)s)",
)
parser.add_argument(
"--hourly-req-limit-decay",
default=DEFARGS['HOURLY_REQ_LIMIT_DECAY'],
type=int,
metavar="<number>",
help="When used in combination with hourly-req-limit, adds additional hourly restrictions that logaritmically decrease for each additional hour. (%(default)s)",
)
parser.add_argument(
"--daily-req-limit",
default=DEFARGS['DAILY_REQ_LIMIT'],