Skip to main content

django_rate_limit_redis - это приложение контроля и ограничения входящих/исходящих запросов,

Project description

Django-Rate-Limit

Installation

$ pip install django_rate_limit_redis

Описание

Django-Rate-Limit - это приложение контроля и ограничения входящих/исходящих запросов, разработанное для работы в контейнерезированном состоянии, исполюзующее Redis и PostgreSQL как связующее звено.

rate_limit(
    system=None,  # Имя вашего приложения либо Api константа
    redis_url=None,  # адрес redis
    limit=1,  # разрешенное количество запросов
    window=1,  # временное окно в секундах в котором выполняется разрешенное количество запросов
    blocking_timeout=None,  # время ожидания блокировки исходящих запросов
    request_method=None  # базовый адрес запроса (шаблон урла)
)

Логика

При создании входящего/исходящего запроса, берется шаблон урла, по данному шаблону производится поиск значений настроек в redis, если значение в redis отсутствует, то поиск производится в БД, в случае если в БД данные остутствуют, в БД устанавливается значение по умолчанию переданные в декоратор limit=1, window=1, после чего производится сохранение в redis.

Входящие запросы при превышении частоты запросов возвращают HTTP_429_TOO_MANY_REQUESTS

Исходящие запросы ожидают окна (выполнение рандомно и не имеет сортировки) для отправки запроса на переданный урл, время ожидания регулируется именованным аргументом blocking_timeout, в случае None значения, ожидание окна будет без временного ограничения.


django-admin

В случае использования администрирования, будет доступен раздел содержащий в себе настройки ограничений входящих и исходящих запросов

img.png img_1.png

Добавление новых ограничений производится как вручную, так и автоматически при создании входящих/исходящих запросов. При наличии авторизации в views так же будет учитываться пользователь входящих запросов, для детальной настройки ограничений. Пользователь для исходящих запросов пока не предусмотрен.


Settings

Необходимо добавить путь к Redis и добавить rate_limit в установленные приложения.

redis_db = 2 # удобная вам БД redis
RATELIMITER_REDIS_URL = f'redis://redis:6379/{redis_db}'

# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

INSTALLED_APPS = [
    ...,
    'django_rate_limit_redis',
    'your_app',
]

AUTH_USER_MODEL = 'SomeUsersModel'

Примеры

Входящие запросы

urls.py
from django_rate_limit_redis.decorators import rate_limit
from django.urls import path

from . import views

urlpatterns = [
    path('/your-views/', rate_limit(system='api')(views.YourViews.as_view()), name='your-views'),
    path('/more-your-views/', rate_limit(system='api')(views.MoreYourViews.as_view()), name='more-your-views'),
]

views.py
from django_rate_limit_redis.decorators import rate_limit
from django.utils.decorators import method_decorator
from rest_framework import generics
from .models import SomeMoreModel
from .serializers import SomeMoreSerializer

@method_decorator(rate_limit(system='api'), name='list')
class SomeMoreYourViews(generics.ListAPIView):
    queryset = SomeMoreModel.objects.all().order_by('-id')
    serializer_class = SomeMoreSerializer

Исходящие запросы

Для исходящих запросов необходимо собрать базовый адрес и передать его как именованный аргумент method_name

import json
import requests
from django_rate_limit_redis.decorators import rate_limit

@rate_limit(system="your_name_app", request_method="GET")
def request_get(url, headers=None, data=None, params=None, auth=None):
    response = requests.get(url, headers=headers, data=json.dumps(data), params=params, auth=auth)
    return response

@rate_limit(system="your_name_app", request_method="POST")
def request_post(url, headers=None, data=None, params=None, auth=None):
    response = requests.post(url, headers=headers, data=json.dumps(data), params=params, auth=auth)
    return response

your_url = "https://your_url.com/api/"
some_arg = 321

method_name = f"{your_url}" + "{some_arg}/" #  "https://your_url.com/api/{some_arg}/"
response = request_get(f"{your_url}{some_arg}/", method_name=method_name) #  "https://your_url.com/api/321/"

Для GET запроса, информация будет сохранена в БД и Redis по ключу GET https://your_url.com/api/{some_arg}/ Для POST запроса, информация будет сохранена в БД и Redis по ключу POST https://your_url.com/api/{some_arg}/

Так же есть возможность убрать разделение на методы, убрав именованный аргумент request_method у декоратора @rate_limit, в таком случае будет проверяться урл целиком без привязки к методу https://your_url.com/api/{some_arg}/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_rate_limit_redis-0.0.25.tar.gz (171.5 kB view hashes)

Uploaded Source

Built Distribution

django_rate_limit_redis-0.0.25-py2.py3-none-any.whl (46.4 kB view hashes)

Uploaded Python 2 Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page