A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://django-rest-durin.readthedocs.io/en/latest/_modules/durin/throttling.html below:

durin.throttling — Django-Rest-Durin Documentation (v1.0.0)

Django-Rest-Durin Source code for durin.throttling
"""
Durin provides a throttling class which make use of the
:class:`durin.models.Client` model it offers.

Usage is the same way as other
`DRF throttling classes <https://django-rest-framework.org/api-guide/throttling/>`__.

Example ``settings.py``::

        #...snip...
        REST_FRAMEWORK = {
            "DEFAULT_THROTTLE_CLASSES": ["durin.throttling.UserClientRateThrottle"],
            "DEFAULT_THROTTLE_RATES": {"user_per_client": "10/min"},
        }
        #...snip...

.. data:: "user_per_client"

    default ``scope`` for the :class:`UserClientRateThrottle` class.

    The rate defined here serves as the default rate incase the
    ``throttle_rate`` field on :class:`durin.models.Client` is ``null``.
"""

from django.core.exceptions import ValidationError as DjValidationError
from rest_framework.throttling import UserRateThrottle


[docs]class UserClientRateThrottle(UserRateThrottle):  # lgtm [py/missing-call-to-init]
    """
    Throttles requests by identifying the *authed* **user-client pair**.

    This is useful if you want to define different user throttle rates
    per :class:`durin.models.Client` instance.

    .. versionadded:: 0.2
    """

    #: Same as the default
    cache_format = "throttle_%(scope)s_%(ident)s"

    #: Scope for this throttle
    scope = "user_per_client"

    def __init__(self):
        # lgtm [py/missing-call-to-init]
        pass

[docs]    def allow_request(self, request, view):
        """
        The ``rate`` is set here because we need access to
        ``request`` object which is not available inside :py:meth:`~get_rate`.
        """
        if request.user.is_authenticated and hasattr(request, "_auth"):
            rate = request._auth.client.throttle_rate
            self.rate = rate if rate else self.get_rate()
        else:
            self.rate = self.get_rate()

        self.num_requests, self.duration = self.parse_rate(self.rate)

        return super().allow_request(request, view)

[docs]    def get_cache_key(self, request, view) -> str:
        if request.user.is_authenticated:
            # overwrite
            if hasattr(request, "_auth"):
                ident = self._get_user_client_ident(request)
            else:
                ident = request.user.pk
        else:
            ident = self.get_ident(request)

        return self.cache_format % {"scope": self.scope, "ident": ident}

    def _get_user_client_ident(self, request) -> str:
        """
        Identify the user-client pair making the request.
        (assumes that ``request._auth`` is set, see :py:meth:`~get_cache_key`).
        """
        user_pk = request._auth.user_id
        client_pk = request._auth.client_id
        ident = "user-{0}.client-{1}".format(user_pk, client_pk)
        return ident

[docs]    @staticmethod
    def validate_client_throttle_rate(rate):
        """
        Used for validating the :attr:`throttle_rate` field
        on :class:`durin.models.Client`.

        *For internal use only.*
        """
        TIME_PERIODS_MAP = {"s": 1, "m": 60, "h": 3600, "d": 86400}

        try:
            num, period = rate.split("/")
            return int(num), TIME_PERIODS_MAP[period]
        except KeyError:
            raise DjValidationError("invalid period '{0}'.".format(period))
        except Exception as e:
            raise DjValidationError(e)

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4