Features: 1) Add rate-limiting decorators for multiple API methods across core viewsets; 2) Add translation support to messaging documentation.
Fixes: 1) Fix missing import for `send_message` moved to method scope in Telegram message handler; 2) Correct Swagger UI socket connection setting to `False`. Extra: 1) Minor code cleanup and reformatting in viewsets and settings.
This commit is contained in:
parent
554769d48e
commit
de0cb836fc
4 changed files with 17 additions and 2 deletions
|
|
@ -266,6 +266,7 @@ class CategoryViewSet(EvibesViewSet):
|
||||||
AllowAny,
|
AllowAny,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="4/s" if not settings.DEBUG else "44/s"))
|
||||||
def seo_meta(self, request: Request, *args, **kwargs) -> Response:
|
def seo_meta(self, request: Request, *args, **kwargs) -> Response:
|
||||||
category = self.get_object()
|
category = self.get_object()
|
||||||
|
|
||||||
|
|
@ -506,6 +507,7 @@ class ProductViewSet(EvibesViewSet):
|
||||||
|
|
||||||
# noinspection PyUnusedLocal
|
# noinspection PyUnusedLocal
|
||||||
@action(detail=True, methods=["get"], url_path="feedbacks")
|
@action(detail=True, methods=["get"], url_path="feedbacks")
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="2/s" if not settings.DEBUG else "44/s"))
|
||||||
def feedbacks(self, request: Request, *args, **kwargs) -> Response:
|
def feedbacks(self, request: Request, *args, **kwargs) -> Response:
|
||||||
product = self.get_object()
|
product = self.get_object()
|
||||||
qs = Feedback.objects.filter(order_product__product=product)
|
qs = Feedback.objects.filter(order_product__product=product)
|
||||||
|
|
@ -522,6 +524,7 @@ class ProductViewSet(EvibesViewSet):
|
||||||
AllowAny,
|
AllowAny,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="4/s" if not settings.DEBUG else "44/s"))
|
||||||
def seo_meta(self, request: Request, *args, **kwargs) -> Response:
|
def seo_meta(self, request: Request, *args, **kwargs) -> Response:
|
||||||
p = self.get_object()
|
p = self.get_object()
|
||||||
images = list(p.images.all()[:6])
|
images = list(p.images.all()[:6])
|
||||||
|
|
@ -561,6 +564,10 @@ class ProductViewSet(EvibesViewSet):
|
||||||
}
|
}
|
||||||
return Response(SeoSnapshotSerializer(payload).data)
|
return Response(SeoSnapshotSerializer(payload).data)
|
||||||
|
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="4/s" if not settings.DEBUG else "44/s"))
|
||||||
|
def retrieve(self, request, *args, **kwargs):
|
||||||
|
return super().retrieve(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**VENDOR_SCHEMA)
|
@extend_schema_view(**VENDOR_SCHEMA)
|
||||||
class VendorViewSet(EvibesViewSet):
|
class VendorViewSet(EvibesViewSet):
|
||||||
|
|
@ -665,6 +672,7 @@ class OrderViewSet(EvibesViewSet):
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
@action(detail=False, methods=["get"], url_path="current")
|
@action(detail=False, methods=["get"], url_path="current")
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="1/s" if not settings.DEBUG else "44/s"))
|
||||||
def current(self, request: Request, *args, **kwargs) -> Response:
|
def current(self, request: Request, *args, **kwargs) -> Response:
|
||||||
if not request.user.is_authenticated:
|
if not request.user.is_authenticated:
|
||||||
raise PermissionDenied(permission_denied_message)
|
raise PermissionDenied(permission_denied_message)
|
||||||
|
|
@ -678,6 +686,7 @@ class OrderViewSet(EvibesViewSet):
|
||||||
)
|
)
|
||||||
|
|
||||||
@action(detail=True, methods=["post"], url_path="buy")
|
@action(detail=True, methods=["post"], url_path="buy")
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="1/s" if not settings.DEBUG else "44/s"))
|
||||||
def buy(self, request: Request, *args, **kwargs) -> Response:
|
def buy(self, request: Request, *args, **kwargs) -> Response:
|
||||||
serializer = BuyOrderSerializer(data=request.data)
|
serializer = BuyOrderSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
@ -731,6 +740,7 @@ class OrderViewSet(EvibesViewSet):
|
||||||
return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": str(e)})
|
return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": str(e)})
|
||||||
|
|
||||||
@action(detail=True, methods=["post"], url_path="add_order_product")
|
@action(detail=True, methods=["post"], url_path="add_order_product")
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="1/s" if not settings.DEBUG else "44/s"))
|
||||||
def add_order_product(self, request: Request, *args, **kwargs) -> Response:
|
def add_order_product(self, request: Request, *args, **kwargs) -> Response:
|
||||||
serializer = AddOrderProductSerializer(data=request.data)
|
serializer = AddOrderProductSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
@ -750,6 +760,7 @@ class OrderViewSet(EvibesViewSet):
|
||||||
return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": str(ve)})
|
return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": str(ve)})
|
||||||
|
|
||||||
@action(detail=True, methods=["post"], url_path="remove_order_product")
|
@action(detail=True, methods=["post"], url_path="remove_order_product")
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="1/s" if not settings.DEBUG else "44/s"))
|
||||||
def remove_order_product(self, request: Request, *args, **kwargs) -> Response:
|
def remove_order_product(self, request: Request, *args, **kwargs) -> Response:
|
||||||
serializer = RemoveOrderProductSerializer(data=request.data)
|
serializer = RemoveOrderProductSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
@ -769,6 +780,7 @@ class OrderViewSet(EvibesViewSet):
|
||||||
return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": str(ve)})
|
return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": str(ve)})
|
||||||
|
|
||||||
@action(detail=True, methods=["post"], url_path="bulk_add_order_products")
|
@action(detail=True, methods=["post"], url_path="bulk_add_order_products")
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="1/s" if not settings.DEBUG else "44/s"))
|
||||||
def bulk_add_order_products(self, request: Request, *args, **kwargs) -> Response:
|
def bulk_add_order_products(self, request: Request, *args, **kwargs) -> Response:
|
||||||
serializer = BulkAddOrderProductsSerializer(data=request.data)
|
serializer = BulkAddOrderProductsSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
@ -788,6 +800,7 @@ class OrderViewSet(EvibesViewSet):
|
||||||
return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": str(ve)})
|
return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": str(ve)})
|
||||||
|
|
||||||
@action(detail=True, methods=["post"], url_path="bulk_remove_order_products")
|
@action(detail=True, methods=["post"], url_path="bulk_remove_order_products")
|
||||||
|
@method_decorator(ratelimit(key="ip", rate="1/s" if not settings.DEBUG else "44/s"))
|
||||||
def bulk_remove_order_products(self, request: Request, *args, **kwargs) -> Response:
|
def bulk_remove_order_products(self, request: Request, *args, **kwargs) -> Response:
|
||||||
serializer = BulkRemoveOrderProductsSerializer(data=request.data)
|
serializer = BulkRemoveOrderProductsSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
from drf_spectacular.utils import OpenApiParameter
|
from drf_spectacular.utils import OpenApiParameter
|
||||||
|
|
||||||
from engine.vibes_auth.messaging.serializers import (
|
from engine.vibes_auth.messaging.serializers import (
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ from django.contrib.auth import get_user_model
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
from engine.vibes_auth.choices import SenderType
|
from engine.vibes_auth.choices import SenderType
|
||||||
from engine.vibes_auth.messaging.services import send_message as svc_send_message
|
|
||||||
from engine.vibes_auth.models import ChatThread
|
from engine.vibes_auth.models import ChatThread
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
@ -97,6 +96,8 @@ def build_router() -> Optional["Router"]:
|
||||||
|
|
||||||
@router.message()
|
@router.message()
|
||||||
async def any_message(message: types.Message): # type: ignore[valid-type]
|
async def any_message(message: types.Message): # type: ignore[valid-type]
|
||||||
|
from engine.vibes_auth.messaging.services import send_message as svc_send_message
|
||||||
|
|
||||||
if not message.from_user or not message.text:
|
if not message.from_user or not message.text:
|
||||||
return
|
return
|
||||||
tid = message.from_user.id
|
tid = message.from_user.id
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ SPECTACULAR_SETTINGS = {
|
||||||
"ENABLE_DJANGO_DEPLOY_CHECK": not DEBUG, # noqa: F405
|
"ENABLE_DJANGO_DEPLOY_CHECK": not DEBUG, # noqa: F405
|
||||||
"SWAGGER_UI_FAVICON_HREF": r"/static/favicon.png",
|
"SWAGGER_UI_FAVICON_HREF": r"/static/favicon.png",
|
||||||
"SWAGGER_UI_SETTINGS": {
|
"SWAGGER_UI_SETTINGS": {
|
||||||
"connectSocket": True,
|
"connectSocket": False,
|
||||||
"socketMaxMessages": 8,
|
"socketMaxMessages": 8,
|
||||||
"socketMessagesInitialOpened": False,
|
"socketMessagesInitialOpened": False,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue