Compare commits

...

2 Commits

Author SHA1 Message Date
lebaudantoine 678fe48ecc (backend) monitor throttling rate failure through sentry
Use a mixin, introduced by @lunika in the shared
backend library to monitor throttling behavior.

The mixin tracks when throttling limits are reached, sending errors to Sentry
to trigger alerts when configured. This helps detect misconfigurations,
fine-tune throttling settings, and identify suspicious operations.

This enables safely increasing API throttling limits while ensuring stability,
providing confidence that higher limits won’t break the system.
2026-02-09 15:00:37 +01:00
lebaudantoine 575b93a5f0 ♻️(backend) extract throttling classes into a module
Extract throttling classes into a dedicated Python module, following the
structure of suitenumerique/docs.

This is a preparatory refactor to ease upcoming changes to the throttling
implementation. No functional behavior change is introduced in this commit.
2026-02-09 14:48:01 +01:00
4 changed files with 37 additions and 16 deletions
+4
View File
@@ -8,6 +8,10 @@ and this project adheres to
## [Unreleased]
### Added
- ✨(backend) monitor throttling rate failure through sentry #964
### Changed
- ♿️(frontend) improve spinner reducedmotion fallback #931
+26
View File
@@ -0,0 +1,26 @@
"""Throttling modules for the API."""
from lasuite.drf.throttling import MonitoredThrottleMixin
from rest_framework.throttling import AnonRateThrottle
from sentry_sdk import capture_message
def sentry_monitoring_throttle_failure(message):
"""Log when a failure occurs to detect rate limiting issues."""
capture_message(message, "warning")
class MonitoredAnonRateThrottle(MonitoredThrottleMixin, AnonRateThrottle):
"""Throttle for the monitored scoped rate throttle."""
class RequestEntryAnonRateThrottle(MonitoredAnonRateThrottle):
"""Throttle Anonymous user requesting room entry"""
scope = "request_entry"
class CreationCallbackAnonRateThrottle(MonitoredAnonRateThrottle):
"""Throttle Anonymous user requesting room generation callback"""
scope = "creation_callback"
+4 -16
View File
@@ -10,7 +10,7 @@ from django.http import Http404
from django.shortcuts import get_object_or_404
from django.utils.text import slugify
from rest_framework import decorators, mixins, pagination, throttling, viewsets
from rest_framework import decorators, mixins, pagination, viewsets
from rest_framework import (
exceptions as drf_exceptions,
)
@@ -58,7 +58,7 @@ from core.services.room_creation import RoomCreation
from core.services.subtitle import SubtitleException, SubtitleService
from ..authentication.livekit import LiveKitTokenAuthentication
from . import permissions, serializers
from . import permissions, serializers, throttling
from .feature_flag import FeatureFlag
# pylint: disable=too-many-ancestors
@@ -191,18 +191,6 @@ class UserViewSet(
)
class RequestEntryAnonRateThrottle(throttling.AnonRateThrottle):
"""Throttle Anonymous user requesting room entry"""
scope = "request_entry"
class CreationCallbackAnonRateThrottle(throttling.AnonRateThrottle):
"""Throttle Anonymous user requesting room generation callback"""
scope = "creation_callback"
class RoomViewSet(
mixins.CreateModelMixin,
mixins.DestroyModelMixin,
@@ -379,7 +367,7 @@ class RoomViewSet(
methods=["post"],
url_path="request-entry",
permission_classes=[],
throttle_classes=[RequestEntryAnonRateThrottle],
throttle_classes=[throttling.RequestEntryAnonRateThrottle],
)
def request_entry(self, request, pk=None): # pylint: disable=unused-argument
"""Request entry to a room"""
@@ -489,7 +477,7 @@ class RoomViewSet(
methods=["post"],
url_path="creation-callback",
permission_classes=[],
throttle_classes=[CreationCallbackAnonRateThrottle],
throttle_classes=[throttling.CreationCallbackAnonRateThrottle],
)
def creation_callback(self, request):
"""Retrieve cached room data via an unauthenticated request with a unique ID.
+3
View File
@@ -292,6 +292,9 @@ class Base(Configuration):
),
},
}
MONITORED_THROTTLE_FAILURE_CALLBACK = (
"core.api.throttling.sentry_monitoring_throttle_failure"
)
SPECTACULAR_SETTINGS = {
"TITLE": "Meet API",