Features: (1) None;

Fixes: (1) Removed all `# type: ignore` annotations across the codebase; (2) Fixed usage of Django Model methods by eliminating unnecessary `# type: ignore` directives; (3) Adjusted usage of functions like `get()` to align with method expectations, removing incorrect comments;

Extra: (1) Deleted `pyrightconfig.json` as part of migration to a stricter type-checked environment; (2) Minor code cleanup, including formatting changes and refactoring import statements in adherence to PEP8 recommendations.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-12-18 15:55:43 +03:00
parent dd8652df96
commit a81f734e23
113 changed files with 837 additions and 598 deletions

View file

@ -1,6 +1,8 @@
from django.contrib.admin import register
from django.db.models import TextField
from django_summernote.admin import SummernoteModelAdminMixin
from django_summernote.admin import (
SummernoteModelAdminMixin,
)
from unfold.admin import ModelAdmin
from unfold_markdown import MarkdownWidget
@ -11,7 +13,7 @@ from engine.core.admin import ActivationActionsMixin, FieldsetsMixin
@register(Post)
class PostAdmin(
SummernoteModelAdminMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
list_display = ("title", "author", "slug", "created", "modified")
list_filter = ("author", "tags", "created", "modified")
search_fields = ("title", "content", "slug")
@ -40,7 +42,7 @@ class PostAdmin(
@register(PostTag)
class PostTagAdmin(ModelAdmin): # type: ignore [type-arg]
class PostTagAdmin(ModelAdmin):
list_display = ("tag_name", "name")
search_fields = ("tag_name", "name")
ordering = ("tag_name",)

View file

@ -9,5 +9,5 @@ class BlogConfig(AppConfig):
# noinspection PyUnresolvedReferences
def ready(self) -> None:
import engine.blog.elasticsearch.documents
import engine.blog.elasticsearch.documents # noqa: F401
import engine.blog.signals # noqa: F401

View file

@ -10,7 +10,7 @@ from engine.core.elasticsearch import (
from engine.core.elasticsearch.documents import BaseDocument
class PostDocument(ActiveOnlyMixin, BaseDocument): # type: ignore [misc]
class PostDocument(ActiveOnlyMixin, BaseDocument):
title = fields.TextField(
attr="title",
analyzer="standard",

View file

@ -4,7 +4,7 @@ from engine.blog.models import Post
from engine.core.filters import CaseInsensitiveListFilter
class PostFilter(FilterSet): # type: ignore [misc]
class PostFilter(FilterSet):
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
slug = CharFilter(field_name="slug", lookup_expr="exact")
author = UUIDFilter(field_name="author__uuid", lookup_expr="exact")

View file

@ -15,8 +15,8 @@ from markdown_field import MarkdownField
from engine.core.abstract import NiceModel
class Post(NiceModel): # type: ignore [django-manager-missing]
__doc__ = _( # type: ignore [assignment]
class Post(NiceModel):
__doc__ = _(
"Represents a blog post model. "
"The Post class defines the structure and behavior of a blog post. "
"It includes attributes for author, title, content, optional file attachment, slug, and associated tags. "

View file

@ -11,8 +11,8 @@ from engine.core.permissions import EvibesPermission
@extend_schema_view(**POST_SCHEMA)
class PostViewSet(ReadOnlyModelViewSet): # type: ignore [type-arg]
__doc__ = _( # type: ignore [assignment]
class PostViewSet(ReadOnlyModelViewSet):
__doc__ = _(
"Encapsulates operations for managing and retrieving Post entities in a read-only model view set. "
"This class is tailored to handle Post objects that are active and allows filtration based on defined "
"filters. It integrates with Django's backend filtering system and ensures operations align with the "

View file

@ -24,12 +24,12 @@ class NiceModel(Model):
)
created = CreationDateTimeField(
_("created"), help_text=_("when the object first appeared on the database")
) # type: ignore [no-untyped-call]
)
modified = ModificationDateTimeField(
_("modified"), help_text=_("when the object was last modified")
) # type: ignore [no-untyped-call]
)
def save( # type: ignore [override]
def save(
self,
*,
force_insert: bool = False,

View file

@ -31,6 +31,7 @@ from mptt.admin import DraggableMPTTAdmin
from unfold.admin import ModelAdmin, TabularInline
from unfold.contrib.import_export.forms import ExportForm, ImportForm
from unfold.decorators import action
from unfold.typing import FieldsetsType
from unfold.widgets import UnfoldAdminSelectWidget, UnfoldAdminTextInputWidget
from engine.core.forms import (
@ -70,9 +71,7 @@ class FieldsetsMixin:
additional_fields: list[str] | None = []
model: ClassVar[Type[Model]]
def get_fieldsets(
self, request: HttpRequest, obj: Any = None
) -> list[tuple[str, dict[str, list[str]]]]:
def get_fieldsets(self, request: HttpRequest, obj: Any = None) -> FieldsetsType:
if request:
pass
@ -82,8 +81,8 @@ class FieldsetsMixin:
fieldsets = []
def add_translations_fieldset(
fss: list[tuple[str, dict[str, list[str]]]],
) -> list[tuple[str, dict[str, list[str]]]]:
fss: FieldsetsType,
) -> FieldsetsType:
with suppress(NotRegistered):
transoptions = translator.get_options_for_model(self.model)
translation_fields = []
@ -95,7 +94,7 @@ class FieldsetsMixin:
_("translations"),
{"classes": ["tab"], "fields": translation_fields},
)
] # type: ignore [list-item]
]
return fss
if self.general_fields:
@ -140,8 +139,8 @@ class FieldsetsMixin:
ts.append(name)
if ts:
fieldsets.append((_("timestamps"), {"classes": ["tab"], "fields": ts}))
fieldsets = add_translations_fieldset(fieldsets) # type: ignore [arg-type, assignment]
return fieldsets # type: ignore [return-value]
fieldsets = add_translations_fieldset(fieldsets)
return fieldsets
# noinspection PyUnresolvedReferences
@ -161,14 +160,14 @@ class ActivationActionsMixin:
def activate_selected(self, request: HttpRequest, queryset: QuerySet[Any]) -> None:
try:
queryset.update(is_active=True)
self.message_user( # type: ignore [attr-defined]
self.message_user(
request=request,
message=_("selected items have been activated.").lower(),
level=messages.SUCCESS,
)
except Exception as e:
self.message_user(request=request, message=str(e), level=messages.ERROR) # type: ignore [attr-defined]
self.message_user(request=request, message=str(e), level=messages.ERROR)
@action(
description=_("deactivate selected %(verbose_name_plural)s").lower(),
@ -179,17 +178,17 @@ class ActivationActionsMixin:
) -> None:
try:
queryset.update(is_active=False)
self.message_user( # type: ignore [attr-defined]
self.message_user(
request=request,
message=_("selected items have been deactivated.").lower(),
level=messages.SUCCESS,
)
except Exception as e:
self.message_user(request=request, message=str(e), level=messages.ERROR) # type: ignore [attr-defined]
self.message_user(request=request, message=str(e), level=messages.ERROR)
class AttributeValueInline(TabularInline): # type: ignore [type-arg]
class AttributeValueInline(TabularInline):
model = AttributeValue
extra = 0
autocomplete_fields = ["attribute"]
@ -201,7 +200,7 @@ class AttributeValueInline(TabularInline): # type: ignore [type-arg]
return super().get_queryset(request).select_related("attribute", "product")
class ProductImageInline(TabularInline): # type: ignore [type-arg]
class ProductImageInline(TabularInline):
model = ProductImage
extra = 0
tab = True
@ -212,7 +211,7 @@ class ProductImageInline(TabularInline): # type: ignore [type-arg]
return super().get_queryset(request).select_related("product")
class StockInline(TabularInline): # type: ignore [type-arg]
class StockInline(TabularInline):
model = Stock
extra = 0
form = StockForm
@ -224,7 +223,7 @@ class StockInline(TabularInline): # type: ignore [type-arg]
return super().get_queryset(request).select_related("vendor", "product")
class OrderProductInline(TabularInline): # type: ignore [type-arg]
class OrderProductInline(TabularInline):
model = OrderProduct
extra = 0
readonly_fields = ("product", "quantity", "buy_price")
@ -242,7 +241,7 @@ class OrderProductInline(TabularInline): # type: ignore [type-arg]
)
class CategoryChildrenInline(TabularInline): # type: ignore [type-arg]
class CategoryChildrenInline(TabularInline):
model = Category
fk_name = "parent"
extra = 0
@ -255,9 +254,9 @@ class CategoryChildrenInline(TabularInline): # type: ignore [type-arg]
@register(AttributeGroup)
class AttributeGroupAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = AttributeGroup # type: ignore [misc]
model = AttributeGroup
list_display = (
"name",
"modified",
@ -281,9 +280,9 @@ class AttributeGroupAdmin(
@register(Attribute)
class AttributeAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = Attribute # type: ignore [misc]
model = Attribute
list_display = (
"name",
"group",
@ -320,9 +319,9 @@ class AttributeAdmin(
@register(AttributeValue)
class AttributeValueAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin): # type: ignore [misc, type-arg]
class AttributeValueAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
# noinspection PyClassVar
model = AttributeValue # type: ignore [misc]
model = AttributeValue
list_display = (
"attribute",
"value",
@ -413,9 +412,9 @@ class CategoryAdmin(
@register(Brand)
class BrandAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = Brand # type: ignore [misc]
model = Brand
list_display = (
"name",
"priority",
@ -451,9 +450,9 @@ class ProductAdmin(
ActivationActionsMixin,
ModelAdmin,
ImportExportModelAdmin,
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = Product # type: ignore [misc]
model = Product
list_display = (
"sku",
"name",
@ -532,9 +531,9 @@ class ProductAdmin(
@register(ProductTag)
class ProductTagAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = ProductTag # type: ignore [misc]
model = ProductTag
list_display = ("tag_name",)
search_fields = ("tag_name",)
readonly_fields = (
@ -552,9 +551,9 @@ class ProductTagAdmin(
@register(CategoryTag)
class CategoryTagAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = CategoryTag # type: ignore [misc]
model = CategoryTag
list_display = (
"name",
"tag_name",
@ -580,9 +579,9 @@ class CategoryTagAdmin(
@register(Vendor)
class VendorAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = Vendor # type: ignore [misc]
model = Vendor
list_display = (
"name",
"markup_percent",
@ -622,9 +621,9 @@ class VendorAdmin(
@register(Feedback)
class FeedbackAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = Feedback # type: ignore [misc]
model = Feedback
list_display = (
"order_product",
"rating",
@ -657,9 +656,9 @@ class FeedbackAdmin(
@register(Order)
class OrderAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = Order # type: ignore [misc]
model = Order
list_display = (
"human_readable_id",
"user",
@ -710,9 +709,9 @@ class OrderAdmin(
@register(OrderProduct)
class OrderProductAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = OrderProduct # type: ignore [misc]
model = OrderProduct
list_display = (
"order",
"product",
@ -750,9 +749,9 @@ class OrderProductAdmin(
@register(PromoCode)
class PromoCodeAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = PromoCode # type: ignore [misc]
model = PromoCode
list_display = (
"code",
"discount_percent",
@ -796,9 +795,9 @@ class PromoCodeAdmin(
@register(Promotion)
class PromotionAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = Promotion # type: ignore [misc]
model = Promotion
list_display = (
"name",
"discount_percent",
@ -825,9 +824,9 @@ class PromotionAdmin(
@register(Stock)
class StockAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = Stock # type: ignore [misc]
model = Stock
form = StockForm
list_display = (
"product",
@ -875,9 +874,9 @@ class StockAdmin(
@register(Wishlist)
class WishlistAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = Wishlist # type: ignore [misc]
model = Wishlist
list_display = (
"user",
"modified",
@ -903,9 +902,9 @@ class WishlistAdmin(
@register(ProductImage)
class ProductImageAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ActivationActionsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = ProductImage # type: ignore [misc]
model = ProductImage
list_display = (
"alt",
"product",
@ -939,9 +938,9 @@ class ProductImageAdmin(
@register(Address)
class AddressAdmin(DjangoQLSearchMixin, FieldsetsMixin, GISModelAdmin): # type: ignore [misc]
class AddressAdmin(DjangoQLSearchMixin, FieldsetsMixin, GISModelAdmin):
# noinspection PyClassVar
model = Address # type: ignore [misc]
model = Address
list_display = (
"street",
"city",
@ -991,9 +990,9 @@ class AddressAdmin(DjangoQLSearchMixin, FieldsetsMixin, GISModelAdmin): # type:
@register(CustomerRelationshipManagementProvider)
class CustomerRelationshipManagementProviderAdmin(
DjangoQLSearchMixin, FieldsetsMixin, ModelAdmin
): # type: ignore [misc, type-arg]
):
# noinspection PyClassVar
model = CustomerRelationshipManagementProvider # type: ignore [misc]
model = CustomerRelationshipManagementProvider
list_display = (
"name",
"default",
@ -1020,9 +1019,9 @@ class CustomerRelationshipManagementProviderAdmin(
@register(OrderCrmLink)
class OrderCrmLinkAdmin(DjangoQLSearchMixin, FieldsetsMixin, ModelAdmin): # type: ignore [misc, type-arg]
class OrderCrmLinkAdmin(DjangoQLSearchMixin, FieldsetsMixin, ModelAdmin):
# noinspection PyClassVar
model = OrderCrmLink # type: ignore [misc]
model = OrderCrmLink
list_display = (
"crm_lead_id",
"order",
@ -1086,7 +1085,7 @@ class ConstanceConfig:
# noinspection PyTypeChecker
site.unregister([Config])
# noinspection PyTypeChecker
site.register([ConstanceConfig], BaseConstanceAdmin) # type: ignore [list-item]
site.register([ConstanceConfig], BaseConstanceAdmin)
site.site_title = settings.PROJECT_NAME
site.site_header = "eVibes"
site.index_title = settings.PROJECT_NAME

View file

@ -434,9 +434,9 @@ def _lang_analyzer(lang_code: str) -> str:
class ActiveOnlyMixin:
def get_queryset(self) -> QuerySet[Any]:
return super().get_queryset().filter(is_active=True) # type: ignore [no-any-return, misc]
return super().get_queryset().filter(is_active=True)
def should_index_object(self, obj) -> bool: # type: ignore [no-untyped-def]
def should_index_object(self, obj) -> bool:
return getattr(obj, "is_active", False)

View file

@ -13,7 +13,7 @@ from engine.core.elasticsearch import (
from engine.core.models import Brand, Category, Product
class BaseDocument(Document): # type: ignore [misc]
class BaseDocument(Document):
name = fields.TextField(
attr="name",
analyzer="standard",
@ -197,7 +197,7 @@ add_multilang_fields(BrandDocument)
registry.register_document(BrandDocument)
class TestModelDocument(Document): # type: ignore [misc]
class TestModelDocument(Document):
class Index:
name = "testmodels"

View file

@ -51,7 +51,7 @@ from engine.core.models import (
logger = logging.getLogger(__name__)
class CaseInsensitiveListFilter(BaseInFilter, CharFilter): # type: ignore [misc]
class CaseInsensitiveListFilter(BaseInFilter, CharFilter):
def filter(self, qs: QuerySet[Any], value: Any) -> QuerySet[Any]:
if not value:
return qs
@ -74,7 +74,7 @@ class CaseInsensitiveListFilter(BaseInFilter, CharFilter): # type: ignore [misc
# noinspection PyUnusedLocal
class ProductFilter(FilterSet): # type: ignore [misc]
class ProductFilter(FilterSet):
search = CharFilter(field_name="name", method="search_products", label=_("Search"))
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID"))
name = CharFilter(lookup_expr="icontains", label=_("Name"))
@ -188,7 +188,7 @@ class ProductFilter(FilterSet): # type: ignore [misc]
if not value:
return queryset
es_products = process_query(query=value, indexes=("products",)) # type: ignore
es_products = process_query(query=value, indexes=("products",))
uuids = [p.get("uuid") for p in (es_products or {}).get("products", [])][:33]
if not uuids:
return queryset.none()
@ -392,7 +392,7 @@ class ProductFilter(FilterSet): # type: ignore [misc]
# noinspection PyUnusedLocal
class OrderFilter(FilterSet): # type: ignore [misc]
class OrderFilter(FilterSet):
search = CharFilter(
method="filter_search",
label=_("Search (ID, product name or part number)"),
@ -455,7 +455,7 @@ class OrderFilter(FilterSet): # type: ignore [misc]
).distinct()
class WishlistFilter(FilterSet): # type: ignore [misc]
class WishlistFilter(FilterSet):
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
user_email = CharFilter(
field_name="user__email", lookup_expr="iexact", label=_("User email")
@ -479,7 +479,7 @@ class WishlistFilter(FilterSet): # type: ignore [misc]
# noinspection PyUnusedLocal
class CategoryFilter(FilterSet): # type: ignore [misc]
class CategoryFilter(FilterSet):
search = CharFilter(
field_name="name", method="search_categories", label=_("Search")
)
@ -521,7 +521,7 @@ class CategoryFilter(FilterSet): # type: ignore [misc]
for category in process_query(query=value, indexes=("categories",))[
"categories"
]
] # type: ignore
]
return queryset.filter(uuid__in=uuids)
@ -621,7 +621,7 @@ class CategoryFilter(FilterSet): # type: ignore [misc]
# noinspection PyUnusedLocal
class BrandFilter(FilterSet): # type: ignore [misc]
class BrandFilter(FilterSet):
search = CharFilter(field_name="name", method="search_brands", label=_("Search"))
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
name = CharFilter(lookup_expr="icontains", label=_("Name"))
@ -653,12 +653,12 @@ class BrandFilter(FilterSet): # type: ignore [misc]
uuids = [
brand.get("uuid")
for brand in process_query(query=value, indexes=("brands",))["brands"]
] # type: ignore
]
return queryset.filter(uuid__in=uuids)
class FeedbackFilter(FilterSet): # type: ignore [misc]
class FeedbackFilter(FilterSet):
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID"))
product_uuid = UUIDFilter(
field_name="order_product__product__uuid",
@ -687,7 +687,7 @@ class FeedbackFilter(FilterSet): # type: ignore [misc]
fields = ["uuid", "product_uuid", "user_uuid", "order_by"]
class AddressFilter(FilterSet): # type: ignore [misc]
class AddressFilter(FilterSet):
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID"))
user_uuid = UUIDFilter(
field_name="user__uuid", lookup_expr="exact", label=_("User UUID")

View file

@ -3,7 +3,7 @@ from typing import Any
from graphene import Mutation
class BaseMutation(Mutation): # type: ignore [misc]
class BaseMutation(Mutation):
def __init__(self, *args: list[Any], **kwargs: dict[Any, Any]) -> None:
super().__init__(*args, **kwargs)

View file

@ -53,7 +53,7 @@ def resolve_tags(product, tag_uuids):
product.tags.set(tags)
class AttributeInput(InputObjectType): # type: ignore[misc]
class AttributeInput(InputObjectType):
attribute_uuid = UUID(required=False, name="attributeUuid")
group_name = String(required=False, name="groupName")
attribute_name = String(required=False, name="attributeName")
@ -61,7 +61,7 @@ class AttributeInput(InputObjectType): # type: ignore[misc]
value = String(required=True)
class ProductInput(InputObjectType): # type: ignore[misc]
class ProductInput(InputObjectType):
name = NonNull(String)
description = String(required=False)
is_digital = Boolean(required=False, name="isDigital")
@ -85,15 +85,15 @@ class CreateProduct(BaseMutation):
product = Field(ProductType)
@staticmethod
def mutate(parent, info, product_data): # type: ignore [override]
def mutate(parent, info, product_data):
user = info.context.user
if not user.has_perm("core.add_product"):
raise PermissionDenied(permission_denied_message)
category = Category.objects.get(uuid=product_data["category_uuid"]) # type: ignore[index]
category = Category.objects.get(uuid=product_data["category_uuid"])
brand = None
if product_data.get("brand_uuid"):
with suppress(Brand.DoesNotExist): # type: ignore[name-defined]
brand = Brand.objects.get(uuid=product_data["brand_uuid"]) # type: ignore[index]
with suppress(Brand.DoesNotExist):
brand = Brand.objects.get(uuid=product_data["brand_uuid"])
product = Product.objects.create(
name=product_data["name"],
@ -124,7 +124,7 @@ class UpdateProduct(BaseMutation):
product = Field(ProductType)
@staticmethod
def mutate(parent, info, product_uuid, product_data): # type: ignore [override]
def mutate(parent, info, product_uuid, product_data):
user = info.context.user
if not user.has_perm("core.change_product"):
raise PermissionDenied(permission_denied_message)
@ -142,10 +142,10 @@ class UpdateProduct(BaseMutation):
updates[model_field] = product_data[field_in]
if product_data.get("category_uuid"):
product.category = Category.objects.get(uuid=product_data["category_uuid"]) # type: ignore[index]
product.category = Category.objects.get(uuid=product_data["category_uuid"])
if product_data.get("brand_uuid") is not None:
if product_data.get("brand_uuid"):
product.brand = Brand.objects.get(uuid=product_data["brand_uuid"]) # type: ignore[index]
product.brand = Brand.objects.get(uuid=product_data["brand_uuid"])
else:
product.brand = None
@ -171,7 +171,7 @@ class DeleteProduct(BaseMutation):
ok = Boolean()
@staticmethod
def mutate(parent, info, product_uuid): # type: ignore [override]
def mutate(parent, info, product_uuid):
user = info.context.user
if not user.has_perm("core.delete_product"):
raise PermissionDenied(permission_denied_message)

View file

@ -49,7 +49,7 @@ class CacheOperator(BaseMutation):
data = GenericScalar(description=_("cached data"))
@staticmethod
def mutate(parent, info, key, data=None, timeout=None) -> dict[Any, Any]: # type: ignore [override]
def mutate(parent, info, key, data=None, timeout=None) -> dict[Any, Any]:
return camelize(web_cache(info.context, key, data, timeout))
@ -64,7 +64,7 @@ class RequestCursedURL(BaseMutation):
data = GenericScalar(description=_("camelized JSON data from the requested URL"))
@staticmethod
def mutate(parent, info, url) -> dict[str, Any]: # type: ignore [override]
def mutate(parent, info, url) -> dict[str, Any]:
if not is_url_safe(url):
raise BadRequest(_("only URLs starting with http(s):// are allowed"))
try:
@ -94,7 +94,7 @@ class AddOrderProduct(BaseMutation):
order = Field(OrderType)
@staticmethod
def mutate(parent, info, product_uuid, order_uuid, attributes=None): # type: ignore [override]
def mutate(parent, info, product_uuid, order_uuid, attributes=None):
user = info.context.user
try:
order = Order.objects.get(uuid=order_uuid)
@ -123,7 +123,7 @@ class RemoveOrderProduct(BaseMutation):
order = Field(OrderType)
@staticmethod
def mutate(parent, info, product_uuid, order_uuid, attributes=None): # type: ignore [override]
def mutate(parent, info, product_uuid, order_uuid, attributes=None):
user = info.context.user
try:
order = Order.objects.get(uuid=order_uuid)
@ -150,7 +150,7 @@ class RemoveAllOrderProducts(BaseMutation):
order = Field(OrderType)
@staticmethod
def mutate(parent, info, order_uuid): # type: ignore [override]
def mutate(parent, info, order_uuid):
user = info.context.user
order = Order.objects.get(uuid=order_uuid)
if not (user.has_perm("core.delete_orderproduct") or user == order.user):
@ -173,7 +173,7 @@ class RemoveOrderProductsOfAKind(BaseMutation):
order = Field(OrderType)
@staticmethod
def mutate(parent, info, product_uuid, order_uuid): # type: ignore [override]
def mutate(parent, info, product_uuid, order_uuid):
user = info.context.user
order = Order.objects.get(uuid=order_uuid)
if not (user.has_perm("core.delete_orderproduct") or user == order.user):
@ -214,7 +214,7 @@ class BuyOrder(BaseMutation):
shipping_address=None,
billing_address=None,
chosen_products=None,
): # type: ignore [override]
):
if not any([order_uuid, order_hr_id]) or all([order_uuid, order_hr_id]):
raise BadRequest(
_(
@ -276,7 +276,7 @@ class BulkOrderAction(BaseMutation):
products,
order_uuid=None,
order_hr_id=None,
): # type: ignore [override]
):
if not any([order_uuid, order_hr_id]) or all([order_uuid, order_hr_id]):
raise BadRequest(
_(
@ -326,7 +326,7 @@ class BulkWishlistAction(BaseMutation):
action,
products,
wishlist_uuid=None,
): # type: ignore [override]
):
if not wishlist_uuid:
raise BadRequest(_("please provide wishlist_uuid value"))
user = info.context.user
@ -379,7 +379,7 @@ class BuyUnregisteredOrder(BaseMutation):
customer_shipping_address=None,
promocode_uuid=None,
is_business=False,
): # type: ignore [override]
):
order = Order.objects.create(status="MOMENTAL")
transaction = order.buy_without_registration(
products=products,
@ -408,7 +408,7 @@ class AddWishlistProduct(BaseMutation):
wishlist = Field(WishlistType)
@staticmethod
def mutate(parent, info, product_uuid, wishlist_uuid): # type: ignore [override]
def mutate(parent, info, product_uuid, wishlist_uuid):
user = info.context.user
try:
wishlist = Wishlist.objects.get(uuid=wishlist_uuid)
@ -436,7 +436,7 @@ class RemoveWishlistProduct(BaseMutation):
wishlist = Field(WishlistType)
@staticmethod
def mutate(parent, info, product_uuid, wishlist_uuid): # type: ignore [override]
def mutate(parent, info, product_uuid, wishlist_uuid):
user = info.context.user
try:
wishlist = Wishlist.objects.get(uuid=wishlist_uuid)
@ -463,7 +463,7 @@ class RemoveAllWishlistProducts(BaseMutation):
wishlist = Field(WishlistType)
@staticmethod
def mutate(parent, info, wishlist_uuid): # type: ignore [override]
def mutate(parent, info, wishlist_uuid):
user = info.context.user
try:
wishlist = Wishlist.objects.get(uuid=wishlist_uuid)
@ -494,7 +494,7 @@ class BuyWishlist(BaseMutation):
transaction = Field(TransactionType, required=False)
@staticmethod
def mutate(parent, info, wishlist_uuid, force_balance=False, force_payment=False): # type: ignore [override]
def mutate(parent, info, wishlist_uuid, force_balance=False, force_payment=False):
user = info.context.user
try:
wishlist = Wishlist.objects.get(uuid=wishlist_uuid)
@ -557,7 +557,7 @@ class BuyProduct(BaseMutation):
attributes=None,
force_balance=False,
force_payment=False,
): # type: ignore [override]
):
user = info.context.user
order = Order.objects.create(user=user, status="MOMENTAL")
order.add_product(
@ -589,7 +589,7 @@ class FeedbackProductAction(BaseMutation):
feedback = Field(FeedbackType, required=False)
@staticmethod
def mutate(parent, info, order_product_uuid, action, comment=None, rating=None): # type: ignore [override]
def mutate(parent, info, order_product_uuid, action, comment=None, rating=None):
user = info.context.user
try:
order_product = OrderProduct.objects.get(uuid=order_product_uuid)
@ -620,7 +620,7 @@ class CreateAddress(BaseMutation):
address = Field(AddressType)
@staticmethod
def mutate(parent, info, raw_data): # type: ignore [override]
def mutate(parent, info, raw_data):
user = info.context.user if info.context.user.is_authenticated else None
address = Address.objects.create(raw_data=raw_data, user=user)
@ -635,7 +635,7 @@ class DeleteAddress(BaseMutation):
success = Boolean()
@staticmethod
def mutate(parent, info, uuid): # type: ignore [override]
def mutate(parent, info, uuid):
try:
address = Address.objects.get(uuid=uuid)
if (
@ -663,7 +663,7 @@ class AutocompleteAddress(BaseMutation):
suggestions = GenericScalar()
@staticmethod
def mutate(parent, info, q, limit): # type: ignore [override]
def mutate(parent, info, q, limit):
if 1 > limit > 10:
raise BadRequest(_("limit must be between 1 and 10"))
try:
@ -688,7 +688,7 @@ class ContactUs(BaseMutation):
error = String()
@staticmethod
def mutate(parent, info, email, name, subject, message, phone_number=None): # type: ignore [override]
def mutate(parent, info, email, name, subject, message, phone_number=None):
try:
contact_us_email.delay(
{
@ -717,7 +717,7 @@ class Search(BaseMutation):
description = _("elasticsearch - works like a charm")
@staticmethod
def mutate(parent, info, query): # type: ignore [override]
def mutate(parent, info, query):
data = process_query(query=query, request=info.context)
# noinspection PyTypeChecker

View file

@ -60,7 +60,7 @@ from engine.payments.graphene.object_types import TransactionType
logger = logging.getLogger(__name__)
class SEOMetaType(ObjectType): # type: ignore [misc]
class SEOMetaType(ObjectType):
title = String()
description = String()
canonical = String()
@ -71,7 +71,7 @@ class SEOMetaType(ObjectType): # type: ignore [misc]
hreflang = String()
class AttributeType(DjangoObjectType): # type: ignore [misc]
class AttributeType(DjangoObjectType):
values = List(lambda: AttributeValueType, description=_("attribute values"))
class Meta:
@ -91,7 +91,7 @@ class AttributeType(DjangoObjectType): # type: ignore [misc]
return base_qs
class AttributeGroupType(DjangoObjectType): # type: ignore [misc]
class AttributeGroupType(DjangoObjectType):
attributes = List(lambda: AttributeType, description=_("grouped attributes"))
class Meta:
@ -112,7 +112,7 @@ class AttributeGroupType(DjangoObjectType): # type: ignore [misc]
return qs
class BrandType(DjangoObjectType): # type: ignore [misc]
class BrandType(DjangoObjectType):
categories = List(lambda: CategoryType, description=_("categories"))
seo_meta = Field(SEOMetaType, description=_("SEO Meta snapshot"))
@ -198,17 +198,17 @@ class BrandType(DjangoObjectType): # type: ignore [misc]
}
class FilterableAttributeType(ObjectType): # type: ignore [misc]
class FilterableAttributeType(ObjectType):
attribute_name = String(required=True)
possible_values = List(String, required=True)
class MinMaxPriceType(ObjectType): # type: ignore [misc]
class MinMaxPriceType(ObjectType):
min_price = Float()
max_price = Float()
class CategoryType(DjangoObjectType): # type: ignore [misc]
class CategoryType(DjangoObjectType):
children = List(
lambda: CategoryType,
description=_("categories"),
@ -358,7 +358,7 @@ class CategoryType(DjangoObjectType): # type: ignore [misc]
}
class VendorType(DjangoObjectType): # type: ignore [misc]
class VendorType(DjangoObjectType):
markup_percent = Float(description=_("markup percentage"))
class Meta:
@ -369,7 +369,7 @@ class VendorType(DjangoObjectType): # type: ignore [misc]
description = _("vendors")
class AddressType(DjangoObjectType): # type: ignore [misc]
class AddressType(DjangoObjectType):
latitude = Float(description=_("Latitude (Y coordinate)"))
longitude = Float(description=_("Longitude (X coordinate)"))
@ -399,7 +399,7 @@ class AddressType(DjangoObjectType): # type: ignore [misc]
return self.location.y if self.location else None
class FeedbackType(DjangoObjectType): # type: ignore [misc]
class FeedbackType(DjangoObjectType):
comment = String(description=_("comment"))
rating = Int(
description=_("rating value from 1 to 10, inclusive, or 0 if not set.")
@ -413,7 +413,7 @@ class FeedbackType(DjangoObjectType): # type: ignore [misc]
description = _("represents feedback from a user.")
class OrderProductType(DjangoObjectType): # type: ignore [misc]
class OrderProductType(DjangoObjectType):
attributes = GenericScalar(description=_("attributes"))
notifications = GenericScalar(description=_("notifications"))
download_url = String(
@ -451,7 +451,7 @@ class OrderProductType(DjangoObjectType): # type: ignore [misc]
return self.download_url
class OrderType(DjangoObjectType): # type: ignore [misc]
class OrderType(DjangoObjectType):
order_products = DjangoFilterConnectionField(
OrderProductType, description=_("a list of order products in this order")
)
@ -508,7 +508,7 @@ class OrderType(DjangoObjectType): # type: ignore [misc]
return None
class ProductImageType(DjangoObjectType): # type: ignore [misc]
class ProductImageType(DjangoObjectType):
image = String(description=_("image url"))
class Meta:
@ -522,7 +522,7 @@ class ProductImageType(DjangoObjectType): # type: ignore [misc]
return info.context.build_absolute_uri(self.image.url) if self.image else ""
class ProductType(DjangoObjectType): # type: ignore [misc]
class ProductType(DjangoObjectType):
category = Field(CategoryType, description=_("category"))
images = DjangoFilterConnectionField(ProductImageType, description=_("images"))
feedbacks = DjangoFilterConnectionField(FeedbackType, description=_("feedbacks"))
@ -646,7 +646,7 @@ class ProductType(DjangoObjectType): # type: ignore [misc]
return self.discount_price
class AttributeValueType(DjangoObjectType): # type: ignore [misc]
class AttributeValueType(DjangoObjectType):
value = String(description=_("attribute value"))
class Meta:
@ -657,7 +657,7 @@ class AttributeValueType(DjangoObjectType): # type: ignore [misc]
description = _("attribute value")
class PromoCodeType(DjangoObjectType): # type: ignore [misc]
class PromoCodeType(DjangoObjectType):
discount = Float()
discount_type = String()
@ -679,13 +679,13 @@ class PromoCodeType(DjangoObjectType): # type: ignore [misc]
float(self.discount_percent)
if self.discount_percent
else float(self.discount_amount)
) # type: ignore [arg-type]
)
def resolve_discount_type(self: PromoCode, _info) -> str:
return "percent" if self.discount_percent else "amount"
class PromotionType(DjangoObjectType): # type: ignore [misc]
class PromotionType(DjangoObjectType):
products = DjangoFilterConnectionField(
ProductType, description=_("products on sale")
)
@ -698,7 +698,7 @@ class PromotionType(DjangoObjectType): # type: ignore [misc]
description = _("promotions")
class StockType(DjangoObjectType): # type: ignore [misc]
class StockType(DjangoObjectType):
vendor = Field(VendorType, description=_("vendor"))
product = Field(ProductType, description=_("product"))
@ -710,7 +710,7 @@ class StockType(DjangoObjectType): # type: ignore [misc]
description = _("stocks")
class WishlistType(DjangoObjectType): # type: ignore [misc]
class WishlistType(DjangoObjectType):
products = DjangoFilterConnectionField(
ProductType, description=_("wishlisted products")
)
@ -722,7 +722,7 @@ class WishlistType(DjangoObjectType): # type: ignore [misc]
description = _("wishlists")
class ProductTagType(DjangoObjectType): # type: ignore [misc]
class ProductTagType(DjangoObjectType):
product_set = DjangoFilterConnectionField(
ProductType, description=_("tagged products")
)
@ -735,7 +735,7 @@ class ProductTagType(DjangoObjectType): # type: ignore [misc]
description = _("product tags")
class CategoryTagType(DjangoObjectType): # type: ignore [misc]
class CategoryTagType(DjangoObjectType):
category_set = DjangoFilterConnectionField(
CategoryType, description=_("tagged categories")
)
@ -748,7 +748,7 @@ class CategoryTagType(DjangoObjectType): # type: ignore [misc]
description = _("categories tags")
class ConfigType(ObjectType): # type: ignore [misc]
class ConfigType(ObjectType):
project_name = String(description=_("project name"))
company_name = String(description=_("company name"))
company_address = String(description=_("company address"))
@ -768,7 +768,7 @@ class ConfigType(ObjectType): # type: ignore [misc]
description = _("company configuration")
class LanguageType(ObjectType): # type: ignore [misc]
class LanguageType(ObjectType):
code = String(description=_("language code"))
name = String(description=_("language name"))
flag = String(description=_("language flag, if exists :)"))
@ -777,34 +777,34 @@ class LanguageType(ObjectType): # type: ignore [misc]
description = _("supported languages")
class SearchProductsResultsType(ObjectType): # type: ignore [misc]
class SearchProductsResultsType(ObjectType):
uuid = UUID()
name = String()
slug = String()
image = String()
class SearchCategoriesResultsType(ObjectType): # type: ignore [misc]
class SearchCategoriesResultsType(ObjectType):
uuid = UUID()
name = String()
slug = String()
image = String()
class SearchBrandsResultsType(ObjectType): # type: ignore [misc]
class SearchBrandsResultsType(ObjectType):
uuid = UUID()
name = String()
slug = String()
image = String()
class SearchPostsResultsType(ObjectType): # type: ignore [misc]
class SearchPostsResultsType(ObjectType):
uuid = UUID()
name = String()
slug = String()
class SearchResultsType(ObjectType): # type: ignore [misc]
class SearchResultsType(ObjectType):
products = List(
description=_("products search results"), of_type=SearchProductsResultsType
)
@ -817,6 +817,6 @@ class SearchResultsType(ObjectType): # type: ignore [misc]
posts = List(description=_("posts search results"), of_type=SearchPostsResultsType)
class BulkProductInput(InputObjectType): # type: ignore [misc]
class BulkProductInput(InputObjectType):
uuid = UUID(required=True)
attributes = GenericScalar(required=False)

View file

@ -95,17 +95,17 @@ class Command(BaseCommand):
)
def handle(self, *args: list[Any], **options: dict[str, str | list[str]]) -> None:
langs: list[str] = options.get("target_languages", []) # type: ignore [assignment]
langs: list[str] = options.get("target_languages", [])
if "ALL" in langs:
langs = list(dict(settings.LANGUAGES).keys())
apps_to_scan: set[str] = set(options["target_apps"])
if "ALL" in apps_to_scan:
apps_to_scan = set(TRANSLATABLE_APPS)
root_path: str = options.get("root_path") or "/app/" # type: ignore [assignment]
root_path: str = options.get("root_path") or "/app/"
configs = list(apps.get_app_configs())
# noinspection PyTypeChecker
configs.append(RootDirectory()) # type: ignore [arg-type]
configs.append(RootDirectory())
errors = 0

View file

@ -30,7 +30,7 @@ def placeholderize(text: str) -> tuple[str, list[str]]:
"""
placeholders: list[str] = []
def _repl(match: re.Match) -> str: # type: ignore [type-arg]
def _repl(match: re.Match) -> str:
idx = len(placeholders)
placeholders.append(match.group(0))
return f"__PH_{idx}__"
@ -107,9 +107,9 @@ class Command(BaseCommand):
)
def handle(self, *args: list[Any], **options: dict[Any, Any]) -> None:
target_langs: list[str] = options["target_languages"] # type: ignore [assignment]
target_langs: list[str] = options["target_languages"]
if "ALL" in target_langs:
target_langs = DEEPL_TARGET_LANGUAGES_MAPPING.keys() # type: ignore [assignment]
target_langs = DEEPL_TARGET_LANGUAGES_MAPPING.keys()
target_apps = set(options["target_apps"])
if "ALL" in target_apps:
target_apps = {
@ -125,7 +125,7 @@ class Command(BaseCommand):
try:
import readline
except ImportError:
readline = None # type: ignore [assignment]
readline = None
for target_lang in target_langs:
api_code = DEEPL_TARGET_LANGUAGES_MAPPING.get(target_lang)
@ -176,16 +176,16 @@ class Command(BaseCommand):
if readline:
def hook() -> None:
readline.insert_text(default) # type: ignore [attr-defined] # noqa: B023
readline.redisplay() # type: ignore [attr-defined]
readline.insert_text(default) # noqa: B023
readline.redisplay()
readline.set_pre_input_hook(hook) # type: ignore [attr-defined]
readline.set_pre_input_hook(hook)
prompt = f"Enter translation for '{e.msgid}': "
user_in = input(prompt).strip()
if readline:
readline.set_pre_input_hook(None) # type: ignore [attr-defined]
readline.set_pre_input_hook(None)
if user_in:
e.msgstr = user_in

View file

@ -19,7 +19,7 @@ class Command(BaseCommand):
)
def handle(self, *args: list[Any], **options: dict[Any, Any]) -> None:
size: int = options["size"] # type: ignore [assignment]
size: int = options["size"]
while True:
batch_ids = list(
Product.objects.filter(orderproduct__isnull=True).values_list(

View file

@ -19,7 +19,7 @@ class Command(BaseCommand):
)
def handle(self, *args: list[Any], **options: dict[Any, Any]) -> None:
size: int = options["size"] # type: ignore [assignment]
size: int = options["size"]
while True:
batch_ids = list(
Product.objects.filter(

View file

@ -11,7 +11,7 @@ class Command(BaseCommand):
self.style.SUCCESS("Starting fetching products task in worker container...")
)
update_products_task.delay() # type: ignore [attr-defined]
update_products_task.delay()
self.stdout.write(
self.style.SUCCESS(

View file

@ -14,7 +14,7 @@ class AddressManager(models.Manager):
if not kwargs.get("raw_data"):
raise ValueError("'raw_data' (address string) must be provided.")
params: dict[str, str | int] = { # type: ignore [annotation-unchecked]
params: dict[str, str | int] = {
"format": "json",
"addressdetails": 1,
"q": kwargs.get("raw_data"),

View file

@ -70,8 +70,8 @@ from evibes.utils.misc import create_object
logger = logging.getLogger(__name__)
class AttributeGroup(ExportModelOperationsMixin("attribute_group"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class AttributeGroup(ExportModelOperationsMixin("attribute_group"), NiceModel):
__doc__ = _(
"Represents a group of attributes, which can be hierarchical."
" This class is used to manage and organize attribute groups."
" An attribute group can have a parent group, forming a hierarchical structure."
@ -106,8 +106,8 @@ class AttributeGroup(ExportModelOperationsMixin("attribute_group"), NiceModel):
verbose_name_plural = _("attribute groups")
class Vendor(ExportModelOperationsMixin("vendor"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Vendor(ExportModelOperationsMixin("vendor"), NiceModel):
__doc__ = _(
"Represents a vendor entity capable of storing information about external vendors and their interaction requirements."
" The Vendor class is used to define and manage information related to an external vendor."
" It stores the vendor's name, authentication details required for communication,"
@ -164,7 +164,7 @@ class Vendor(ExportModelOperationsMixin("vendor"), NiceModel): # type: ignore [
def __str__(self) -> str:
return self.name
def save( # type: ignore [override]
def save(
self,
*,
force_insert: bool = False,
@ -198,8 +198,8 @@ class Vendor(ExportModelOperationsMixin("vendor"), NiceModel): # type: ignore [
]
class ProductTag(ExportModelOperationsMixin("product_tag"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class ProductTag(ExportModelOperationsMixin("product_tag"), NiceModel):
__doc__ = _(
"Represents a product tag used for classifying or identifying products."
" The ProductTag class is designed to uniquely identify and classify products through a combination"
" of an internal tag identifier and a user-friendly display name."
@ -230,8 +230,8 @@ class ProductTag(ExportModelOperationsMixin("product_tag"), NiceModel): # type:
verbose_name_plural = _("product tags")
class CategoryTag(ExportModelOperationsMixin("category_tag"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class CategoryTag(ExportModelOperationsMixin("category_tag"), NiceModel):
__doc__ = _(
"Represents a category tag used for products."
" This class models a category tag that can be used to associate and classify products."
" It includes attributes for an internal tag identifier and a user-friendly display name."
@ -261,8 +261,8 @@ class CategoryTag(ExportModelOperationsMixin("category_tag"), NiceModel): # typ
verbose_name_plural = _("category tags")
class Category(ExportModelOperationsMixin("category"), NiceModel, MPTTModel): # type: ignore [misc, django-manager-missing]
__doc__ = _( # type: ignore
class Category(ExportModelOperationsMixin("category"), NiceModel, MPTTModel):
__doc__ = _(
"Represents a category entity to organize and group related items in a hierarchical structure."
" Categories may have hierarchical relationships with other categories, supporting parent-child relationships."
" The class includes fields for metadata and visual representation,"
@ -437,7 +437,7 @@ class Category(ExportModelOperationsMixin("category"), NiceModel, MPTTModel): #
):
bucket["possible_values"].append(value)
return list(by_attr.values()) # type: ignore [arg-type]
return list(by_attr.values())
@cached_property
def image_url(self) -> str:
@ -452,8 +452,8 @@ class Category(ExportModelOperationsMixin("category"), NiceModel, MPTTModel): #
ordering = ["tree_id", "lft"]
class Brand(ExportModelOperationsMixin("brand"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Brand(ExportModelOperationsMixin("brand"), NiceModel):
__doc__ = _(
"Represents a Brand object in the system. "
"This class handles information and attributes related to a brand, including its name, logos, "
"description, associated categories, a unique slug, and priority order. "
@ -522,8 +522,8 @@ class Brand(ExportModelOperationsMixin("brand"), NiceModel): # type: ignore [mi
verbose_name_plural = _("brands")
class Stock(ExportModelOperationsMixin("stock"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Stock(ExportModelOperationsMixin("stock"), NiceModel):
__doc__ = _(
"Represents the stock of a product managed in the system."
" This class provides details about the relationship between vendors, products, and their stock information, "
"as well as inventory-related properties like price, purchase price, quantity, SKU, and digital assets."
@ -588,8 +588,8 @@ class Stock(ExportModelOperationsMixin("stock"), NiceModel): # type: ignore [mi
verbose_name_plural = _("stock entries")
class Product(ExportModelOperationsMixin("product"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Product(ExportModelOperationsMixin("product"), NiceModel):
__doc__ = _(
"Represents a product with attributes such as category, brand, tags, digital status, name, description, part number, and slug."
" Provides related utility properties to retrieve ratings, feedback counts, price, quantity, and total orders."
" Designed for use in a system that handles e-commerce or inventory management."
@ -695,7 +695,7 @@ class Product(ExportModelOperationsMixin("product"), NiceModel): # type: ignore
@cached_property
def discount_price(self) -> float | None:
return self.promos.first().discount_percent if self.promos.exists() else None # type: ignore [union-attr]
return self.promos.first().discount_percent if self.promos.exists() else None
@property
def rating(self) -> float:
@ -736,8 +736,8 @@ class Product(ExportModelOperationsMixin("product"), NiceModel): # type: ignore
self.__dict__["personal_orders_only"] = value
class Attribute(ExportModelOperationsMixin("attribute"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Attribute(ExportModelOperationsMixin("attribute"), NiceModel):
__doc__ = _(
"Represents an attribute in the system."
" This class is used to define and manage attributes,"
" which are customizable pieces of data that can be associated with other entities."
@ -795,8 +795,8 @@ class Attribute(ExportModelOperationsMixin("attribute"), NiceModel): # type: ig
verbose_name_plural = _("attributes")
class AttributeValue(ExportModelOperationsMixin("attribute_value"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class AttributeValue(ExportModelOperationsMixin("attribute_value"), NiceModel):
__doc__ = _(
"Represents a specific value for an attribute that is linked to a product. "
"It links the 'attribute' to a unique 'value', allowing "
"better organization and dynamic representation of product characteristics."
@ -833,8 +833,8 @@ class AttributeValue(ExportModelOperationsMixin("attribute_value"), NiceModel):
verbose_name_plural = _("attribute values")
class ProductImage(ExportModelOperationsMixin("product_image"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class ProductImage(ExportModelOperationsMixin("product_image"), NiceModel):
__doc__ = _(
"Represents a product image associated with a product in the system. "
"This class is designed to manage images for products, including functionality "
"for uploading image files, associating them with specific products, and "
@ -886,8 +886,8 @@ class ProductImage(ExportModelOperationsMixin("product_image"), NiceModel): # t
verbose_name_plural = _("product images")
class Promotion(ExportModelOperationsMixin("promotion"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Promotion(ExportModelOperationsMixin("promotion"), NiceModel):
__doc__ = _(
"Represents a promotional campaign for products with a discount. "
"This class is used to define and manage promotional campaigns that offer a "
"percentage-based discount for products. The class includes attributes for "
@ -932,8 +932,8 @@ class Promotion(ExportModelOperationsMixin("promotion"), NiceModel): # type: ig
return str(self.id)
class Wishlist(ExportModelOperationsMixin("wishlist"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Wishlist(ExportModelOperationsMixin("wishlist"), NiceModel):
__doc__ = _(
"Represents a user's wishlist for storing and managing desired products. "
"The class provides functionality to manage a collection of products, "
"supporting operations such as adding and removing products, "
@ -1003,8 +1003,8 @@ class Wishlist(ExportModelOperationsMixin("wishlist"), NiceModel): # type: igno
return self
class Documentary(ExportModelOperationsMixin("attribute_group"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Documentary(ExportModelOperationsMixin("attribute_group"), NiceModel):
__doc__ = _(
"Represents a documentary record tied to a product. "
"This class is used to store information about documentaries related to specific "
"products, including file uploads and their metadata. It contains methods and "
@ -1034,8 +1034,8 @@ class Documentary(ExportModelOperationsMixin("attribute_group"), NiceModel): #
return self.document.name.split(".")[-1] or _("unresolved")
class Address(ExportModelOperationsMixin("address"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Address(ExportModelOperationsMixin("address"), NiceModel):
__doc__ = _(
"Represents an address entity that includes location details and associations with a user. "
"Provides functionality for geographic and address data storage, as well "
"as integration with geocoding services. "
@ -1099,8 +1099,8 @@ class Address(ExportModelOperationsMixin("address"), NiceModel): # type: ignore
return f"{base} for {self.user.email}" if self.user else base
class PromoCode(ExportModelOperationsMixin("promocode"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class PromoCode(ExportModelOperationsMixin("promocode"), NiceModel):
__doc__ = _(
"Represents a promotional code that can be used for discounts, managing its validity, "
"type of discount, and application. "
"The PromoCode class stores details about a promotional code, including its unique "
@ -1211,13 +1211,13 @@ class PromoCode(ExportModelOperationsMixin("promocode"), NiceModel): # type: ig
if self.discount_type == "percent":
promo_amount -= round(
promo_amount * (float(self.discount_percent) / 100), 2
) # type: ignore [arg-type]
)
order.attributes.update(
{"promocode_uuid": str(self.uuid), "final_price": promo_amount}
)
order.save()
elif self.discount_type == "amount":
promo_amount -= round(float(self.discount_amount), 2) # type: ignore [arg-type]
promo_amount -= round(float(self.discount_amount), 2)
order.attributes.update(
{"promocode_uuid": str(self.uuid), "final_price": promo_amount}
)
@ -1230,8 +1230,8 @@ class PromoCode(ExportModelOperationsMixin("promocode"), NiceModel): # type: ig
return promo_amount
class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Order(ExportModelOperationsMixin("order"), NiceModel):
__doc__ = _(
"Represents an order placed by a user."
" This class models an order within the application,"
" including its various attributes such as billing and shipping information,"
@ -1341,7 +1341,7 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
(
self.user.attributes.get("is_business", False)
and self.user.attributes.get("business_identificator")
) # type: ignore [union-attr]
)
if self.user
else False
)
@ -1410,7 +1410,7 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
if promotions.exists():
buy_price -= round(
product.price * (promotions.first().discount_percent / 100), 2
) # type: ignore [union-attr]
)
order_product, is_created = OrderProduct.objects.get_or_create(
product=product,
@ -1800,8 +1800,8 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
return None
class Feedback(ExportModelOperationsMixin("feedback"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class Feedback(ExportModelOperationsMixin("feedback"), NiceModel):
__doc__ = _(
"Manages user feedback for products. "
"This class is designed to capture and store user feedback for specific products "
"that they have purchased. It contains attributes to store user comments, "
@ -1849,8 +1849,8 @@ class Feedback(ExportModelOperationsMixin("feedback"), NiceModel): # type: igno
verbose_name_plural = _("feedbacks")
class OrderProduct(ExportModelOperationsMixin("order_product"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class OrderProduct(ExportModelOperationsMixin("order_product"), NiceModel):
__doc__ = _(
"Represents products associated with orders and their attributes. "
"The OrderProduct model maintains information about a product that is part of an order, "
"including details such as purchase price, quantity, product attributes, and status. It "
@ -1969,12 +1969,12 @@ class OrderProduct(ExportModelOperationsMixin("order_product"), NiceModel): # t
@property
def total_price(self: Self) -> float:
return round(float(self.buy_price) * self.quantity, 2) # type: ignore [arg-type]
return round(float(self.buy_price) * self.quantity, 2)
@property
def download_url(self: Self) -> str:
if self.product and self.product.stocks:
if self.product.is_digital and self.product.stocks.first().digital_asset: # type: ignore [union-attr]
if self.product.is_digital and self.product.stocks.first().digital_asset:
if hasattr(self, "download"):
return self.download.url
else:
@ -2010,7 +2010,7 @@ class OrderProduct(ExportModelOperationsMixin("order_product"), NiceModel): # t
class CustomerRelationshipManagementProvider(
ExportModelOperationsMixin("crm_provider"), NiceModel
): # type: ignore [misc]
):
name = CharField(max_length=128, unique=True, verbose_name=_("name"))
integration_url = URLField(
blank=True, null=True, help_text=_("URL of the integration")
@ -2053,7 +2053,7 @@ class CustomerRelationshipManagementProvider(
verbose_name_plural = _("CRMs")
class OrderCrmLink(ExportModelOperationsMixin("order_crm_link"), NiceModel): # type: ignore
class OrderCrmLink(ExportModelOperationsMixin("order_crm_link"), NiceModel):
order = ForeignKey(to=Order, on_delete=PROTECT, related_name="crm_links")
crm = ForeignKey(
to=CustomerRelationshipManagementProvider,
@ -2070,8 +2070,8 @@ class OrderCrmLink(ExportModelOperationsMixin("order_crm_link"), NiceModel): #
verbose_name_plural = _("orders CRM links")
class DigitalAssetDownload(ExportModelOperationsMixin("attribute_group"), NiceModel): # type: ignore [misc]
__doc__ = _( # type: ignore
class DigitalAssetDownload(ExportModelOperationsMixin("attribute_group"), NiceModel):
__doc__ = _(
"Represents the downloading functionality for digital assets associated with orders. "
"The DigitalAssetDownload class provides the ability to manage and access "
"downloads related to order products. It maintains information about the "

View file

@ -50,7 +50,7 @@ class AttributeGroupDetailSerializer(ModelSerializer):
class CategoryDetailListSerializer(ListSerializer):
def to_representation(self, data): # type: ignore[override]
def to_representation(self, data):
items = list(data)
with suppress(Exception):
Category.bulk_prefetch_filterable_attributes(items)
@ -92,7 +92,7 @@ class CategoryDetailSerializer(ModelSerializer):
CategorySimpleSerializer(children, many=True, context=self.context).data
if obj.children.exists()
else []
) # type: ignore [return-value]
)
class BrandDetailSerializer(ModelSerializer):

View file

@ -25,9 +25,9 @@ from engine.core.models import (
from engine.core.serializers.utility import AddressSerializer
class AttributeGroupSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
parent = PrimaryKeyRelatedField(read_only=True) # type: ignore [assignment, var-annotated]
children = PrimaryKeyRelatedField(many=True, read_only=True) # type: ignore [assignment, var-annotated]
class AttributeGroupSimpleSerializer(ModelSerializer):
parent = PrimaryKeyRelatedField(read_only=True)
children = PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = AttributeGroup
@ -39,7 +39,7 @@ class AttributeGroupSimpleSerializer(ModelSerializer): # type: ignore [type-arg
]
class CategorySimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class CategorySimpleSerializer(ModelSerializer):
children = SerializerMethodField()
class Meta:
@ -63,10 +63,10 @@ class CategorySimpleSerializer(ModelSerializer): # type: ignore [type-arg]
CategorySimpleSerializer(children, many=True, context=self.context).data
if obj.children.exists()
else []
) # type: ignore [return-value]
)
class BrandSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class BrandSimpleSerializer(ModelSerializer):
class Meta:
model = Brand
fields = [
@ -77,7 +77,7 @@ class BrandSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class ProductTagSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class ProductTagSimpleSerializer(ModelSerializer):
class Meta:
model = ProductTag
fields = [
@ -87,8 +87,8 @@ class ProductTagSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class ProductImageSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
product: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True) # type: ignore [type-arg]
class ProductImageSimpleSerializer(ModelSerializer):
product: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
class Meta:
model = ProductImage
@ -101,7 +101,7 @@ class ProductImageSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class AttributeSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class AttributeSimpleSerializer(ModelSerializer):
group = AttributeGroupSimpleSerializer(read_only=True)
class Meta:
@ -114,9 +114,9 @@ class AttributeSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class AttributeValueSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class AttributeValueSimpleSerializer(ModelSerializer):
attribute = AttributeSimpleSerializer(read_only=True)
product: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True) # type: ignore [type-arg]
product: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
class Meta:
model = AttributeValue
@ -128,7 +128,7 @@ class AttributeValueSimpleSerializer(ModelSerializer): # type: ignore [type-arg
]
class ProductSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class ProductSimpleSerializer(ModelSerializer):
brand = BrandSimpleSerializer(read_only=True)
category = CategorySimpleSerializer(read_only=True)
tags = ProductTagSimpleSerializer(many=True, read_only=True)
@ -185,7 +185,7 @@ class ProductSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
return obj.discount_price
class VendorSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class VendorSimpleSerializer(ModelSerializer):
class Meta:
model = Vendor
fields = [
@ -194,7 +194,7 @@ class VendorSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class StockSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class StockSimpleSerializer(ModelSerializer):
vendor = VendorSimpleSerializer(read_only=True)
product = ProductSimpleSerializer(read_only=True)
@ -211,7 +211,7 @@ class StockSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class PromoCodeSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class PromoCodeSimpleSerializer(ModelSerializer):
class Meta:
model = PromoCode
fields = [
@ -220,7 +220,7 @@ class PromoCodeSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class PromotionSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class PromotionSimpleSerializer(ModelSerializer):
products = ProductSimpleSerializer(many=True, read_only=True)
class Meta:
@ -233,8 +233,8 @@ class PromotionSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class WishlistSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
user: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True) # type: ignore [type-arg]
class WishlistSimpleSerializer(ModelSerializer):
user: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
products = ProductSimpleSerializer(many=True, read_only=True)
class Meta:
@ -246,8 +246,8 @@ class WishlistSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class FeedbackSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
order_product: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True) # type: ignore [type-arg]
class FeedbackSimpleSerializer(ModelSerializer):
order_product: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
class Meta:
model = Feedback
@ -258,7 +258,7 @@ class FeedbackSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class OrderProductSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
class OrderProductSimpleSerializer(ModelSerializer):
product = ProductSimpleSerializer(read_only=True)
class Meta:
@ -272,8 +272,8 @@ class OrderProductSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
]
class OrderSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
user: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True) # type: ignore [type-arg]
class OrderSimpleSerializer(ModelSerializer):
user: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
promo_code = PromoCodeSimpleSerializer(read_only=True)
order_products = OrderProductSimpleSerializer(many=True, read_only=True)
billing_address = AddressSerializer(read_only=True, required=False)

View file

@ -18,19 +18,19 @@ from rest_framework.serializers import ListSerializer, ModelSerializer, Serializ
from engine.core.models import Address
class AddressAutocompleteInputSerializer(Serializer): # type: ignore [type-arg]
class AddressAutocompleteInputSerializer(Serializer):
q = CharField(required=True)
limit = IntegerField(required=False, min_value=1, max_value=10, default=5)
class AddressSuggestionSerializer(Serializer): # type: ignore [type-arg]
class AddressSuggestionSerializer(Serializer):
display_name = CharField()
lat = FloatField()
lon = FloatField()
address = DictField(child=CharField())
class AddressSerializer(ModelSerializer): # type: ignore [type-arg]
class AddressSerializer(ModelSerializer):
latitude = FloatField(source="location.y", read_only=True)
longitude = FloatField(source="location.x", read_only=True)
@ -59,7 +59,7 @@ class AddressSerializer(ModelSerializer): # type: ignore [type-arg]
]
class AddressCreateSerializer(ModelSerializer): # type: ignore [type-arg]
class AddressCreateSerializer(ModelSerializer):
raw_data = CharField(
write_only=True,
max_length=512,
@ -76,10 +76,10 @@ class AddressCreateSerializer(ModelSerializer): # type: ignore [type-arg]
user = None
if self.context["request"].user.is_authenticated:
user = self.context["request"].user
return Address.objects.create(raw_data=raw, user=user, **validated_data) # type: ignore [no-untyped-call]
return Address.objects.create(raw_data=raw, user=user, **validated_data)
class DoFeedbackSerializer(Serializer): # type: ignore [type-arg]
class DoFeedbackSerializer(Serializer):
comment = CharField(required=True)
rating = IntegerField(min_value=1, max_value=10, default=10)
action = CharField(default="add")
@ -94,13 +94,13 @@ class DoFeedbackSerializer(Serializer): # type: ignore [type-arg]
return data
class CacheOperatorSerializer(Serializer): # type: ignore [type-arg]
class CacheOperatorSerializer(Serializer):
key = CharField(required=True)
data = JSONField(required=False) # type: ignore [assignment]
data = JSONField(required=False)
timeout = IntegerField(required=False)
class ContactUsSerializer(Serializer): # type: ignore [type-arg]
class ContactUsSerializer(Serializer):
email = CharField(required=True)
name = CharField(required=True)
subject = CharField(required=True)
@ -108,13 +108,13 @@ class ContactUsSerializer(Serializer): # type: ignore [type-arg]
message = CharField(required=True)
class LanguageSerializer(Serializer): # type: ignore [type-arg]
class LanguageSerializer(Serializer):
code = CharField(required=True)
name = CharField(required=True)
flag = CharField()
class RecursiveField(Field): # type: ignore [type-arg]
class RecursiveField(Field):
def to_representation(self, value: Any) -> Any:
parent = self.parent
if isinstance(parent, ListSerializer):
@ -127,45 +127,45 @@ class RecursiveField(Field): # type: ignore [type-arg]
return data
class AddOrderProductSerializer(Serializer): # type: ignore [type-arg]
class AddOrderProductSerializer(Serializer):
product_uuid = CharField(required=True)
attributes = ListField(required=False, child=DictField(), default=list)
class BulkAddOrderProductsSerializer(Serializer): # type: ignore [type-arg]
class BulkAddOrderProductsSerializer(Serializer):
products = ListField(child=AddOrderProductSerializer(), required=True)
class RemoveOrderProductSerializer(Serializer): # type: ignore [type-arg]
class RemoveOrderProductSerializer(Serializer):
product_uuid = CharField(required=True)
attributes = JSONField(required=False, default=dict)
class BulkRemoveOrderProductsSerializer(Serializer): # type: ignore [type-arg]
class BulkRemoveOrderProductsSerializer(Serializer):
products = ListField(child=RemoveOrderProductSerializer(), required=True)
class AddWishlistProductSerializer(Serializer): # type: ignore [type-arg]
class AddWishlistProductSerializer(Serializer):
product_uuid = CharField(required=True)
class RemoveWishlistProductSerializer(Serializer): # type: ignore [type-arg]
class RemoveWishlistProductSerializer(Serializer):
product_uuid = CharField(required=True)
class BulkAddWishlistProductSerializer(Serializer): # type: ignore [type-arg]
class BulkAddWishlistProductSerializer(Serializer):
product_uuids = ListField(
child=CharField(required=True), allow_empty=False, max_length=64
)
class BulkRemoveWishlistProductSerializer(Serializer): # type: ignore [type-arg]
class BulkRemoveWishlistProductSerializer(Serializer):
product_uuids = ListField(
child=CharField(required=True), allow_empty=False, max_length=64
)
class BuyOrderSerializer(Serializer): # type: ignore [type-arg]
class BuyOrderSerializer(Serializer):
force_balance = BooleanField(required=False, default=False)
force_payment = BooleanField(required=False, default=False)
promocode_uuid = CharField(required=False)
@ -174,7 +174,7 @@ class BuyOrderSerializer(Serializer): # type: ignore [type-arg]
chosen_products = AddOrderProductSerializer(many=True, required=False)
class BuyUnregisteredOrderSerializer(Serializer): # type: ignore [type-arg]
class BuyUnregisteredOrderSerializer(Serializer):
products = AddOrderProductSerializer(many=True, required=True)
promocode_uuid = UUIDField(required=False)
customer_name = CharField(required=True)
@ -185,7 +185,7 @@ class BuyUnregisteredOrderSerializer(Serializer): # type: ignore [type-arg]
payment_method = CharField(required=True)
class BuyAsBusinessOrderSerializer(Serializer): # type: ignore [type-arg]
class BuyAsBusinessOrderSerializer(Serializer):
products = AddOrderProductSerializer(many=True, required=True)
business_identificator = CharField(required=True)
promocode_uuid = UUIDField(required=False)

View file

@ -156,8 +156,8 @@ def process_order_changes(instance: Order, created: bool, **kwargs: dict[Any, An
)
order_product.order.user.payments_balance.amount -= (
order_product.buy_price
) # type: ignore [union-attr, operator]
order_product.order.user.payments_balance.save() # type: ignore [union-attr]
)
order_product.order.user.payments_balance.save()
order_product.save()
continue
@ -169,7 +169,7 @@ def process_order_changes(instance: Order, created: bool, **kwargs: dict[Any, An
price=order_product.buy_price
)
.first()
.vendor.name.lower() # type: ignore [union-attr, attr-defined, misc]
.vendor.name.lower()
)
vendor = create_object(
@ -177,7 +177,7 @@ def process_order_changes(instance: Order, created: bool, **kwargs: dict[Any, An
f"{vendor_name.title()}Vendor",
)
vendor.buy_order_product(order_product) # type: ignore [attr-defined]
vendor.buy_order_product(order_product)
except Exception as e:
order_product.add_error(

View file

@ -12,7 +12,7 @@ class SitemapLanguageMixin:
return getattr(req, "LANGUAGE_CODE", settings.LANGUAGE_CODE)
class StaticPagesSitemap(SitemapLanguageMixin, Sitemap): # type: ignore [type-arg]
class StaticPagesSitemap(SitemapLanguageMixin, Sitemap):
protocol = "https"
changefreq = "monthly"
priority = 0.8
@ -58,7 +58,7 @@ class StaticPagesSitemap(SitemapLanguageMixin, Sitemap): # type: ignore [type-a
return obj.get("lastmod")
class ProductSitemap(SitemapLanguageMixin, Sitemap): # type: ignore [type-arg]
class ProductSitemap(SitemapLanguageMixin, Sitemap):
protocol = "https"
changefreq = "daily"
priority = 0.9
@ -84,7 +84,7 @@ class ProductSitemap(SitemapLanguageMixin, Sitemap): # type: ignore [type-arg]
return f"/{self._lang()}/product/{obj.slug if obj.slug else '404-non-existent-product'}"
class CategorySitemap(SitemapLanguageMixin, Sitemap): # type: ignore [type-arg]
class CategorySitemap(SitemapLanguageMixin, Sitemap):
protocol = "https"
changefreq = "weekly"
priority = 0.7
@ -109,7 +109,7 @@ class CategorySitemap(SitemapLanguageMixin, Sitemap): # type: ignore [type-arg]
return f"/{self._lang()}/catalog/{obj.slug if obj.slug else '404-non-existent-category'}"
class BrandSitemap(SitemapLanguageMixin, Sitemap): # type: ignore [type-arg]
class BrandSitemap(SitemapLanguageMixin, Sitemap):
protocol = "https"
changefreq = "weekly"
priority = 0.6

View file

@ -8,7 +8,7 @@ register = template.Library()
def _to_float(val: object) -> float:
conv: float = 0.0
with suppress(Exception):
return float(val) # type: ignore [arg-type]
return float(val)
return conv

View file

@ -66,15 +66,15 @@ def get_random_code() -> str:
return get_random_string(20)
def get_product_uuid_as_path(instance, filename: str = "") -> str: # type: ignore [no-untyped-def]
def get_product_uuid_as_path(instance, filename: str = "") -> str:
return "products" + "/" + str(instance.product.uuid) + "/" + filename
def get_vendor_name_as_path(instance, filename: str = "") -> str: # type: ignore [no-untyped-def]
def get_vendor_name_as_path(instance, filename: str = "") -> str:
return "vendors_responses/" + str(instance.name) + "/" + filename
def get_brand_name_as_path(instance, filename: str = "") -> str: # type: ignore [no-untyped-def]
def get_brand_name_as_path(instance, filename: str = "") -> str:
return "brands/" + str(instance.name) + "/" + filename
@ -150,7 +150,7 @@ def get_project_parameters() -> Any:
return parameters
def resolve_translations_for_elasticsearch(instance, field_name: str) -> None: # type: ignore [no-untyped-def]
def resolve_translations_for_elasticsearch(instance, field_name: str) -> None:
"""
Resolves translations for a given field in an Elasticsearch-compatible
format. It checks if the localized version of the field contains data,
@ -211,7 +211,7 @@ def is_status_code_success(status_code: int) -> bool:
def get_dynamic_email_connection() -> EmailBackend:
return mail.get_connection( # type: ignore [no-any-return]
return mail.get_connection(
host=config.EMAIL_HOST,
port=config.EMAIL_PORT,
username=config.EMAIL_HOST_USER,

View file

@ -43,14 +43,14 @@ def web_cache(
request: Request | Context, key: str, data: dict[str, Any], timeout: int
) -> dict[str, Any]:
if not data and not timeout:
return {"data": get_cached_value(request.user, key)} # type: ignore [assignment, arg-type]
return {"data": get_cached_value(request.user, key)}
if (data and not timeout) or (timeout and not data):
raise BadRequest(_("both data and timeout are required"))
if not 0 < int(timeout) < 216000:
raise BadRequest(
_("invalid timeout value, it must be between 0 and 216000 seconds")
)
return {"data": set_cached_value(request.user, key, data, timeout)} # type: ignore [assignment, arg-type]
return {"data": set_cached_value(request.user, key, data, timeout)}
def set_default_cache() -> None:

View file

@ -160,7 +160,7 @@ def get_top_returned_products(
p = product_by_id[pid]
img = ""
with suppress(Exception):
img = p.images.first().image_url if p.images.exists() else "" # type: ignore [union-attr]
img = p.images.first().image_url if p.images.exists() else ""
result.append(
{
"name": p.name,

View file

@ -121,7 +121,7 @@ def send_order_finished_email(order_pk: str) -> tuple[bool, str]:
"order_products": ops,
"project_name": settings.PROJECT_NAME,
"contact_email": config.EMAIL_FROM,
"total_price": round(sum(0.0 or op.buy_price for op in ops), 2), # type: ignore [misc]
"total_price": round(sum(0.0 or op.buy_price for op in ops), 2),
"display_system_attributes": order.user.has_perm("core.view_order"),
"today": datetime.today(),
},

View file

@ -16,7 +16,7 @@ def get_vendors_integrations(name: str | None = None) -> list[AbstractVendor]:
for vendor in vendors:
try:
module_name, class_name = vendor.integration_path.rsplit(".", 1) # type: ignore [union-attr]
module_name, class_name = vendor.integration_path.rsplit(".", 1)
vendors_integrations.append(create_object(module_name, class_name))
except Exception as e:
logger.warning(

View file

@ -11,11 +11,11 @@ def validate_category_image_dimensions(
if image:
try:
width, height = get_image_dimensions(image.file) # type: ignore [arg-type]
width, height = get_image_dimensions(image.file)
except (FileNotFoundError, OSError, ValueError):
return
if int(width) > max_width or int(height) > max_height: # type: ignore [arg-type]
if int(width) > max_width or int(height) > max_height:
raise ValidationError(
_(
f"image dimensions should not exceed w{max_width} x h{max_height} pixels"

View file

@ -343,7 +343,7 @@ class AbstractVendor:
f"No rate found for {currency} in {rates} with probider {provider}..."
)
return float(round(price / rate, 2)) if rate else float(round(price, 2)) # type: ignore [arg-type, operator]
return float(round(price / rate, 2)) if rate else float(round(price, 2))
@staticmethod
def round_price_marketologically(price: float) -> float:
@ -536,7 +536,7 @@ class AbstractVendor:
Attribute.objects.filter(name=key, group=attr_group)
.order_by("uuid")
.first()
) # type: ignore [assignment]
)
fields_to_update: list[str] = []
if not attribute.is_active:
attribute.is_active = True

View file

@ -104,7 +104,7 @@ def sitemap_index(request, *args, **kwargs):
# noinspection PyTypeChecker
sitemap_index.__doc__ = _( # type: ignore [assignment]
sitemap_index.__doc__ = _(
"Handles the request for the sitemap index and returns an XML response. "
"It ensures the response includes the appropriate content type header for XML."
)
@ -119,7 +119,7 @@ def sitemap_detail(request, *args, **kwargs):
# noinspection PyTypeChecker
sitemap_detail.__doc__ = _( # type: ignore [assignment]
sitemap_detail.__doc__ = _(
"Handles the detailed view response for a sitemap. "
"This function processes the request, fetches the appropriate "
"sitemap detail response, and sets the Content-Type header for XML."
@ -157,7 +157,7 @@ class CustomRedocView(SpectacularRedocView):
class SupportedLanguagesView(APIView):
__doc__ = _(
"Returns a list of supported languages and their corresponding information."
) # type: ignore [assignment]
)
serializer_class = LanguageSerializer
permission_classes = [
@ -189,7 +189,7 @@ class SupportedLanguagesView(APIView):
@extend_schema_view(**PARAMETERS_SCHEMA)
class WebsiteParametersView(APIView):
__doc__ = _("Returns the parameters of the website as a JSON object.") # type: ignore [assignment]
__doc__ = _("Returns the parameters of the website as a JSON object.")
serializer_class = None
permission_classes = [
@ -212,7 +212,7 @@ class WebsiteParametersView(APIView):
class CacheOperatorView(APIView):
__doc__ = _(
"Handles cache operations such as reading and setting cache data with a specified key and timeout."
) # type: ignore [assignment]
)
serializer_class = CacheOperatorSerializer
permission_classes = [
@ -229,9 +229,9 @@ class CacheOperatorView(APIView):
return Response(
data=web_cache(
request,
request.data.get("key"), # type: ignore [arg-type]
request.data.get("key"),
request.data.get("data", {}),
request.data.get("timeout"), # type: ignore [arg-type]
request.data.get("timeout"),
),
status=status.HTTP_200_OK,
)
@ -239,7 +239,7 @@ class CacheOperatorView(APIView):
@extend_schema_view(**CONTACT_US_SCHEMA)
class ContactUsView(APIView):
__doc__ = _("Handles `contact us` form submissions.") # type: ignore [assignment]
__doc__ = _("Handles `contact us` form submissions.")
serializer_class = ContactUsSerializer
renderer_classes = [
@ -253,7 +253,7 @@ class ContactUsView(APIView):
def post(self, request: Request, *args, **kwargs) -> Response:
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
contact_us_email.delay(serializer.validated_data) # type: ignore [attr-defined]
contact_us_email.delay(serializer.validated_data)
return Response(data=serializer.data, status=status.HTTP_200_OK)
@ -262,7 +262,7 @@ class ContactUsView(APIView):
class RequestCursedURLView(APIView):
__doc__ = _(
"Handles requests for processing and validating URLs from incoming POST requests."
) # type: ignore [assignment]
)
permission_classes = [
AllowAny,
@ -304,7 +304,7 @@ class RequestCursedURLView(APIView):
@extend_schema_view(**SEARCH_SCHEMA)
class GlobalSearchView(APIView):
__doc__ = _("Handles global search queries.") # type: ignore [assignment]
__doc__ = _("Handles global search queries.")
renderer_classes = [
CamelCaseJSONRenderer,
@ -327,7 +327,7 @@ class GlobalSearchView(APIView):
@extend_schema_view(**BUY_AS_BUSINESS_SCHEMA)
class BuyAsBusinessView(APIView):
__doc__ = _("Handles the logic of buying as a business without registration.") # type: ignore [assignment]
__doc__ = _("Handles the logic of buying as a business without registration.")
# noinspection PyUnusedLocal
@method_decorator(
@ -374,7 +374,7 @@ class BuyAsBusinessView(APIView):
@extend_schema_view(**DOWNLOAD_DIGITAL_ASSET_SCHEMA)
class DownloadDigitalAssetView(APIView):
__doc__ = _( # type: ignore [assignment]
__doc__ = _(
"Handles the downloading of a digital asset associated with an order.\n"
"This function attempts to serve the digital asset file located in the "
"storage directory of the project. If the file is not found, an HTTP 404 "
@ -409,7 +409,7 @@ class DownloadDigitalAssetView(APIView):
if not order_product.download.order_product.product:
raise BadRequest(_("the order product does not have a product"))
file_path = order_product.download.order_product.product.stocks.first().digital_asset.path # type: ignore [union-attr]
file_path = order_product.download.order_product.product.stocks.first().digital_asset.path
content_type, encoding = mimetypes.guess_type(file_path)
if not content_type:
@ -453,7 +453,7 @@ def favicon_view(request: HttpRequest, *args, **kwargs) -> HttpResponse | FileRe
# noinspection PyTypeChecker
favicon_view.__doc__ = _( # type: ignore [assignment]
favicon_view.__doc__ = _(
"Handles requests for the favicon of a website.\n"
"This function attempts to serve the favicon file located in the static directory of the project. "
"If the favicon file is not found, an HTTP 404 error is raised to indicate the resource is unavailable."
@ -465,7 +465,7 @@ def index(request: HttpRequest, *args, **kwargs) -> HttpResponse | HttpResponseR
# noinspection PyTypeChecker
index.__doc__ = _( # type: ignore [assignment]
index.__doc__ = _(
"Redirects the request to the admin index page. "
"The function handles incoming HTTP requests and redirects them to the Django "
"admin interface index page. It uses Django's `redirect` function for handling "
@ -478,9 +478,7 @@ def version(request: HttpRequest, *args, **kwargs) -> HttpResponse:
# noinspection PyTypeChecker
version.__doc__ = _( # type: ignore [assignment]
"Returns current version of the eVibes. "
)
version.__doc__ = _("Returns current version of the eVibes. ")
def dashboard_callback(request: HttpRequest, context: Context) -> Context:
@ -631,7 +629,7 @@ def dashboard_callback(request: HttpRequest, context: Context) -> Context:
with suppress(Exception):
quick_links_section = settings.UNFOLD.get("SIDEBAR", {}).get("navigation", [])[
1
] # type: ignore[assignment]
]
for item in quick_links_section.get("items", []):
title = item.get("title")
link = item.get("link")
@ -661,7 +659,7 @@ def dashboard_callback(request: HttpRequest, context: Context) -> Context:
if product:
img = (
product.images.first().image_url if product.images.exists() else ""
) # type: ignore [union-attr]
)
most_wished = {
"name": product.name,
"image": img,
@ -684,7 +682,7 @@ def dashboard_callback(request: HttpRequest, context: Context) -> Context:
if not pid or pid not in product_by_id:
continue
p = product_by_id[pid]
img = p.images.first().image_url if p.images.exists() else "" # type: ignore [union-attr]
img = p.images.first().image_url if p.images.exists() else ""
most_wished_list.append(
{
"name": p.name,
@ -783,7 +781,7 @@ def dashboard_callback(request: HttpRequest, context: Context) -> Context:
if product:
img = (
product.images.first().image_url if product.images.exists() else ""
) # type: ignore [union-attr]
)
most_popular = {
"name": product.name,
"image": img,
@ -806,7 +804,7 @@ def dashboard_callback(request: HttpRequest, context: Context) -> Context:
if not pid or pid not in product_by_id:
continue
p = product_by_id[pid]
img = p.images.first().image_url if p.images.exists() else "" # type: ignore [union-attr]
img = p.images.first().image_url if p.images.exists() else ""
most_popular_list.append(
{
"name": p.name,
@ -905,6 +903,4 @@ def dashboard_callback(request: HttpRequest, context: Context) -> Context:
return context
dashboard_callback.__doc__ = _( # type: ignore [assignment]
"Returns custom variables for Dashboard. "
)
dashboard_callback.__doc__ = _("Returns custom variables for Dashboard. ")

View file

@ -139,7 +139,7 @@ logger = logging.getLogger(__name__)
class EvibesViewSet(ModelViewSet):
__doc__ = _( # type: ignore
__doc__ = _(
"Defines a viewset for managing Evibes-related operations. "
"The EvibesViewSet class inherits from ModelViewSet and provides functionality "
"for handling actions and operations on Evibes entities. It includes support "
@ -161,7 +161,7 @@ class EvibesViewSet(ModelViewSet):
# noinspection PyTypeChecker
return self.action_serializer_classes.get(
self.action, super().get_serializer_class()
) # type: ignore [arg-type]
)
@extend_schema_view(**ATTRIBUTE_GROUP_SCHEMA)

View file

@ -11,7 +11,7 @@ from django.utils.safestring import SafeString
class JSONTableWidget(forms.Widget):
template_name = "json_table_widget.html"
def format_value(self, value: str | dict[str, Any]) -> str | dict[str, Any]: # type: ignore [override]
def format_value(self, value: str | dict[str, Any]) -> str | dict[str, Any]:
if isinstance(value, dict):
return value
try:
@ -40,8 +40,8 @@ class JSONTableWidget(forms.Widget):
json_data = {}
try:
keys = data.getlist(f"{name}_key") # type: ignore [attr-defined]
values = data.getlist(f"{name}_value") # type: ignore [attr-defined]
keys = data.getlist(f"{name}_key")
values = data.getlist(f"{name}_value")
for key, value in zip(keys, values, strict=True):
if key.strip():
try:

View file

@ -9,7 +9,7 @@ from engine.payments.forms import GatewayForm, TransactionForm
from engine.payments.models import Balance, Gateway, Transaction
class TransactionInline(TabularInline): # type: ignore [type-arg]
class TransactionInline(TabularInline):
model = Transaction
form = TransactionForm
extra = 1
@ -23,7 +23,7 @@ class TransactionInline(TabularInline): # type: ignore [type-arg]
@register(Balance)
class BalanceAdmin(ActivationActionsMixin, ModelAdmin): # type: ignore [misc, type-arg]
class BalanceAdmin(ActivationActionsMixin, ModelAdmin):
inlines = (TransactionInline,)
list_display = ("user", "amount")
search_fields = ("user__email",)
@ -35,7 +35,7 @@ class BalanceAdmin(ActivationActionsMixin, ModelAdmin): # type: ignore [misc, t
@register(Transaction)
class TransactionAdmin(ActivationActionsMixin, ModelAdmin): # type: ignore [misc, type-arg]
class TransactionAdmin(ActivationActionsMixin, ModelAdmin):
list_display = ("balance", "amount", "order", "modified", "created")
search_fields = ("balance__user__email", "currency", "payment_method")
list_filter = ("currency", "payment_method")
@ -44,7 +44,7 @@ class TransactionAdmin(ActivationActionsMixin, ModelAdmin): # type: ignore [mis
@register(Gateway)
class GatewayAdmin(ActivationActionsMixin, ModelAdmin): # type: ignore [misc]
class GatewayAdmin(ActivationActionsMixin, ModelAdmin):
list_display = (
"name",
"can_be_used",
@ -57,8 +57,8 @@ class GatewayAdmin(ActivationActionsMixin, ModelAdmin): # type: ignore [misc]
ordering = ("name",)
form = GatewayForm
def can_be_used(self, obj: Gateway) -> bool: # type: ignore[override]
def can_be_used(self, obj: Gateway) -> bool:
return obj.can_be_used
can_be_used.boolean = True # type: ignore[attr-defined]
can_be_used.short_description = _("can be used") # type: ignore[attr-defined]
can_be_used.boolean = True
can_be_used.short_description = _("can be used")

View file

@ -4,7 +4,7 @@ from engine.core.widgets import JSONTableWidget
from engine.payments.models import Gateway, Transaction
class TransactionForm(forms.ModelForm): # type: ignore [type-arg]
class TransactionForm(forms.ModelForm):
class Meta:
model = Transaction
fields = "__all__"
@ -13,7 +13,7 @@ class TransactionForm(forms.ModelForm): # type: ignore [type-arg]
}
class GatewayForm(forms.ModelForm): # type: ignore [type-arg]
class GatewayForm(forms.ModelForm):
class Meta:
model = Gateway
fields = "__all__"

View file

@ -58,6 +58,6 @@ class GatewayQuerySet(QuerySet):
).order_by("-priority")
class GatewayManager(Manager.from_queryset(GatewayQuerySet)): # type: ignore [misc]
class GatewayManager(Manager.from_queryset(GatewayQuerySet)):
def get_queryset(self) -> QuerySet:
return super().get_queryset().can_be_used()

View file

@ -4,17 +4,17 @@ from rest_framework.serializers import ModelSerializer, Serializer
from engine.payments.models import Transaction
class DepositSerializer(Serializer): # type: ignore [type-arg]
class DepositSerializer(Serializer):
amount = FloatField(required=True)
class TransactionSerializer(ModelSerializer): # type: ignore [type-arg]
class TransactionSerializer(ModelSerializer):
class Meta:
model = Transaction
fields = "__all__"
class TransactionProcessSerializer(ModelSerializer): # type: ignore [type-arg]
class TransactionProcessSerializer(ModelSerializer):
process = JSONField(required=True)
order_hr_id = SerializerMethodField(read_only=True, required=False)
order_uuid = SerializerMethodField(read_only=True, required=False)
@ -31,6 +31,6 @@ class TransactionProcessSerializer(ModelSerializer): # type: ignore [type-arg]
read_only_fields = ("process", "order_hr_id", "order_uuid")
class LimitsSerializer(Serializer): # type: ignore [type-arg]
class LimitsSerializer(Serializer):
min_amount = FloatField(read_only=True)
max_amount = FloatField(read_only=True)

View file

@ -38,7 +38,7 @@ def process_transaction_changes(
<= instance.amount
<= instance.gateway.maximum_transaction_amount
):
gateway.process_transaction(instance) # type: ignore [union-attr]
gateway.process_transaction(instance)
else:
raise BadLimitsError(
_(

View file

@ -24,7 +24,7 @@ logger = logging.getLogger(__name__)
@extend_schema_view(**DEPOSIT_SCHEMA)
class DepositView(APIView):
__doc__ = _( # type: ignore [assignment]
__doc__ = _(
"This class provides an API endpoint to handle deposit transactions.\n"
"It supports the creation of a deposit transaction after validating the "
"provided data. If the user is not authenticated, an appropriate response "
@ -57,7 +57,7 @@ class DepositView(APIView):
@extend_schema(exclude=True)
class CallbackAPIView(APIView):
__doc__ = _( # type: ignore [assignment]
__doc__ = _(
"Handles incoming callback requests to the API.\n"
"This class processes and routes incoming HTTP POST requests to the appropriate "
"pgateway handler based on the provided gateway parameter. It is designed to handle "
@ -92,7 +92,7 @@ class CallbackAPIView(APIView):
@extend_schema_view(**LIMITS_SCHEMA)
class LimitsAPIView(APIView):
__doc__ = _( # type: ignore [assignment]
__doc__ = _(
"This endpoint returns minimal and maximal allowed deposit amounts across available gateways."
)

View file

@ -9,8 +9,8 @@ from engine.payments.serializers import TransactionSerializer
@extend_schema_view(**TRANSACTION_SCHEMA)
class TransactionViewSet(ReadOnlyModelViewSet): # type: ignore
__doc__ = _( # type: ignore [assignment]
class TransactionViewSet(ReadOnlyModelViewSet):
__doc__ = _(
"ViewSet for handling read-only operations on the Transaction model. "
"This class provides a read-only interface for interacting with transaction data. "
"It uses the TransactionSerializer for serializing and deserializing "

View file

@ -44,7 +44,7 @@ from engine.vibes_auth.models import (
)
class BalanceInline(TabularInline): # type: ignore [type-arg]
class BalanceInline(TabularInline):
model = Balance
can_delete = False
extra = 0
@ -54,7 +54,7 @@ class BalanceInline(TabularInline): # type: ignore [type-arg]
icon = "fa-solid fa-wallet"
class OrderInline(TabularInline): # type: ignore [type-arg]
class OrderInline(TabularInline):
model = Order
extra = 0
verbose_name = _("order")
@ -63,7 +63,7 @@ class OrderInline(TabularInline): # type: ignore [type-arg]
icon = "fa-solid fa-cart-shopping"
class UserAdmin(ActivationActionsMixin, BaseUserAdmin, ModelAdmin): # type: ignore [misc, type-arg]
class UserAdmin(ActivationActionsMixin, BaseUserAdmin, ModelAdmin):
inlines = (BalanceInline, OrderInline)
fieldsets = (
(None, {"fields": ("email", "password")}),
@ -165,11 +165,11 @@ class ChatThreadAdmin(ModelAdmin):
readonly_fields = ("created", "modified")
@admin.action(description=_("Close selected threads"))
def close_threads(self, request, queryset): # type: ignore[no-untyped-def]
def close_threads(self, request, queryset):
queryset.update(status=ThreadStatus.CLOSED)
@admin.action(description=_("Open selected threads"))
def open_threads(self, request, queryset): # type: ignore[no-untyped-def]
def open_threads(self, request, queryset):
queryset.update(status=ThreadStatus.OPEN)

View file

@ -4,7 +4,7 @@ from engine.core.widgets import JSONTableWidget
from engine.vibes_auth.models import User
class UserForm(UserChangeForm): # type: ignore [type-arg]
class UserForm(UserChangeForm):
password = ReadOnlyPasswordHashField(label="Password")
class Meta:

View file

@ -36,7 +36,7 @@ class JWTAuthMiddleware(BaseMiddleware):
def __init__(self, token_str: str):
self.META = {"HTTP_X_EVIBES_AUTH": f"Bearer {token_str}"}
user, _ = jwt_auth.authenticate(_Req(token)) # type: ignore[arg-type]
user, _ = jwt_auth.authenticate(_Req(token))
scope["user"] = user
return await super().__call__(scope, receive, send)

View file

@ -26,7 +26,7 @@ def _get_bot() -> Bot | None:
if not is_telegram_enabled():
logger.warning("Telegram forwarder disabled: missing aiogram or TELEGRAM_TOKEN")
return None
return Bot(token=settings.TELEGRAM_TOKEN, parse_mode=ParseMode.HTML) # type: ignore[arg-type]
return Bot(token=settings.TELEGRAM_TOKEN, parse_mode=ParseMode.HTML)
def build_router() -> Router | None:
@ -37,7 +37,7 @@ def build_router() -> Router | None:
router: Router = Router()
@router.message(Command("start"))
async def cmd_start(message: types.Message): # type: ignore[valid-type]
async def cmd_start(message: types.Message):
parts = (message.text or "").split(maxsplit=1)
if len(parts) < 2:
await message.answer(
@ -50,12 +50,12 @@ def build_router() -> Router | None:
def _link():
try:
retrieved_user = User.objects.get(activation_token=token)
except User.DoesNotExist: # type: ignore[attr-defined]
except User.DoesNotExist:
return None
attrs = dict(retrieved_user.attributes or {})
attrs["telegram_id"] = message.from_user.id if message.from_user else None # type: ignore[union-attr]
attrs["telegram_id"] = message.from_user.id if message.from_user else None
retrieved_user.attributes = attrs
retrieved_user.save(update_fields=["attributes", "modified"]) # type: ignore[attr-defined]
retrieved_user.save(update_fields=["attributes", "modified"])
return retrieved_user
user = await asyncio.to_thread(_link)
@ -65,8 +65,8 @@ def build_router() -> Router | None:
await message.answer("Your Telegram account has been linked successfully.")
@router.message(Command("unlink"))
async def cmd_unlink(message: types.Message): # type: ignore[valid-type]
tid = message.from_user.id if message.from_user else None # type: ignore[union-attr]
async def cmd_unlink(message: types.Message):
tid = message.from_user.id if message.from_user else None
if not tid:
await message.answer("Cannot unlink: no Telegram user id.")
return
@ -83,7 +83,7 @@ def build_router() -> Router | None:
await message.answer("No linked account found.")
@router.message(Command("help"))
async def cmd_help(message: types.Message): # type: ignore[valid-type]
async def cmd_help(message: types.Message):
await message.answer(
"Commands:\n"
"/start <token> — link your account\n"
@ -92,7 +92,7 @@ def build_router() -> Router | None:
)
@router.message()
async def any_message(message: types.Message): # type: ignore[valid-type]
async def any_message(message: types.Message):
from engine.vibes_auth.messaging.services import (
send_message as svc_send_message,
)
@ -106,7 +106,7 @@ def build_router() -> Router | None:
staff_user = User.objects.get(
attributes__telegram_id=tid, is_staff=True, is_active=True
)
except User.DoesNotExist: # type: ignore[attr-defined]
except User.DoesNotExist:
return None, None, None
# group check
if not staff_user.groups.filter(name=USER_SUPPORT_GROUP_NAME).exists():
@ -193,7 +193,7 @@ def install_aiohttp_webhook(app) -> None:
if not is_telegram_enabled():
logger.warning("Telegram forwarder not installed: disabled")
return
dp = Dispatcher() # type: ignore[call-arg]
dp = Dispatcher()
router = build_router()
if router:
dp.include_router(router)
@ -202,5 +202,5 @@ def install_aiohttp_webhook(app) -> None:
return
SimpleRequestHandler(dispatcher=dp, bot=bot).register(
app, path="/telegram/webhook/" + settings.TELEGRAM_TOKEN
) # type: ignore[arg-type]
)
logger.info("Telegram webhook handler installed on aiohttp app.")

View file

@ -103,7 +103,7 @@ def send_message(
def auto_reply(thread: ChatThread) -> None:
text = _("We're searching for the operator to answer you already, hold by!")
msg = ChatMessage.objects.create( # type: ignore [misc]
msg = ChatMessage.objects.create(
thread=thread,
sender_type=SenderType.SYSTEM,
sender_user=None,

View file

@ -37,9 +37,9 @@ from engine.vibes_auth.managers import UserManager
from engine.vibes_auth.validators import validate_phone_number
class User(AbstractUser, NiceModel): # type: ignore [django-manager-missing]
class User(AbstractUser, NiceModel):
__doc__ = _(
"Represents a User entity with customized fields and methods for extended functionality. " # type: ignore
"Represents a User entity with customized fields and methods for extended functionality. "
"This class extends the AbstractUser model and integrates additional features like "
"custom email login, validation methods, subscription status, verification, and "
"attributes storage. It also provides utilities for managing recently viewed items and "
@ -62,9 +62,9 @@ class User(AbstractUser, NiceModel): # type: ignore [django-manager-missing]
validate_phone_number,
],
)
username: None = None # type: ignore [assignment]
first_name = CharField(_("first_name"), max_length=150, blank=True, null=True) # type: ignore [assignment]
last_name = CharField(_("last_name"), max_length=150, blank=True, null=True) # type: ignore [assignment]
username: None = None
first_name = CharField(_("first_name"), max_length=150, blank=True, null=True)
last_name = CharField(_("last_name"), max_length=150, blank=True, null=True)
avatar = ImageField(
null=True,
verbose_name=_("avatar"),
@ -106,7 +106,7 @@ class User(AbstractUser, NiceModel): # type: ignore [django-manager-missing]
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
# noinspection PyClassVar
objects = UserManager() # type: ignore [misc, assignment]
objects = UserManager()
@cached_property
def avatar_url(self) -> str:

View file

@ -200,7 +200,7 @@ class TokenObtainPairSerializer(TokenObtainSerializer):
refresh = self.get_token(self.user)
data["refresh"] = str(refresh)
# noinspection PyUnresolvedReferences
data["access"] = str(refresh.access_token) # type: ignore [attr-defined]
data["access"] = str(refresh.access_token)
data["user"] = (
UserSerializer(self.user).data if self.retrieve_user else self.user.pk
)

View file

@ -30,7 +30,7 @@ logger = logging.getLogger(__name__)
@extend_schema_view(**TOKEN_OBTAIN_SCHEMA)
class TokenObtainPairView(TokenViewBase):
__doc__ = _( # type: ignore [assignment]
__doc__ = _(
"Represents a view for getting a pair of access and refresh tokens and user's data. "
"This view manages the process of handling token-based authentication where "
"clients can get a pair of JWT tokens (access and refresh) using provided "
@ -38,12 +38,12 @@ class TokenObtainPairView(TokenViewBase):
"rate limiting to protect against brute force attacks."
)
serializer_class = TokenObtainPairSerializer # type: ignore [assignment]
_serializer_class = TokenObtainPairSerializer # type: ignore [assignment]
permission_classes: list[Type[BasePermission]] = [ # type: ignore [assignment]
serializer_class = TokenObtainPairSerializer
_serializer_class = TokenObtainPairSerializer
permission_classes: list[Type[BasePermission]] = [
AllowAny,
]
authentication_classes: list[str] = [] # type: ignore [assignment]
authentication_classes: list[str] = []
@method_decorator(ratelimit(key="ip", rate="10/h"))
def post(
@ -54,7 +54,7 @@ class TokenObtainPairView(TokenViewBase):
@extend_schema_view(**TOKEN_REFRESH_SCHEMA)
class TokenRefreshView(TokenViewBase):
__doc__ = _( # type: ignore [assignment]
__doc__ = _(
"Handles refreshing of tokens for authentication purposes. "
"This class is used to provide functionality for token refresh "
"operations as part of an authentication system. It ensures that "
@ -63,12 +63,12 @@ class TokenRefreshView(TokenViewBase):
"refresh inputs and produce appropriate outputs."
)
serializer_class = TokenRefreshSerializer # type: ignore [assignment]
_serializer_class = TokenRefreshSerializer # type: ignore [assignment]
permission_classes: list[Type[BasePermission]] = [ # type: ignore [assignment]
serializer_class = TokenRefreshSerializer
_serializer_class = TokenRefreshSerializer
permission_classes: list[Type[BasePermission]] = [
AllowAny,
]
authentication_classes: list[str] = [] # type: ignore [assignment]
authentication_classes: list[str] = []
@method_decorator(ratelimit(key="ip", rate="10/h"))
def post(
@ -79,16 +79,16 @@ class TokenRefreshView(TokenViewBase):
@extend_schema_view(**TOKEN_VERIFY_SCHEMA)
class TokenVerifyView(TokenViewBase):
__doc__ = _( # type: ignore [assignment]
__doc__ = _(
"Represents a view for verifying JSON Web Tokens (JWT) using specific serialization and validation logic. "
)
serializer_class = TokenVerifySerializer # type: ignore [assignment]
_serializer_class = TokenVerifySerializer # type: ignore [assignment]
permission_classes: list[Type[BasePermission]] = [ # type: ignore [assignment]
serializer_class = TokenVerifySerializer
_serializer_class = TokenVerifySerializer
permission_classes: list[Type[BasePermission]] = [
AllowAny,
]
authentication_classes: list[str] = [] # type: ignore [assignment]
authentication_classes: list[str] = []
def post(
self, request: Request, *args: list[Any], **kwargs: dict[Any, Any]

View file

@ -41,7 +41,7 @@ class UserViewSet(
mixins.DestroyModelMixin,
GenericViewSet,
):
__doc__ = _( # type: ignore [assignment]
__doc__ = _(
"User view set implementation.\n"
"Provides a set of actions that manage user-related data such as creation, "
"retrieval, updates, deletion, and custom actions including password reset, "
@ -89,16 +89,16 @@ class UserViewSet(
try:
if not compare_digest(
request.data.get("password"), request.data.get("confirm_password")
): # type: ignore [arg-type]
):
return Response(
{"error": _("passwords do not match")},
status=status.HTTP_400_BAD_REQUEST,
)
uuid = urlsafe_base64_decode(request.data.get("uidb_64")).decode() # type: ignore [arg-type]
uuid = urlsafe_base64_decode(request.data.get("uidb_64")).decode()
user = User.objects.get(pk=uuid)
validate_password(password=request.data.get("password"), user=user) # type: ignore [arg-type]
validate_password(password=request.data.get("password"), user=user)
password_reset_token = PasswordResetTokenGenerator()
if not password_reset_token.check_token(user, request.data.get("token")):
@ -147,11 +147,11 @@ class UserViewSet(
detail = ""
activation_error: Type[Exception] | None = None
try:
uuid = urlsafe_base64_decode(request.data.get("uidb_64")).decode() # type: ignore [arg-type]
uuid = urlsafe_base64_decode(request.data.get("uidb_64")).decode()
user = User.objects.get(pk=uuid)
if not user.check_token(
urlsafe_base64_decode(request.data.get("token")).decode()
): # type: ignore [arg-type]
):
return Response(
{"error": _("activation link is invalid!")},
status=status.HTTP_400_BAD_REQUEST,
@ -175,7 +175,7 @@ class UserViewSet(
detail = str(traceback.format_exc())
if user is None:
if settings.DEBUG:
raise Exception from activation_error # type: ignore [misc]
raise Exception from activation_error
return Response(
{"error": _("activation link is invalid!"), "detail": detail},
status=status.HTTP_400_BAD_REQUEST,

View file

@ -4,7 +4,7 @@ from urllib.parse import urlparse
from storages.backends.ftp import FTPStorage
class AbsoluteFTPStorage(FTPStorage): # type: ignore
class AbsoluteFTPStorage(FTPStorage):
# noinspection PyProtectedMember
# noinspection PyUnresolvedReferences

View file

@ -167,10 +167,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -216,9 +216,9 @@ msgstr ""
"## المصادقة\n"
"- يتم التعامل مع المصادقة عبر رموز JWT المميزة. قم بتضمين الرمز المميز في رأس \"X-EVIBES-AUTH\" لطلباتك بصيغة \"حامل <your_token>\".\n"
"{\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}{\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"}- يتم تدوير رموز التحديث تلقائيًا وإبطالها بعد الاستخدام لتعزيز الأمان.\n"
"\n"
"## التدويل (i18n)\n"

View file

@ -167,10 +167,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -216,10 +216,10 @@ msgstr ""
"## Ověřování\n"
"- Ověřování se provádí pomocí tokenů JWT. Token zahrňte do hlavičky `X-EVIBES-AUTH` svých požadavků ve formátu `Bearer <vůj_token>`.\n"
"- Životnost přístupového tokenu je {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"}. {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Životnost tokenu pro obnovení je {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hodin.\n"
"- Tokeny pro obnovení jsou po použití automaticky rotovány a zneplatněny z důvodu vyšší bezpečnosti.\n"
"\n"

View file

@ -167,10 +167,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -216,10 +216,10 @@ msgstr ""
"## Autentificering\n"
"- Autentificering håndteres via JWT-tokens. Inkluder tokenet i `X-EVIBES-AUTH`-headeren i dine anmodninger i formatet `Bearer <your_token>`.\n"
"- Adgangstokenets levetid er {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Opdateringstokenets levetid er {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} timer.\n"
"- Refresh-tokens bliver automatisk roteret og ugyldiggjort efter brug for at øge sikkerheden.\n"
"\n"

View file

@ -170,10 +170,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -219,10 +219,10 @@ msgstr ""
"## Authentifizierung\n"
"- Die Authentifizierung erfolgt über JWT-Tokens. Fügen Sie das Token in den `X-EVIBES-AUTH`-Header Ihrer Anfragen im Format `Bearer <Ihr_token>` ein.\n"
"- Die Lebensdauer des Zugangstokens beträgt {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Die Lebensdauer von Auffrischungstoken beträgt {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} Stunden.\n"
"- Refresh-Tokens werden automatisch rotiert und nach der Verwendung ungültig gemacht, um die Sicherheit zu erhöhen.\n"
"\n"

View file

@ -171,10 +171,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -220,10 +220,10 @@ msgstr ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"

View file

@ -167,10 +167,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -216,10 +216,10 @@ msgstr ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"

View file

@ -169,10 +169,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -218,10 +218,10 @@ msgstr ""
"## Autenticación\n"
"- La autenticación se gestiona mediante tokens JWT. Incluya el token en la cabecera `X-EVIBES-AUTH` de sus peticiones con el formato `Bearer <su_token>`.\n"
"- La duración del token de acceso es {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- La duración del token de actualización es de {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} horas.\n"
"- Los tokens de actualización se rotan automáticamente y se invalidan después de su uso para mejorar la seguridad.\n"
"\n"

View file

@ -182,7 +182,7 @@ msgid ""
"EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not "
"DEBUG else 3600 # type: ignore [union-attr]\n"
"DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # "

View file

@ -172,10 +172,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -221,10 +221,10 @@ msgstr ""
"## Authentification\n"
"- L'authentification est gérée par des jetons JWT. Incluez le jeton dans l'en-tête `X-EVIBES-AUTH` de vos requêtes au format `Bearer <votre_token>`.\n"
"- La durée de vie du jeton d'accès est de {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- La durée de vie du jeton de rafraîchissement est de {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} heures.\n"
"- Les jetons de rafraîchissement font l'objet d'une rotation automatique et sont invalidés après utilisation pour une meilleure sécurité.\n"
"\n"

View file

@ -166,10 +166,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -198,9 +198,9 @@ msgstr ""
"\n"
"## ממשקי API זמינים - **REST API:** ממשק RESTful מלא (תיעוד זה) - **GraphQL API:** זמין ב-`/graphql/` עם ממשק GraphiQL לשאילתות אינטראקטיביות ## אימות - האימות מתבצע באמצעות אסימוני JWT. כלול את האסימון בכותרת `X-EVIBES-AUTH` של בקשותיך בפורמט `Bearer <your_token>`.\n"
"- אורך חיי אסימון הגישה הוא {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}. - אורך חיי אסימון הרענון הוא {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} שעות. - אסימוני הרענון מסתובבים באופן אוטומטי ומבוטלים לאחר השימוש לשם אבטחה משופרת. ## בינלאומיות (i18n) - הגדר את הכותרת `Accept-Language` כדי לציין את השפה המועדפת עליך (לדוגמה, `Accept-Language: en-US`).\n"
"- ניתן לאחזר את השפות הזמינות מנקודת הקצה `/app/languages/`. - כל התוכן המוצג למשתמש תומך במספר שפות באופן מובנה. ## פורמטים של תגובה ה-API תומך במספר פורמטים של תגובה: - **JSON** (ברירת מחדל, בפורמט camelCase) - **XML** (הוסף `?format=xml` או הגדר `Accept: application/xml`)\n"
"- **YAML** (הוסף `?format=yaml` או הגדר `Accept: application/x-yaml`) ## תקינות וניטור - בדיקות תקינות: `/health/` - מדדי Prometheus (מוגנים באמצעות אימות בסיסי): `/prometheus/` ## גרסה גרסת ה-API הנוכחית: {EVIBES_VERSION}\n"

View file

@ -182,7 +182,7 @@ msgid ""
"EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not "
"DEBUG else 3600 # type: ignore [union-attr]\n"
"DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # "

View file

@ -182,7 +182,7 @@ msgid ""
"EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not "
"DEBUG else 3600 # type: ignore [union-attr]\n"
"DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # "

View file

@ -167,10 +167,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -216,10 +216,10 @@ msgstr ""
"## Otentikasi\n"
"- Otentikasi ditangani melalui token JWT. Sertakan token di header `X-EVIBES-AUTH` pada permintaan Anda dalam format `Bearer <your_token>`.\n"
"- Masa berlaku token akses adalah {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Masa berlaku token refresh adalah {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} jam.\n"
"- Refresh token secara otomatis dirotasi dan dibatalkan setelah digunakan untuk meningkatkan keamanan.\n"
"\n"

View file

@ -168,10 +168,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -217,10 +217,10 @@ msgstr ""
"## Autenticazione\n"
"- L'autenticazione è gestita tramite token JWT. Includere il token nell'intestazione `X-EVIBES-AUTH` delle richieste nel formato `Bearer <your_token>`.\n"
"- La durata di vita del token di accesso è {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- La durata del token di aggiornamento è di {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} ore.\n"
"- I token di aggiornamento vengono ruotati e invalidati automaticamente dopo l'uso per una maggiore sicurezza.\n"
"\n"

View file

@ -165,10 +165,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -214,10 +214,10 @@ msgstr ""
"## 認証\n"
"- 認証はJWTトークンで行われる。リクエストの `X-EVIBES-AUTH` ヘッダーに `Bearer <your_token>` という形式でトークンを含めてください。\n"
"- アクセストークンの有効期限は {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}。\n"
"- リフレッシュ・トークンの有効期限は {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} 時間です。\n"
"- リフレッシュ・トークンはセキュリティ強化のため、使用後に自動的にローテーションされ無効化されます。\n"
"\n"

View file

@ -182,7 +182,7 @@ msgid ""
"EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not "
"DEBUG else 3600 # type: ignore [union-attr]\n"
"DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # "

View file

@ -165,10 +165,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -214,10 +214,10 @@ msgstr ""
"## 인증\n"
"- 인증은 JWT 토큰을 통해 처리됩니다. 토큰을 요청의 `X-EVIBES-AUTH` 헤더에 `Bearer <your_token>` 형식으로 포함하세요.\n"
"- 액세스 토큰 수명은 {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"}입니다. {\"minutes\" if not DEBUG else \"hours\"}입니다.\n"
"- 새로 고침 토큰 수명은 {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} 시간입니다.\n"
"- 새로 고침 토큰은 보안 강화를 위해 사용 후 자동으로 교체되고 무효화됩니다.\n"
"\n"

View file

@ -169,10 +169,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -218,10 +218,10 @@ msgstr ""
"## Authenticatie\n"
"- Authenticatie wordt afgehandeld via JWT tokens. Neem het token op in de `X-EVIBES-AUTH` header van je verzoeken in het formaat `Bearer <jouw_token>`.\n"
"- De levensduur van het toegangstoken is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- De levensduur van een verversingstoken is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} uur.\n"
"- Refresh tokens worden automatisch geroteerd en ongeldig gemaakt na gebruik voor een betere beveiliging.\n"
"\n"

View file

@ -167,10 +167,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -216,10 +216,10 @@ msgstr ""
"## Autentisering\n"
"- Autentisering håndteres via JWT-tokens. Inkluder tokenet i `X-EVIBES-AUTH`-overskriften i forespørslene dine i formatet `Bearer <your_token>`.\n"
"- Levetiden for tilgangstoken er {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"}. {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Levetiden for oppdateringstoken er {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} timer.\n"
"- Oppdateringstokener roteres automatisk og ugyldiggjøres etter bruk for økt sikkerhet.\n"
"\n"

View file

@ -167,10 +167,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -216,10 +216,10 @@ msgstr ""
"## Uwierzytelnianie\n"
"- Uwierzytelnianie jest obsługiwane za pomocą tokenów JWT. Dołącz token w nagłówku `X-EVIBES-AUTH` swoich żądań w formacie `Bearer <your_token>`.\n"
"- Okres ważności tokenu dostępu wynosi {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Okres ważności tokenu odświeżania wynosi {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} godzin.\n"
"- Tokeny odświeżania są automatycznie obracane i unieważniane po użyciu w celu zwiększenia bezpieczeństwa.\n"
"\n"

View file

@ -168,10 +168,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -217,10 +217,10 @@ msgstr ""
"## Autenticação\n"
"- A autenticação é tratada por meio de tokens JWT. Inclua o token no cabeçalho `X-EVIBES-AUTH` de suas solicitações no formato `Bearer <your_token>`.\n"
"- O tempo de vida do token de acesso é {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- A vida útil do token de atualização é de {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} horas.\n"
"- Os tokens de atualização são automaticamente girados e invalidados após o uso para aumentar a segurança.\n"
"\n"

View file

@ -168,10 +168,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -217,10 +217,10 @@ msgstr ""
"## Autentificare\n"
"- Autentificarea este gestionată prin jetoane JWT. Includeți tokenul în antetul `X-EVIBES-AUTH` al cererilor dvs. în formatul `Bearer <your_token>`.\n"
"- Durata de viață a jetonului de acces este {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Durata de viață a jetonului de reînnoire este de {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} ore.\n"
"- Jetoanele de reîmprospătare sunt rotite automat și invalidate după utilizare pentru o securitate sporită.\n"
"\n"

View file

@ -167,10 +167,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -216,10 +216,10 @@ msgstr ""
"## Аутентификация\n"
"- Аутентификация осуществляется с помощью JWT-токенов. Включите токен в заголовок `X-EVIBES-AUTH` ваших запросов в формате `Bearer <ваш_токен>`.\n"
"- Срок действия токена доступа составляет {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Время жизни токена обновления составляет {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} часов.\n"
"- Для повышения безопасности маркеры доступа автоматически поворачиваются и аннулируются после использования.\n"
"\n"

View file

@ -167,10 +167,10 @@ msgid ""
"## Authentication\n"
"- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.\n"
"- Access token lifetime is {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Refresh token lifetime is {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} hours.\n"
"- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.\n"
"\n"
@ -216,10 +216,10 @@ msgstr ""
"## Autentisering\n"
"- Autentisering hanteras via JWT-tokens. Inkludera token i `X-EVIBES-AUTH`-huvudet för dina förfrågningar i formatet `Bearer <your_token>`.\n"
"- Åtkomsttokenens livstid är {\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"ACCESS_TOKEN_LIFETIME\").total_seconds() // 60 if not DEBUG else 3600\n"
"} {\"minutes\" if not DEBUG else \"hours\"}.\n"
"- Uppdateringstokenens livslängd är {\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600 # type: ignore [union-attr]\n"
" SIMPLE_JWT.get(\"REFRESH_TOKEN_LIFETIME\").total_seconds() // 3600\n"
"} timmar.\n"
"- Uppdateringstokens roteras automatiskt och ogiltigförklaras efter användning för ökad säkerhet.\n"
"\n"

Some files were not shown because too many files have changed in this diff Show more