Skip to content

Commit 72ce344

Browse files
committed
Add throttling for Django REST Framework
We add two limits to the number of requests from authenticated users and non-authenticated users to prevent the APIs from being overloaded.
1 parent 3e2a37c commit 72ce344

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

promgen/settings.py

+8
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@
199199
"DEFAULT_FILTER_BACKENDS": ("django_filters.rest_framework.DjangoFilterBackend",),
200200
"DEFAULT_SCHEMA_CLASS": "promgen.schemas.CustomSchema",
201201
"EXCEPTION_HANDLER": "promgen.middleware.custom_exception_handler",
202+
"DEFAULT_THROTTLE_CLASSES": [
203+
"rest_framework.throttling.UserRateThrottle",
204+
],
205+
"DEFAULT_THROTTLE_RATES": {
206+
# Limits the rate of API calls that may be made by a given user.
207+
# The user id will be used as a unique cache key.
208+
"user": "1000/day",
209+
},
202210
}
203211

204212
# If CELERY_BROKER_URL is set in our environment, then we configure celery as

promgen/tests/test_rest.py

+20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Copyright (c) 2018 LINE Corporation
22
# These sources are released under the terms of the MIT license: see LICENSE
3+
import django.core.cache
34
from django.contrib.auth.models import User, Permission
45
from django.test import override_settings
56
from django.urls import reverse
@@ -9,6 +10,11 @@
910

1011

1112
class RestAPITest(tests.PromgenTest):
13+
def setUp(self):
14+
super().setUp()
15+
# Clear the cache before each test to reset throttling
16+
django.core.cache.cache.clear()
17+
1218
@override_settings(PROMGEN=tests.SETTINGS)
1319
@override_settings(CELERY_TASK_ALWAYS_EAGER=True)
1420
def test_alert_blackhole(self):
@@ -2284,3 +2290,17 @@ def test_rest_shard(self):
22842290
)
22852291
self.assertEqual(response.status_code, 200)
22862292
self.assertEqual(response.json(), expected)
2293+
2294+
@override_settings(PROMGEN=tests.SETTINGS)
2295+
def test_throttling(self):
2296+
# Check throttling for authenticated users
2297+
token = Token.objects.filter(user__username="demo").first().key
2298+
for _ in range(1000):
2299+
response = self.client.get(
2300+
reverse("api-v2:service-list"), HTTP_AUTHORIZATION=f"Token {token}"
2301+
)
2302+
self.assertEqual(response.status_code, 200)
2303+
response = self.client.get(
2304+
reverse("api-v2:service-list"), HTTP_AUTHORIZATION=f"Token {token}"
2305+
)
2306+
self.assertEqual(response.status_code, 429)

0 commit comments

Comments
 (0)