Complete worked example
python
from drf_lab import setup
setup()
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.test import APIRequestFactory, force_authenticate
from rest_framework.throttling import SimpleRateThrottle
from rest_framework.views import APIView
from drf_lab import reset_fixture
def inspect_example(times):
alice, _, _ = reset_fixture()
clock = {"now": 0}
class Quota(SimpleRateThrottle):
rate = "2/min"
timer = staticmethod(lambda: clock["now"])
def get_cache_key(self, request, view):
return "owned-quota:" + str(request.user.pk)
class Read(APIView):
permission_classes = [IsAuthenticated]
throttle_classes = [Quota]
def get(self, request):
return Response({"ok": True})
statuses, waits = [], []
for now in times:
clock["now"] = now
request = APIRequestFactory().get("/quota/")
force_authenticate(request, user=alice)
response = Read.as_view()(request)
statuses.append(response.status_code)
waits.append(int(response["Retry-After"]) if "Retry-After" in response else None)
return {"statuses": statuses, "waits": waits}- Reasoning
- SimpleRateThrottle uses a stable cache key and the current timer to retain recent request history. The protected view runs only after the throttle allows the request. A denied response exposes status 429 and a Retry-After duration that the helper records. Each inspection resets the owned cache and advances the local clock through supplied timestamps. Two requests at time zero are accepted and the third is denied. A later timestamp outside the window can be accepted again. The test compares actual responses, not a manually computed quota result.