From a81f734e23b1795bfbbe8860a95ea3acdcac5bc9 Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Thu, 18 Dec 2025 15:55:43 +0300 Subject: [PATCH] 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. --- engine/blog/admin.py | 8 +- engine/blog/apps.py | 2 +- engine/blog/elasticsearch/documents.py | 2 +- engine/blog/filters.py | 2 +- engine/blog/models.py | 4 +- engine/blog/viewsets.py | 4 +- engine/core/abstract.py | 6 +- engine/core/admin.py | 111 +++--- engine/core/elasticsearch/__init__.py | 4 +- engine/core/elasticsearch/documents.py | 4 +- engine/core/filters.py | 22 +- engine/core/graphene/__init__.py | 2 +- .../graphene/dashboard_mutations/product.py | 20 +- engine/core/graphene/mutations.py | 42 +- engine/core/graphene/object_types.py | 60 +-- .../management/commands/check_translated.py | 6 +- .../management/commands/deepl_translate.py | 16 +- .../commands/delete_never_ordered_products.py | 2 +- .../delete_products_by_description.py | 2 +- .../management/commands/fetch_products.py | 2 +- engine/core/managers.py | 2 +- engine/core/models.py | 102 ++--- engine/core/serializers/detail.py | 4 +- engine/core/serializers/simple.py | 48 +-- engine/core/serializers/utility.py | 44 +-- engine/core/signals.py | 8 +- engine/core/sitemaps.py | 8 +- engine/core/templatetags/arith.py | 2 +- engine/core/utils/__init__.py | 10 +- engine/core/utils/caching.py | 4 +- engine/core/utils/commerce.py | 2 +- engine/core/utils/emailing.py | 2 +- engine/core/utils/vendors.py | 2 +- engine/core/validators.py | 4 +- engine/core/vendors/__init__.py | 4 +- engine/core/views.py | 50 ++- engine/core/viewsets.py | 4 +- engine/core/widgets.py | 6 +- engine/payments/admin.py | 14 +- engine/payments/forms.py | 4 +- engine/payments/managers.py | 2 +- engine/payments/serializers.py | 8 +- engine/payments/signals.py | 2 +- engine/payments/views.py | 6 +- engine/payments/viewsets.py | 4 +- engine/vibes_auth/admin.py | 10 +- engine/vibes_auth/forms.py | 2 +- engine/vibes_auth/messaging/auth.py | 2 +- .../messaging/forwarders/telegram.py | 24 +- engine/vibes_auth/messaging/services.py | 2 +- engine/vibes_auth/models.py | 12 +- engine/vibes_auth/serializers.py | 2 +- engine/vibes_auth/views.py | 30 +- engine/vibes_auth/viewsets.py | 14 +- evibes/ftpstorage.py | 2 +- evibes/locale/ar_AR/LC_MESSAGES/django.mo | Bin 10547 -> 10535 bytes evibes/locale/ar_AR/LC_MESSAGES/django.po | 8 +- evibes/locale/cs_CZ/LC_MESSAGES/django.mo | Bin 9041 -> 9029 bytes evibes/locale/cs_CZ/LC_MESSAGES/django.po | 8 +- evibes/locale/da_DK/LC_MESSAGES/django.mo | Bin 8733 -> 8717 bytes evibes/locale/da_DK/LC_MESSAGES/django.po | 8 +- evibes/locale/de_DE/LC_MESSAGES/django.mo | Bin 9198 -> 9186 bytes evibes/locale/de_DE/LC_MESSAGES/django.po | 8 +- evibes/locale/en_GB/LC_MESSAGES/django.mo | Bin 8583 -> 8567 bytes evibes/locale/en_GB/LC_MESSAGES/django.po | 8 +- evibes/locale/en_US/LC_MESSAGES/django.mo | Bin 8587 -> 8573 bytes evibes/locale/en_US/LC_MESSAGES/django.po | 8 +- evibes/locale/es_ES/LC_MESSAGES/django.mo | Bin 9244 -> 9234 bytes evibes/locale/es_ES/LC_MESSAGES/django.po | 8 +- evibes/locale/fa_IR/LC_MESSAGES/django.po | 2 +- evibes/locale/fr_FR/LC_MESSAGES/django.mo | Bin 9512 -> 9498 bytes evibes/locale/fr_FR/LC_MESSAGES/django.po | 8 +- evibes/locale/he_IL/LC_MESSAGES/django.mo | Bin 9874 -> 9866 bytes evibes/locale/he_IL/LC_MESSAGES/django.po | 8 +- evibes/locale/hi_IN/LC_MESSAGES/django.po | 2 +- evibes/locale/hr_HR/LC_MESSAGES/django.po | 2 +- evibes/locale/id_ID/LC_MESSAGES/django.mo | Bin 8771 -> 8757 bytes evibes/locale/id_ID/LC_MESSAGES/django.po | 8 +- evibes/locale/it_IT/LC_MESSAGES/django.mo | Bin 9159 -> 9143 bytes evibes/locale/it_IT/LC_MESSAGES/django.po | 8 +- evibes/locale/ja_JP/LC_MESSAGES/django.mo | Bin 9573 -> 9561 bytes evibes/locale/ja_JP/LC_MESSAGES/django.po | 8 +- evibes/locale/kk_KZ/LC_MESSAGES/django.po | 2 +- evibes/locale/ko_KR/LC_MESSAGES/django.mo | Bin 8975 -> 8957 bytes evibes/locale/ko_KR/LC_MESSAGES/django.po | 8 +- evibes/locale/nl_NL/LC_MESSAGES/django.mo | Bin 8869 -> 8853 bytes evibes/locale/nl_NL/LC_MESSAGES/django.po | 8 +- evibes/locale/no_NO/LC_MESSAGES/django.mo | Bin 8791 -> 8773 bytes evibes/locale/no_NO/LC_MESSAGES/django.po | 8 +- evibes/locale/pl_PL/LC_MESSAGES/django.mo | Bin 9113 -> 9093 bytes evibes/locale/pl_PL/LC_MESSAGES/django.po | 8 +- evibes/locale/pt_BR/LC_MESSAGES/django.mo | Bin 9183 -> 9173 bytes evibes/locale/pt_BR/LC_MESSAGES/django.po | 8 +- evibes/locale/ro_RO/LC_MESSAGES/django.mo | Bin 9237 -> 9223 bytes evibes/locale/ro_RO/LC_MESSAGES/django.po | 8 +- evibes/locale/ru_RU/LC_MESSAGES/django.mo | Bin 11647 -> 11631 bytes evibes/locale/ru_RU/LC_MESSAGES/django.po | 8 +- evibes/locale/sv_SE/LC_MESSAGES/django.mo | Bin 8880 -> 8870 bytes evibes/locale/sv_SE/LC_MESSAGES/django.po | 8 +- evibes/locale/th_TH/LC_MESSAGES/django.mo | Bin 13442 -> 13430 bytes evibes/locale/th_TH/LC_MESSAGES/django.po | 8 +- evibes/locale/tr_TR/LC_MESSAGES/django.mo | Bin 9217 -> 9207 bytes evibes/locale/tr_TR/LC_MESSAGES/django.po | 8 +- evibes/locale/vi_VN/LC_MESSAGES/django.mo | Bin 9793 -> 9785 bytes evibes/locale/vi_VN/LC_MESSAGES/django.po | 8 +- evibes/locale/zh_Hans/LC_MESSAGES/django.mo | Bin 8305 -> 8289 bytes evibes/locale/zh_Hans/LC_MESSAGES/django.po | 8 +- evibes/pagination.py | 4 +- evibes/settings/base.py | 4 +- evibes/settings/drf.py | 21 +- pyproject.toml | 49 ++- pyrightconfig.json | 23 -- uv.lock | 367 ++++++++++++++---- 113 files changed, 837 insertions(+), 598 deletions(-) delete mode 100644 pyrightconfig.json diff --git a/engine/blog/admin.py b/engine/blog/admin.py index 54e427b3..0c44db09 100644 --- a/engine/blog/admin.py +++ b/engine/blog/admin.py @@ -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",) diff --git a/engine/blog/apps.py b/engine/blog/apps.py index 500c1bdd..87fa6ba2 100644 --- a/engine/blog/apps.py +++ b/engine/blog/apps.py @@ -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 diff --git a/engine/blog/elasticsearch/documents.py b/engine/blog/elasticsearch/documents.py index 779c644a..122b7bad 100644 --- a/engine/blog/elasticsearch/documents.py +++ b/engine/blog/elasticsearch/documents.py @@ -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", diff --git a/engine/blog/filters.py b/engine/blog/filters.py index fd6f1db3..0b8fc327 100644 --- a/engine/blog/filters.py +++ b/engine/blog/filters.py @@ -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") diff --git a/engine/blog/models.py b/engine/blog/models.py index 7c9658de..e187f866 100644 --- a/engine/blog/models.py +++ b/engine/blog/models.py @@ -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. " diff --git a/engine/blog/viewsets.py b/engine/blog/viewsets.py index 0ca86f77..a617ec96 100644 --- a/engine/blog/viewsets.py +++ b/engine/blog/viewsets.py @@ -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 " diff --git a/engine/core/abstract.py b/engine/core/abstract.py index 9f7cf6c4..40851d7d 100644 --- a/engine/core/abstract.py +++ b/engine/core/abstract.py @@ -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, diff --git a/engine/core/admin.py b/engine/core/admin.py index a4a1a2e9..f9afb886 100644 --- a/engine/core/admin.py +++ b/engine/core/admin.py @@ -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 diff --git a/engine/core/elasticsearch/__init__.py b/engine/core/elasticsearch/__init__.py index 7756e3ae..185ec46b 100644 --- a/engine/core/elasticsearch/__init__.py +++ b/engine/core/elasticsearch/__init__.py @@ -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) diff --git a/engine/core/elasticsearch/documents.py b/engine/core/elasticsearch/documents.py index f741f8c7..cf7f05b5 100644 --- a/engine/core/elasticsearch/documents.py +++ b/engine/core/elasticsearch/documents.py @@ -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" diff --git a/engine/core/filters.py b/engine/core/filters.py index cd27fcf0..70fa2ef1 100644 --- a/engine/core/filters.py +++ b/engine/core/filters.py @@ -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") diff --git a/engine/core/graphene/__init__.py b/engine/core/graphene/__init__.py index 382eefd7..c461af03 100644 --- a/engine/core/graphene/__init__.py +++ b/engine/core/graphene/__init__.py @@ -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) diff --git a/engine/core/graphene/dashboard_mutations/product.py b/engine/core/graphene/dashboard_mutations/product.py index 0bbc97af..747158dc 100644 --- a/engine/core/graphene/dashboard_mutations/product.py +++ b/engine/core/graphene/dashboard_mutations/product.py @@ -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) diff --git a/engine/core/graphene/mutations.py b/engine/core/graphene/mutations.py index e0d9fde4..4f1dd3a1 100644 --- a/engine/core/graphene/mutations.py +++ b/engine/core/graphene/mutations.py @@ -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 diff --git a/engine/core/graphene/object_types.py b/engine/core/graphene/object_types.py index 1f6abe78..c1b3f879 100644 --- a/engine/core/graphene/object_types.py +++ b/engine/core/graphene/object_types.py @@ -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) diff --git a/engine/core/management/commands/check_translated.py b/engine/core/management/commands/check_translated.py index 29e62927..afdcdac3 100644 --- a/engine/core/management/commands/check_translated.py +++ b/engine/core/management/commands/check_translated.py @@ -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 diff --git a/engine/core/management/commands/deepl_translate.py b/engine/core/management/commands/deepl_translate.py index b5441ea5..395ea2cc 100644 --- a/engine/core/management/commands/deepl_translate.py +++ b/engine/core/management/commands/deepl_translate.py @@ -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 diff --git a/engine/core/management/commands/delete_never_ordered_products.py b/engine/core/management/commands/delete_never_ordered_products.py index 11a47347..7f9c8f10 100644 --- a/engine/core/management/commands/delete_never_ordered_products.py +++ b/engine/core/management/commands/delete_never_ordered_products.py @@ -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( diff --git a/engine/core/management/commands/delete_products_by_description.py b/engine/core/management/commands/delete_products_by_description.py index f39e1434..f249cf4d 100644 --- a/engine/core/management/commands/delete_products_by_description.py +++ b/engine/core/management/commands/delete_products_by_description.py @@ -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( diff --git a/engine/core/management/commands/fetch_products.py b/engine/core/management/commands/fetch_products.py index 27bd635a..56cd1922 100644 --- a/engine/core/management/commands/fetch_products.py +++ b/engine/core/management/commands/fetch_products.py @@ -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( diff --git a/engine/core/managers.py b/engine/core/managers.py index 36882106..69b24961 100644 --- a/engine/core/managers.py +++ b/engine/core/managers.py @@ -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"), diff --git a/engine/core/models.py b/engine/core/models.py index 63d8aaa8..7ff1797a 100644 --- a/engine/core/models.py +++ b/engine/core/models.py @@ -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 " diff --git a/engine/core/serializers/detail.py b/engine/core/serializers/detail.py index 834c5bec..2286779c 100644 --- a/engine/core/serializers/detail.py +++ b/engine/core/serializers/detail.py @@ -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): diff --git a/engine/core/serializers/simple.py b/engine/core/serializers/simple.py index 7f88badc..22a7f1c5 100644 --- a/engine/core/serializers/simple.py +++ b/engine/core/serializers/simple.py @@ -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) diff --git a/engine/core/serializers/utility.py b/engine/core/serializers/utility.py index 4b2cd298..ea015f3c 100644 --- a/engine/core/serializers/utility.py +++ b/engine/core/serializers/utility.py @@ -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) diff --git a/engine/core/signals.py b/engine/core/signals.py index 44c20d51..3f4b8aca 100644 --- a/engine/core/signals.py +++ b/engine/core/signals.py @@ -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( diff --git a/engine/core/sitemaps.py b/engine/core/sitemaps.py index ce30bfe6..b43e65c5 100644 --- a/engine/core/sitemaps.py +++ b/engine/core/sitemaps.py @@ -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 diff --git a/engine/core/templatetags/arith.py b/engine/core/templatetags/arith.py index fbd9dfa1..a3e000d2 100644 --- a/engine/core/templatetags/arith.py +++ b/engine/core/templatetags/arith.py @@ -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 diff --git a/engine/core/utils/__init__.py b/engine/core/utils/__init__.py index 5a23312a..bb6e3a41 100644 --- a/engine/core/utils/__init__.py +++ b/engine/core/utils/__init__.py @@ -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, diff --git a/engine/core/utils/caching.py b/engine/core/utils/caching.py index a51754a5..7f1a9fe1 100644 --- a/engine/core/utils/caching.py +++ b/engine/core/utils/caching.py @@ -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: diff --git a/engine/core/utils/commerce.py b/engine/core/utils/commerce.py index f6035e6e..4a9e2c91 100644 --- a/engine/core/utils/commerce.py +++ b/engine/core/utils/commerce.py @@ -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, diff --git a/engine/core/utils/emailing.py b/engine/core/utils/emailing.py index c570ba1c..4cd82d2d 100644 --- a/engine/core/utils/emailing.py +++ b/engine/core/utils/emailing.py @@ -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(), }, diff --git a/engine/core/utils/vendors.py b/engine/core/utils/vendors.py index efd18be0..3edf4304 100644 --- a/engine/core/utils/vendors.py +++ b/engine/core/utils/vendors.py @@ -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( diff --git a/engine/core/validators.py b/engine/core/validators.py index 525bb927..3b3643d0 100644 --- a/engine/core/validators.py +++ b/engine/core/validators.py @@ -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" diff --git a/engine/core/vendors/__init__.py b/engine/core/vendors/__init__.py index b2c2f249..28145d4f 100644 --- a/engine/core/vendors/__init__.py +++ b/engine/core/vendors/__init__.py @@ -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 diff --git a/engine/core/views.py b/engine/core/views.py index 8ca22bf2..21c69e7d 100644 --- a/engine/core/views.py +++ b/engine/core/views.py @@ -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. ") diff --git a/engine/core/viewsets.py b/engine/core/viewsets.py index 367d436f..c0681ae4 100644 --- a/engine/core/viewsets.py +++ b/engine/core/viewsets.py @@ -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) diff --git a/engine/core/widgets.py b/engine/core/widgets.py index eb484863..10098d34 100644 --- a/engine/core/widgets.py +++ b/engine/core/widgets.py @@ -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: diff --git a/engine/payments/admin.py b/engine/payments/admin.py index 4cd4b905..222a7cb8 100644 --- a/engine/payments/admin.py +++ b/engine/payments/admin.py @@ -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") diff --git a/engine/payments/forms.py b/engine/payments/forms.py index cfa3d522..41de8563 100644 --- a/engine/payments/forms.py +++ b/engine/payments/forms.py @@ -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__" diff --git a/engine/payments/managers.py b/engine/payments/managers.py index 80148a1e..36a28f90 100644 --- a/engine/payments/managers.py +++ b/engine/payments/managers.py @@ -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() diff --git a/engine/payments/serializers.py b/engine/payments/serializers.py index f2faac8c..4c89b6f6 100644 --- a/engine/payments/serializers.py +++ b/engine/payments/serializers.py @@ -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) diff --git a/engine/payments/signals.py b/engine/payments/signals.py index 32a55b8a..3aa05c04 100644 --- a/engine/payments/signals.py +++ b/engine/payments/signals.py @@ -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( _( diff --git a/engine/payments/views.py b/engine/payments/views.py index d63fff22..4afd4628 100644 --- a/engine/payments/views.py +++ b/engine/payments/views.py @@ -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." ) diff --git a/engine/payments/viewsets.py b/engine/payments/viewsets.py index 585ee39e..c8644bf0 100644 --- a/engine/payments/viewsets.py +++ b/engine/payments/viewsets.py @@ -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 " diff --git a/engine/vibes_auth/admin.py b/engine/vibes_auth/admin.py index 8e393a30..0e2aad00 100644 --- a/engine/vibes_auth/admin.py +++ b/engine/vibes_auth/admin.py @@ -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) diff --git a/engine/vibes_auth/forms.py b/engine/vibes_auth/forms.py index 26725eac..fba74eff 100644 --- a/engine/vibes_auth/forms.py +++ b/engine/vibes_auth/forms.py @@ -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: diff --git a/engine/vibes_auth/messaging/auth.py b/engine/vibes_auth/messaging/auth.py index 035843bb..f658efe5 100644 --- a/engine/vibes_auth/messaging/auth.py +++ b/engine/vibes_auth/messaging/auth.py @@ -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) diff --git a/engine/vibes_auth/messaging/forwarders/telegram.py b/engine/vibes_auth/messaging/forwarders/telegram.py index a9f1ae41..5e523e53 100644 --- a/engine/vibes_auth/messaging/forwarders/telegram.py +++ b/engine/vibes_auth/messaging/forwarders/telegram.py @@ -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 — 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.") diff --git a/engine/vibes_auth/messaging/services.py b/engine/vibes_auth/messaging/services.py index 91427d9c..0c99e08c 100644 --- a/engine/vibes_auth/messaging/services.py +++ b/engine/vibes_auth/messaging/services.py @@ -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, diff --git a/engine/vibes_auth/models.py b/engine/vibes_auth/models.py index 7156b0c6..13df78d8 100644 --- a/engine/vibes_auth/models.py +++ b/engine/vibes_auth/models.py @@ -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: diff --git a/engine/vibes_auth/serializers.py b/engine/vibes_auth/serializers.py index 1db4cc02..9876ce65 100644 --- a/engine/vibes_auth/serializers.py +++ b/engine/vibes_auth/serializers.py @@ -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 ) diff --git a/engine/vibes_auth/views.py b/engine/vibes_auth/views.py index b6dc60b8..3ff1597c 100644 --- a/engine/vibes_auth/views.py +++ b/engine/vibes_auth/views.py @@ -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] diff --git a/engine/vibes_auth/viewsets.py b/engine/vibes_auth/viewsets.py index 6e71ddc4..c0aa7d45 100644 --- a/engine/vibes_auth/viewsets.py +++ b/engine/vibes_auth/viewsets.py @@ -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, diff --git a/evibes/ftpstorage.py b/evibes/ftpstorage.py index a0e736ff..54b16ebf 100644 --- a/evibes/ftpstorage.py +++ b/evibes/ftpstorage.py @@ -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 diff --git a/evibes/locale/ar_AR/LC_MESSAGES/django.mo b/evibes/locale/ar_AR/LC_MESSAGES/django.mo index 0ee529c79b4700cf1a6efd4109cb56510d14e712..fcf5e77d13dd75c06b758d154bde3b7cd0149deb 100644 GIT binary patch delta 664 zcmZvau}Z^G6oyY)sWuU9Dw>8^YmM51q7@ob4i)`7GNT5{fzqf@B2ZBL(|IzmXl zImBd57m#)a?K{uxzt*uo!fr>_e-9jBG)N55OLUC>HThjiLbk)b=9j6XM0s3(_59+a Y{8`CQn%%q>ToqYx9}?UYFU@iA1OIBMtN;K2 delta 684 zcmaLUL1+^}6oBDLT7q^>H7Ri$V$8-^t~H62T|Dj9+jXJ9r)Yc7E}`pTX;kN`=ry`Ctcq*u*hBaN|>)Bkte= z`bhTMe`YgP2J%4zDX#W0f=74`zoUV_T>s*EVo!hqXrRPliS?!@65e7YmFn(F1D_B# zb<2}TerD;_gi@2tq^~LU0JCUf4e#Qf>rZWZW4GQUl)Av|HcDLw<;aIfqUvG_|LYZR zBqV#<;1|i^-(eAJy6!dO@23V`+9<1Ek&UPx&SPKy@R~2HHwM?RiyT#*pmgivZTyYW z8fS0fd8hyY diff --git a/evibes/locale/ar_AR/LC_MESSAGES/django.po b/evibes/locale/ar_AR/LC_MESSAGES/django.po index d94ab378..eb6e5f21 100644 --- a/evibes/locale/ar_AR/LC_MESSAGES/django.po +++ b/evibes/locale/ar_AR/LC_MESSAGES/django.po @@ -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 `.\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\" لطلباتك بصيغة \"حامل \".\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" diff --git a/evibes/locale/cs_CZ/LC_MESSAGES/django.mo b/evibes/locale/cs_CZ/LC_MESSAGES/django.mo index 09f709fbfea8235b170e9b79fe0d60db09b55746..84571096ffe4287436150c1fff45c8f97385fe47 100644 GIT binary patch delta 612 zcmZ{hKTE?v7>D1alGX&RX{#}nzl5VWyBQArBAFbdIQRiX z90eV8^(*)s_i{zhz~%Sc@7{lxJWrk`+4txwqXnP-m7O)yx(X^L<)duHx~!7| rZOiwEG!r`4sI>AD#N}t@D+=Q)^WNSyt>mIClD)clYu}Z(oyY1AKcS-e delta 604 zcmaLTJxD@P7{>8)Q!EoRwGy-NT7gkSL=Dvv60|ioRg{B-i-p+W(9j1B4S^giq9KSN zT3jr!prp^CDQS%gg1{w^K86PAf9TF$IQ-s+^Pcw{?(JA%%=zpxrv+ahtA%xt^7sSk zIw9%_N7#gC*og(~z~5AOG-Rh(bqLXjDO3jz(SkXw#k`U4ae!RFLA20pPkr`}Z&IiO z8DzLPK_A{=4Zflci-zB5C2LLwpbb^_sw|f^pLd%|P1-YdGB`ob$#X4eU2zM+8$?-_ zwBXQ&UkJ9vKB_6lSdAA(zC(5U12*6jdaxwJRU@s3x)3hX8>(OTgX+!hfO^YyRd;Be ziX&nN)y^rZw_T|YETFpg1=a5=8u<&o`.\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 `.\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" diff --git a/evibes/locale/da_DK/LC_MESSAGES/django.mo b/evibes/locale/da_DK/LC_MESSAGES/django.mo index c2ed534db9aef7a93318aa7092293f25e201abda..463771cf41551a89aca6868d2fe8c20c45e0c6a0 100644 GIT binary patch delta 573 zcmZvZJ5Iwu5QfJNauQoOI5Llfhe1I~BxoWi=u#vN6`+VdoP?T!!rGc9H$bithd?Pf z0JPiy@vU~WRwOL#{@?t&vopJXnLW>Tf8O7^8%)ACW*jgG%d9vQ-V)NbAU%9-RWFC9 zRiHzy(hDb>oLh+G>O6##Yn)^M0FdTES`*TTTJv}{+by1En9p!%|37b_Jwgk&%Vdp@ bAg;a|-;ufPpPM{cRAsVE3CilXUo`&!M*^D^ delta 570 zcmaLSJxD@P7{>8)vosSeqYu=~8wNHM5e0oLBDpj)Hbszxgo}mP(3ma-7096)Dgp_l z#RiMShzJ^@C8WlXrothY2*RoVL1!-lrw( z3DH5gz#c5%5EgL|tEtdzz{)1sE<`t`P#wsi5%buF_x1dY6XYUJp^;*1>Sug@pN%?@ zMVgCibm1em;s;u=T=y5vWX(7&zS=M}k zWWNxdyw9NOR6upp6PoZ1)i1oGn(zzNO%-(GpImA3o3A`VbdkR0Ws`q;Tdz%jjH>nq zRqqE>GrgedSwen9lu^}H<)p!9PYl#1IK*Y%rsam=RkP;inm>(hUH9to&Gqn%9$Ag9 r#lrgHMl`Y(9SOzbu_ZZb*=<~ryS1ckjZ0`UEO(sY##OnB(_{Jv25)b4 diff --git a/evibes/locale/da_DK/LC_MESSAGES/django.po b/evibes/locale/da_DK/LC_MESSAGES/django.po index 8105f764..f5af89df 100644 --- a/evibes/locale/da_DK/LC_MESSAGES/django.po +++ b/evibes/locale/da_DK/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/de_DE/LC_MESSAGES/django.mo b/evibes/locale/de_DE/LC_MESSAGES/django.mo index e480d5f192fd711cd8b6246032fd6141a5634410..dcf494f4af212b4bdae6e224573b1709c888b789 100644 GIT binary patch delta 633 zcmZvZ&q~8U5QitN#+rb&R;?PLYCKqC5A_cyA|84Oo}?7<>PvW0#Iwh+Z_roBQN*Y4 z;8jpODZYW9SWa8Tl@<|+P%X7Pds$DuK5 z<5i7Qbd$J;_R%3agVF(_*NUPoa^|HY^BAPZICNxhitx%!o1@)#Xw6gRsq4tR1^F3u z8$Ju7qdg1K5g@&(2|9IoW>9GzlF$6p&Ve)^(mw#{l|c+;JD8$!(zThlTkbmWAngzB zxjbm76~C2cW-HE9k$dzC)hQ=Pe}(B(pMt3TsD6f~lkA$s__{3OyE?(B{7S;wA3D&a AsQ>@~ delta 640 zcmaLTKS%;$7{~EfGqc40QeqaK*-)5+)euHQG)O~JL_cdhCG2Ap9%Bau<6+Mn2L`4IbY&!gl@H2?qr diff --git a/evibes/locale/de_DE/LC_MESSAGES/django.po b/evibes/locale/de_DE/LC_MESSAGES/django.po index d0bf1209..3f46812e 100644 --- a/evibes/locale/de_DE/LC_MESSAGES/django.po +++ b/evibes/locale/de_DE/LC_MESSAGES/django.po @@ -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 `.\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 ` 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" diff --git a/evibes/locale/en_GB/LC_MESSAGES/django.mo b/evibes/locale/en_GB/LC_MESSAGES/django.mo index e4b4500aba1ef828fec7ebeab85d91b88557f2ca..54e4717b48e3b3a709ddd309e8580d4ea515ab7d 100644 GIT binary patch delta 610 zcmZvY!AiqG5QaBNi8X<0Emf=5RO~^iP=X4AH}e1@;?Y;|2}F+~=pp1$auGy4`v5+I zUOkGQ{MH#J2!~2Gjuz-CI)hRHqSmsaKP2XvP<0zj`#3`z59G&_R4+kx&d$1&64DFc>D{5m)9iQy z$^Iu!XNkwHeHT?8P72MFIX4m)Y8mMz@OtLy=-*t%^aIy-p7;O& delta 607 zcma*iJxBs!9LMqJPO%r!vZxR@wansNvt z0*9oKEFy@8hQOsUA|i^WhzO2`z7O6k9ry5ge)l}j|NhU<}N z^XHvHv=WZ66VI_9tJsG|E*hF}Fj;94q62d%4;-Qm%h-%pX1>E=aur9>#%4$EYiMed zi9Aq5ii=b9;0-q76Wa0J^c$PVii-khN15F+>siI)-eo2$?VBq_oF`.\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 `.\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" diff --git a/evibes/locale/en_US/LC_MESSAGES/django.mo b/evibes/locale/en_US/LC_MESSAGES/django.mo index 259f5851bf8e2351bf1ed55668374f086f6e6605..a360a149edd05781e6980c3dd1a1e8159d8bbdf6 100644 GIT binary patch delta 604 zcmZvY&q~8U5QjHOi8aA$6>aOkRur`KP=kU(Z{`6+#G^0a3kcpsFUvkkE{YVN!bi}n zX9dA;yTb&*u$$jEzuldg-G}n$tn>LgU2gC*ds5z;bdDHzb2(t*;RY`-Ya zvw(}ntSZT2yi~nM4|REVFM%w{!r?Hi#yCbI^uTQz`$4=JBF7>ChbYaZlo1 zbceV=OY{<*L#Y5!t1IXa1@kJ9yN~u4a8`_A_%-(&jjz$|P$G~tjwg49YEQD_^+Jw6 z`{WJrxb3V$5symA(>G=iT&STW&ErW|kUSa0nB}qY8ECJNWQP2c&_CoKC6Hux gU-3A>al_;#%BuI|BXx)CkCn~uS^`gTWw*YQU$e`gvj6}9 delta 599 zcma*iJxGE<9LMo{RP5zJ%c4Tee59ZtM52PIshlDjo5G<%qD4b&Xb4KFp`v&=dRd}H zh?W|p5F=`+#m&ZsXo{ki2p1vgd-%-K!##ZN_uSq8{?G5!PQ>%l<~R^ML%iL*S+gq; zJa7xqN;t<(EZ_i^un#NdLS)j#B-0{92b!o3oS_r**o=2pF5(Eegk$Jrv&;M$p50@j z4qPC`#TEMS0UPlZb^Nd_V-s2PPylsQ*{ibL(0tw_W~$PuwQ_-T*!`sM^k2`O;dyMlav*QQi8C>bKvKhD24a*#<||%3(kV1GDJBM{K|% zs(YVMb@zr0QI?;!iI6&(G-|!9qsrSD#AA$L0ac}{jM~H6rrfvRXs+Ch`.\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 `.\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" diff --git a/evibes/locale/es_ES/LC_MESSAGES/django.mo b/evibes/locale/es_ES/LC_MESSAGES/django.mo index 87e306172155310db86a1b0388eddee50197fe17..ecfd854649e4e7db98b87ce8bc919c965b9dd900 100644 GIT binary patch delta 619 zcmZvaze>YU6o+q8O=}|7YSo4au|`m6QA-8w;MAo~BH}3cCdJW7;$2;QhRosvI6L?N z3Qj(Ni{IrQP7w^r{e9$9x8cDV`P+Jl(4y~yWLJNBwZcVd z$&jR+aM?kegMGbD8nHr=GBi;y*g-ocF%Qqv`3gJ8DeOW!lbz;gdti}JE()Lnb$08lW-T7~IxSskD?PH0L*%47v-q2SDK=N~zu6hD z2u)eWN{nMOo?#=tDz~+>Vcrnol{J10$Pwxt-k}>mQJ=u6V%9p}u1}23*4om&Q1ib7h57WxQJ>-<-G7Su)HkT_{~q=Ay{SN!*Jb)eMo1f|SAVNm*0sf% z7_dFrs|~|%M5iamdW?zjP&hJX3{Qn7!l9;MG#VLEgPukebc|-6mAG&$6=t47q3z5w J5+5F4&L7j|bLId5 diff --git a/evibes/locale/es_ES/LC_MESSAGES/django.po b/evibes/locale/es_ES/LC_MESSAGES/django.po index 2b0e273e..0ffc1cee 100644 --- a/evibes/locale/es_ES/LC_MESSAGES/django.po +++ b/evibes/locale/es_ES/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/fa_IR/LC_MESSAGES/django.po b/evibes/locale/fa_IR/LC_MESSAGES/django.po index 67548e09..3cc87687 100644 --- a/evibes/locale/fa_IR/LC_MESSAGES/django.po +++ b/evibes/locale/fa_IR/LC_MESSAGES/django.po @@ -182,7 +182,7 @@ msgid "" "EVIBES-AUTH` header of your requests in the format `Bearer `.\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 # " diff --git a/evibes/locale/fr_FR/LC_MESSAGES/django.mo b/evibes/locale/fr_FR/LC_MESSAGES/django.mo index 9ff632174b4b8f21957c33342cbbf6754d5da31f..7c80f5b1df3815475cb37082d16e62514f2feb54 100644 GIT binary patch delta 609 zcmZvZy-EW?5XX0ua3*(Zy!aUth~^9m+C&BIMAD^DL~N{l1m7TaDmk|E3DU~d;zNi{ ztQAuE3jWp^HjM{&^PB(9?0np0_&nVFd3$YC_!yo(Z<`l4PdkU0Wn)%EfHndh1lrT^ zo56J~ST|-pkS3!=L7T_TwbO8V4n?HJ`NzqK4nPfqXu>xKwE|TGCI3(j&8A$3O|af? zs-IzZ@%z{T_7=NEi+pLDN_@}!UyYKh7Bi9M(vfRvG_%W!{lw3%Q zK)MS^hlI2SbWg@v*O-Q6Lb@lY5;R=^+G@~rQE2=i_f+a#`bwkBm~DxHv^K=Fem+Pi tg|vU@SWexn)L9~m3m;WU%kMTWzRKT`8@GcVSU0B3sd_xOXYks4dtl24m7F5}(vW#mk=P@%?>9qDHi%aCZENI@w%T^)wWL5Lo z)4C9StUsZ;Asl#w>Vjuz#0skZU$Fx} zQFZkvUmJ!dRp+~2A$l-@>I)g9Rgpt=qdQc6m2eC{WWeAt$NBvcQc7+a9yMz&VEi!k z>bh5tZAaE-^o{jUIJ%~`.\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 `.\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" diff --git a/evibes/locale/he_IL/LC_MESSAGES/django.mo b/evibes/locale/he_IL/LC_MESSAGES/django.mo index 5fe2e76ae701c9901032e90de03f062f93a40680..f828a57977800a3372f4efabfe2a2c0bb1186bd3 100644 GIT binary patch delta 619 zcmZvZOG?B*5QaO6#7QDL86Qy$gfR{{h=gGj#OSARXaQn{brO|$RUm);yN#WUjM9NaoBb}@@eb*%uc3GE1NyY$n^ zacpr(sZ}9Yj24R4=C#_sL=T~mvbcU5&zJyoX%Iu0;h;^Sj!^OsMQC11J8XhA{)Y2Q zY#)DwonX(f^H^?xxNF^^DYD{)C4K9a5ei*->nE==%c9q^jYFBxf)I26=6im1MgEpj zE(UR`Kw}}dPc+tSdbFf({OSOOzvLDMt=KHcRYI<^CH?LfeJTf1 q3AwL>u5AyU23bIs9tO`|+~jpn2HW|cG#Ij3WO-dD5?$HXu%`Q#d9OyU^Dq1ThT(XJ^It+Ut*#* z>>t3x+uO1_f#I=#1u!o$$E^PA%;lc%M!d+B9;03v} z_%uw(N0ZOH!B14T+{Y5UMRl7uRMp>xf3n@|YTT|(S0A7{@g2_KJE}7c)TJFqb@Paf znNKx)ygTc|Ql;x2Jv22o)TWON2Z9qrdf#MVBp7HI42358Ws7Ywb4C2pHd~mvgeG1& N>YUD86;C*~tp9_HcYgo? diff --git a/evibes/locale/he_IL/LC_MESSAGES/django.po b/evibes/locale/he_IL/LC_MESSAGES/django.po index 650f2f06..99e4d0a2 100644 --- a/evibes/locale/he_IL/LC_MESSAGES/django.po +++ b/evibes/locale/he_IL/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/hi_IN/LC_MESSAGES/django.po b/evibes/locale/hi_IN/LC_MESSAGES/django.po index 8005be12..e5498dc3 100644 --- a/evibes/locale/hi_IN/LC_MESSAGES/django.po +++ b/evibes/locale/hi_IN/LC_MESSAGES/django.po @@ -182,7 +182,7 @@ msgid "" "EVIBES-AUTH` header of your requests in the format `Bearer `.\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 # " diff --git a/evibes/locale/hr_HR/LC_MESSAGES/django.po b/evibes/locale/hr_HR/LC_MESSAGES/django.po index 67548e09..3cc87687 100644 --- a/evibes/locale/hr_HR/LC_MESSAGES/django.po +++ b/evibes/locale/hr_HR/LC_MESSAGES/django.po @@ -182,7 +182,7 @@ msgid "" "EVIBES-AUTH` header of your requests in the format `Bearer `.\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 # " diff --git a/evibes/locale/id_ID/LC_MESSAGES/django.mo b/evibes/locale/id_ID/LC_MESSAGES/django.mo index 20023f79a19844febec30fdb11d1ed975bfb0f82..2253df7773e99d3915a71c1b92b98c91bfd7c682 100644 GIT binary patch delta 585 zcmZvYy-EW?5Xa||a4~lhJw=U)7~=;jsX`2~vq(U!B#5ogVP`Ga9P67LmJ-CyRxEq~ z#m-mox9l(>;KAPf=D+i`^E!SSZ~RW5S1SC3ugBTq;O1Goi>Zq&2LW0)Ix^bV@X6>h z3AiM(W~9kzv1zlonRa5gr%+5M^%ruuu> z4t@_i!d_vkSUN!TYAE`oAYKP@_tD`1W!2ugEkcfunxkFQ4m9&KIzJ<-ZJCg61geB6 zNFM`fcW9tBCZ*v8HFiW0eNRXShqM~huv=Xr+M;Q?IQLQ-cBsK7wC5b%gm{;g-=n1X XDu2iBCwVCH^sVl0n~%kDt6BX6c3Yi1 delta 584 zcmaLSJxGE<9LMo{QnWHHi(b^q$6lzQ2C1;xBB3D~o1(x$%0)wrXskAgLLQ`{L5Lzk za1m1yX)uV~9@?WRC|V*~8lvyvGyA~tx!-gD``=w5SPeQ~I?ZXp=V$aYE>pc;U)mu= z2jK>L@D9gO#}WKZg_aiWOpe-x=*ASv4cBPF61L*Kk!v_Z)^QFk6x&nZ)2k;;;aXv25IA8a8jP8y&MWp>G|9Vi~x88g`_W31$Gja(% zt_+JfM1I0i{M1}c%l@RdUY$nyoGhC07UiwVC{KUHS=6;mQ(!)+3c(L?j#ezAylWNv zP)GUZ4{XCPlyCjhyrzKb!dLH|H7w#Lt5t2!^sLzPE9N)LfT|9wiT$1Mf*RS1#^Pah oeK#73MW;fEM0`W@+m0Jo`.\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 `.\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" diff --git a/evibes/locale/it_IT/LC_MESSAGES/django.mo b/evibes/locale/it_IT/LC_MESSAGES/django.mo index 8437d9fd2cd44a6291b055e044f87f63d52ddc21..6193c30ddb93be8352fc7a34f41382d51d388490 100644 GIT binary patch delta 591 zcmZvZu}Z{15QaB*N6t&Y^AwE|@ze;X#O62^LB!&U*vTQbK7+o1Ha3Dy*e8(`79y5D zfrVHr7J~Q&e#;J%#=!3X?Z2}-vy+$Np-6t7pJrQ3hHuDNX0R-K{T!J#X2u)Pg3_ka zhJ;VXCy~dlG4o1t7%x<>j;p;L-Q9;mjz#6`=$Z;Z34fGb5xWkwlUl#z9U_a@axavaK}-CB%24`!uR@9BP&-FLCt% diff --git a/evibes/locale/it_IT/LC_MESSAGES/django.po b/evibes/locale/it_IT/LC_MESSAGES/django.po index 4c075280..aa18c595 100644 --- a/evibes/locale/it_IT/LC_MESSAGES/django.po +++ b/evibes/locale/it_IT/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/ja_JP/LC_MESSAGES/django.mo b/evibes/locale/ja_JP/LC_MESSAGES/django.mo index acea4d0cd35d534ea45ad9224397b5ec5b95a727..691e46c3b33e21988053a21503a19cf977b8b3e0 100644 GIT binary patch delta 600 zcmZvZu}%U(5Qg^-J>*V>!zd7lijau0k)V-I6DnzpG4>WTK83aAxi4XVwecYc1*HYH zyn^3mCqqKGWbgmx-Ahzh1x3^L)SGe$VfI`enM|F;JBjJcF!OR@M%7 zbf)Wss3#m@GoE4?OW2LS_QKSpkIj}}h$ggAH5{M^3s{5aPQJonatTM#L$S~P8j9?& zQ4Kj{xHv%*FR>b*P{%jNZ}gJ21_q#xDjO=xP0chi?9`+^=SvP}$pv|)b@$PeY%HI7 z+Y*A~h+VA3V;sPu`.\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 ` という形式でトークンを含めてください。\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" diff --git a/evibes/locale/kk_KZ/LC_MESSAGES/django.po b/evibes/locale/kk_KZ/LC_MESSAGES/django.po index 8005be12..e5498dc3 100644 --- a/evibes/locale/kk_KZ/LC_MESSAGES/django.po +++ b/evibes/locale/kk_KZ/LC_MESSAGES/django.po @@ -182,7 +182,7 @@ msgid "" "EVIBES-AUTH` header of your requests in the format `Bearer `.\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 # " diff --git a/evibes/locale/ko_KR/LC_MESSAGES/django.mo b/evibes/locale/ko_KR/LC_MESSAGES/django.mo index 220284d2f16b27767d6c382dbeddadbb0cd1507f..502707b19b430ebc21c160642ef093d59c20dbd6 100644 GIT binary patch delta 652 zcmZvZze)o^5Qq0Jl9)R&IfH+aQ(`#h**hTu(GmK2-a3|EcgVzfTR`+ zpCJ!mp5C^$QI4Kt=Igmf?vT5cp7ct4fpVpHcC>N2- zN=u=nP~s+X)N)V`a==9??{Cj@-cwJn@8@~Gzwd9qXMcU0{hpU<$Cl!1=WgWQ&(!;y zwX{TFjsoHn)S?A$KVEq zEXX3m)d~9W21_uHZhW`>!BVp3VF0>OvRAUXsQJ9xR5EGLev`#v@~L^D1-;7*TdJ{+ z>hfEiA=J%3%{RDB#RlpaX;N1x)1R>%^C-Xe!_ME>K-LUvT_eig5!B7uqPCV@sd(~) zP56p3K{Z>?U7~qc^7p)v3O$A7@3Pju-MrCk3wOmm?C diff --git a/evibes/locale/ko_KR/LC_MESSAGES/django.po b/evibes/locale/ko_KR/LC_MESSAGES/django.po index 11234db6..8f962d81 100644 --- a/evibes/locale/ko_KR/LC_MESSAGES/django.po +++ b/evibes/locale/ko_KR/LC_MESSAGES/django.po @@ -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 `.\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 ` 형식으로 포함하세요.\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" diff --git a/evibes/locale/nl_NL/LC_MESSAGES/django.mo b/evibes/locale/nl_NL/LC_MESSAGES/django.mo index aa50179e4db0ae0075f491594cff539bceb01495..572ca95550bd159d2750f38b21fa90e156793dc1 100644 GIT binary patch delta 595 zcmZvZ&q~8U5QldgN!vuKZPi*UMvVuHUW$M58j5(5BEE-Dpf^GA5*HuAgGb3l5b-H| zgo-y`!EfDV_F`c3`}Q|8JG05t_;K9(`FQWl@KQV@)+&o_+0J&5mQwT1fR==|g|>Y9 zq&QC;&MCDhb_?QM>Q^ zeU5IhAE5<$f!0wvK=fMnXp5YA>B!vayotl9yv>X5<>;DHM=lN>3NfwfW{hB_x;P*Y z=7ZQu$Tzfc@dBMV&rE9B8Tsq(0*)4346h@^G4@=%Ss~lsd5rZp?{n?c{&()~I|VX2 m>h`UBy(!T^W*EKcq?$%wvH4E!t1^9U0lVg5<*LdCxAk9FnV#eT delta 610 zcmaLSJxD@P6u|LohE^{%wGYh7XEqcR5k((vArcLZP0`>W(PAP7wFDW|Qo`dQK@l!i zwA3JxB@skZ(BK$EM1#;4L<9}d|MK4KgUj!n`_4V*-dyxJ>VEaq=LFvftBY08Is(C* zQ-~IlGi=8j?8gfB;jb2pOgjj+Ttc*=hVsBE+OUL8cxUF1I7VKk>W?UT4&rxLF0v=rhj_O>TQ#6-sm;{?4q20pzm4B7DsWm zzG~}M)sUKAPsYRQ@={_Y6;~Hl6U!@!p;$VdTGWS?-P#q!vQl!^E}_Ywp6^W7t}43x G+xCBW9dI51 diff --git a/evibes/locale/nl_NL/LC_MESSAGES/django.po b/evibes/locale/nl_NL/LC_MESSAGES/django.po index 78b7d5e3..94a26b9b 100644 --- a/evibes/locale/nl_NL/LC_MESSAGES/django.po +++ b/evibes/locale/nl_NL/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/no_NO/LC_MESSAGES/django.mo b/evibes/locale/no_NO/LC_MESSAGES/django.mo index 4a78bdb1edf1666099f2fe7ad9dc3c79ffeb8859..8caf3868379f4a0614da60816ee970a1e6216b5e 100644 GIT binary patch delta 559 zcmZvYy-EW?5XW~Dy(D)My#zla#&8y*h=f?!NQwk3Ma06|hp@C3Y>orpL$0z2Ruxai!nkrtyxrp@wZ+L1+%p@_0Le;?d30jOyZLxka=j#1qx`G*>4KBXNt!3KX_ z{S4c~?_)>U3v3O`4G?#&DTX2uFNKObpEXeE%D;H@(`9Wrmq{Gz8tHq{7PR`;pN8d< zqA_S*Vo=zCL{BvTs&Y6)*|x5b_JZ1y1?f^Cofu;E(;1&C!yY|&Z%Y(NdqCHkl~&(; ZTz*!+qT)NgFZ1NJS=?+qlzW|n+83DUT(}FL==w|GtI=sGg zvkEVknr_G1bAu#$>QjN6%PwFuFMDO3dqXvG5B@S>XUaEM&OVYIT@p85(;?=VpX zIi$HbMGszM1HPe-<*MJc1OWm)t3 z)_aBU^FNDTd_dLl1Do(ihD}qx3`^=FyJ*2fR2MkLQ7p@SQ!un{{PmEiYV+vAOH{Xc zLUqbdJW1VsylaEyNQ`QDb%` q9!tankz{gdP6qVt+B@<^{kGYt*~GRsD1-WdJnD-5)2q`HsQ(2n@^4Q7 diff --git a/evibes/locale/no_NO/LC_MESSAGES/django.po b/evibes/locale/no_NO/LC_MESSAGES/django.po index d0385347..a6d2f41c 100644 --- a/evibes/locale/no_NO/LC_MESSAGES/django.po +++ b/evibes/locale/no_NO/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/pl_PL/LC_MESSAGES/django.mo b/evibes/locale/pl_PL/LC_MESSAGES/django.mo index 82be2da860ec160a7c703230c24f72bec307f880..be7e7de976d16b5fce011ab8324288a54fc6d337 100644 GIT binary patch delta 581 zcmZvZze)o^5QpcIcrkZkjKn|52~kf-L<@ro+6f02$t*la8%9SE1 zdg^!&A`8xdmOTwT zZE5;>b{08oiY$53V!Y6M)4Zv7;CGLpkg}+F-@ju5P}3lWu){%#r&&+&Kh(erT6_+T zQ5$zOPSFkGA)28VXdR^kM6XpvTjb13N9G|&8#r|2ZJvX^y~mzN*X=_c&HN6sV?FV@ z$c%F#I@nrBTS6z^J9T8PD*Z#Un36Nwd}z;;9{A60TPvR`c}D)Gh+YuHZ?NBh^dg}V sUM;m}6}d+3theYKO0L#@$iu276mh_b#Gd5jB*kIVmX_8!xF{8TF8Ie zAVe+ePZ+?Q3^|56RL@OQ2p8@no5dk|(82+{#1Z_FM~+Zyvhn}wTiD6!0jd)}+Uw6) zLH?A#j&R?0)BnAmk+%?Us7{;1DRc&fsKE%Tvn*o?Zpih5OU-KyJKx>)rWrI7OY@O_ vGddHSi$~0f#aMJM)-jz(#3yB&zLCGeI@f1?`AcZhF2{_8{8iSiap(C1S-o&A diff --git a/evibes/locale/pl_PL/LC_MESSAGES/django.po b/evibes/locale/pl_PL/LC_MESSAGES/django.po index b7090574..7d097514 100644 --- a/evibes/locale/pl_PL/LC_MESSAGES/django.po +++ b/evibes/locale/pl_PL/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/pt_BR/LC_MESSAGES/django.mo b/evibes/locale/pt_BR/LC_MESSAGES/django.mo index e03c7942aa09730e6362067660901597dbf5de9b..0455d4c95beb5c4051df4b4f1fd21be8f5c88987 100644 GIT binary patch delta 607 zcmZva%}T>S5XUEJNoxYu*7`*XRjb5Lq^PK;9(w4(gNS(d348_59>YF>50RsYPf^g5 zC%uYq;BVPsieMo5|K`6lyR*Cbm`o=t->)y7Iv?Q~^7eQM%XWVsnHO0I2DEInW3;8| z*W;@+U`u4lNQ?0j^JaN7@5DyWp@g!uoE|^W0jOyZP59=Z+^A`k{X=tjQJd+|4E6Dv z#shSNc!-YC8?=G40>oOYioPhAw}ISaRGi{0im)|5*0)_lUGt8N4z=<<8u^1=7wH5C zqQuVuX(gnab{BCmVvIgFLl#sw(#_*(ACO)Xv>ozX8K3!XnLy9}59w{;?S*{kQY(Mr o!v7%y5nTz=({Q`B=P0c{YhQ`$AA2WE+xeImE;nuQsONI}sO(clo#;5-u8ILt{0#1($=l1TIlD z)FMR`5q&I11P#(wO_giW(jfg0I(y;pI}i6g?|tv7MBk$B*G_9*@I+YstbL=;>&v$b z(Lp%EUcA5&e8wUCGvafzPBz;vA$rh2b>I+fc#ds&-N+9(L4L+5v{CFde#RGe*r)?1 zNON(D8s4KF-_e29hQHWKHo0kl4piBrvfMOjo&r17sn~dPf-&;ByfOuXTU|mhgUEU7 zgBP%ye2ihd#Snf=k9o#t=t6Xo&X5xK)@0Q@8O(7+U6Ijn57kv3;wWC>JbuZTCE&jE*Lyyq`rnF_mP?bfv}paX4d}XG z&u*+GruF1%DxFE_OY5m*Iu(j%vzcWX*2ZMqvC_P%bmK_5nwQY1*u0|jq_x=p0h&&7 A%K!iX diff --git a/evibes/locale/pt_BR/LC_MESSAGES/django.po b/evibes/locale/pt_BR/LC_MESSAGES/django.po index bb0a89f5..a642a7ab 100644 --- a/evibes/locale/pt_BR/LC_MESSAGES/django.po +++ b/evibes/locale/pt_BR/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/ro_RO/LC_MESSAGES/django.mo b/evibes/locale/ro_RO/LC_MESSAGES/django.mo index a54780653962a251b0f100d409df10cec5438cdf..11f9a1680b3fa6afc1855f5fb23f50fb9874f438 100644 GIT binary patch delta 587 zcmZ{hu}%U(5QgUtJ@77yAc_VOKuj=^#9Yu|M?phJjIlKFO)L%NW#cQ@T3l@`cmfL^ z0b65X@3+~_TqBp;`@i{Tc6WB~W%fL4et*2zxA+K8%4jnPvs&i@*%R4!26Uu!u5{+h zZ>RIvVO8W%$xp_M)GO)=?@F^bP{g!2TaBLR0Q6-LP1xq3mQqD2`G{mzCroCpkDsyNomkZY=F0tjFS@Bnp=~ zj9N+(7jjXYL{20}Tvp`$9@30%~6uVNNor5bZ^nnc0 zTu#uBS6GTK=)`x^Z*-6?9vYw%b*|M}Em-`u8?1DvZF47sBjlVqv$O;jD@7Qx+8|Pe zyQp&x!+5LQ*51I9Ard65qZcob0=Y*YeyKTYN83(7gdtg8#rS~wu8*ky+8c6R`BhKW za46CEzq@9-WqN@6Cdb%`*EobfYPhJy@zM1EHF=dRy0o~m1GZOty#h4P`2&kvaO?m8 diff --git a/evibes/locale/ro_RO/LC_MESSAGES/django.po b/evibes/locale/ro_RO/LC_MESSAGES/django.po index d4a3af57..c96a5a2c 100644 --- a/evibes/locale/ro_RO/LC_MESSAGES/django.po +++ b/evibes/locale/ro_RO/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/ru_RU/LC_MESSAGES/django.mo b/evibes/locale/ru_RU/LC_MESSAGES/django.mo index 29158a758f2d666ff4bc6a613d41e5684a961d48..ce5352dc678ad3a75e954ec694c68ab6e66b4f9f 100644 GIT binary patch delta 627 zcmZvZu}T9$5QgV2dYZeSCPWj75RVfzCK8WW*og$OR0%ezv=B*UVHXQ)%VVFyQc_DE zLVN^mgHNE}y31bU!QKDOKQp^?yFbI(ur`~%Rp$5zPs+Q&OPH0LZDdJg#Td|N{5gEAK64^H%bY@76{I0(7JrOq5 zolwW-Ui?O?r#x+&9R{e5Z&7{C59o=hg+_+dx8KkwVWV>4-3uq5g|9%hHan^sT~D&; Mu}UzV%*W%>FQrhTyZ`_I delta 651 zcmaLUODIH99LMqhHDmNP~2FpPS^A=>Z^(=Zm#H`qeH!&bC0*%AKo_N`Os z1remVoS+M@F$G`HjvsNqF_mm&(*W(LbCJ$!(Qp-QQ|V57@h1@+BA=-%!)-lxiY%!Q zqikWTQly{pH}s;nO2my5sJFg~>9~a~l6@@1)A;x;Hj$rDf0}~>s>Mz$$4S)dH;^sJ zF0y%vU{Iu3Vid~^cxpr%Fp53+s$xl=_I-NMS&p$DA5gcm*8Lxl6ZNlYM12t5s9!Uv zvud{Fr0!7p8F^F#7MJyiYDLXh?hQw@H~HOGYMO2{G&|*MGyM~R;Iz*inF;uVfrhbA gXnIt6>}!cg*o2MK<5Z~y=R diff --git a/evibes/locale/ru_RU/LC_MESSAGES/django.po b/evibes/locale/ru_RU/LC_MESSAGES/django.po index e98e1260..050ad3fc 100644 --- a/evibes/locale/ru_RU/LC_MESSAGES/django.po +++ b/evibes/locale/ru_RU/LC_MESSAGES/django.po @@ -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 `.\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" diff --git a/evibes/locale/sv_SE/LC_MESSAGES/django.mo b/evibes/locale/sv_SE/LC_MESSAGES/django.mo index 14e652c45253066ebbc0442f7108fe8bf17b6f1d..7944343e9720c46bc3e14ce5b9b314f459694385 100644 GIT binary patch delta 619 zcmZvY!AiqG5QZmdNoxYtwrI5#YmJDtr=mikhaO6)H!13)c=oE`B`o*|o`oEX_!J)W zu6PsQz;D@MgJ2-}zxj7&b}~=1$64$9<+)MjBRoUiZC=8x-W?z{ku_&P8=ek5?Q8mC zdLBDm6~K)WQ`J-Q53S$@b=si`YU3@9 zQ?y4sM5pKlT0yx1;;v0aTjb0uN9Ha_$2fH5+Z1Uye@BGCdQjo@y_ahJTQHxH)fH(w z2hy!UIs~MG#6n7= zo->1tE;q4=?+26RcqiZ})Hj@30tMO}W!<)ZN-}1iMlHot3_Lvs88 diff --git a/evibes/locale/sv_SE/LC_MESSAGES/django.po b/evibes/locale/sv_SE/LC_MESSAGES/django.po index fd8febf1..cd42d4c7 100644 --- a/evibes/locale/sv_SE/LC_MESSAGES/django.po +++ b/evibes/locale/sv_SE/LC_MESSAGES/django.po @@ -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 `.\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 `.\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" diff --git a/evibes/locale/th_TH/LC_MESSAGES/django.mo b/evibes/locale/th_TH/LC_MESSAGES/django.mo index 4cdf9be0791c07f1edb52ff6c01f26f6dddc2c8e..e8ef9ea47706dc837d9b1e001df0d672e0b552aa 100644 GIT binary patch delta 639 zcmZvZy-osA5JqPggR-k4_yY!!m?cI;1;j!dDJZOrF~k^cX(X}n2~6xP$*oL$2}5lx zeF8gM>5QSV_AGOAY24)QcjlX!oyp#Z-tSHB=j}B+#Y=b^oHY(%KU1nA^CAmsKr4>6 z9F=YPdHXC-Op7c#vdwr&=S}J+-hs;=LP^?!{zvnk4M1B4u|&KaRB$xoDEx;~cwUCj zp&=T_t2U0%4dMpcMmy*<$^?j6d5dwAniopu(Th?zxv_6vyj+v0DsriL=oYH)h-|9^ z?K+BwQg23HZ4M=IY@Lc<>f-E;^XfT1s);n!gIZ8f7nwy*(Rj`^x~>(FodQ*ymsK)P ze(8ic4R_zrlIEbIqlp*c`THVQ=q5_HR+*7sSk&l__2M7h;W`6TOuT!+;43jqn(wG$ SGGTYn4_kSH&%v<#oc;q^{;Kr= delta 698 zcmaLUPe_w-9LMqRGskGIXUl1sOxrUyqWPyy*FilrWO&>mLc+?!2&qAAIws<&oOnza z4?_=)T?QiJE+ZI&SO*d561!zY)J5nZ6p^3@@%_V{_rQL&noHy+=230fMjO_!6C17k86S|F zIF2@o_58m`e1nPFP(hl@2lU`RUc;a0z~3$Zqn)gE(EuH&a-YiPs^;n2WTrZmT5l>i zL#~-0HUIRdUXfh4NQ9NxkVpuZF^t>z1i#{I3=fM8Vi8C15Pf)RMl2zFlck5GGc#@R zKH9o3@{Y8NC7htKI^zhVsB^$|jHBxL6z||Vs-9&G;sLtxkNMZ)eX}}xbty&cVYQ9} z_@$Lk&`-9EiOk|%RA2EHRaYmUpzbS->aWh=FI+?&A9E+l1gcZhsG*g?eVe6@Jx#C1 zt;e`.\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" @@ -199,9 +199,9 @@ msgstr "" "\n" "## API ที่มีให้บริการ - **REST API:** อินเทอร์เฟซ RESTful แบบเต็มรูปแบบ (เอกสารนี้) - **GraphQL API:** สามารถใช้งานได้ที่ `/graphql/` พร้อมอินเทอร์เฟซ GraphiQL สำหรับการสืบค้นแบบโต้ตอบ ## การยืนยันตัวตน - การยืนยันตัวตนดำเนินการผ่านโทเค็น 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" -" 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 (ป้องกันด้วย basic-auth): `/prometheus/` ## เวอร์ชัน เวอร์ชัน API ปัจจุบัน: {EVIBES_VERSION}\n" diff --git a/evibes/locale/tr_TR/LC_MESSAGES/django.mo b/evibes/locale/tr_TR/LC_MESSAGES/django.mo index df5587a6cd85645da2bcb45c89c5d830616f9d58..323531ae8ce6e3f7a95cbc6742ed10402a5712f1 100644 GIT binary patch delta 636 zcmZvZze)o^5Qp~?y(D*Fj6^SbVvMI?h!(*=2!bh6Xs03;c0Pdk1cF!!Hpf1RTq$DV zGxz`&3Raf3e(Mes0v_!CzWMF!&g|aZ(a&M>{qj6B!DRUQj70`v-e~ubDPyL+0nI6` zE3HcU>F_x6ST|-?NjBq!>W%V7-nOppK_T0s{B7%&4nRqRXu>rIrAk$$_#dj_1r3fv zW7Ng-5@%?KxQ`CeGqi$I0isq*&~5VOxhH!cWHlTrGTX->>7Z?6HvRe-an@hfdoXYp zTBZT-K#7tR#*_Df;uCFN+Fz4$SS{~D z@&ln=$^0s%J(qc%8FPW&pt5s}q@3-RpMt3PD1U}_A>FXe__E03t2)6$@tPh~e*vNV Bri=gp delta 658 zcmaLTPbkA-9LMozHZ#_k|JKj=%_s*u$e-jua^NB^4w5n@t+YvVSSgKiLd}ynky3Km zWeL;L%7q-bh>JfZrMQsPT)dzB&imEV>-qG2pYQWLzn{KnfAK?!Wkc{aGpZSTvC3M{ zMxhW+!U0xb5*zUb>oF7a_x3oLEENe+jxkgl_R)&RSb%3nzQk7Y4R)ZFVn^(&Wnhho z+7L&Yi$m1#9Buf7c6>AZ#(c7=m!s7Z5eGE<#)jFmVJlaFP}zqQ`$4X3N9^RvR>NBbvzhgIk;}Eua{<|z= z4S5T5@d(w+QmF2Gfn|7yb@*YdI|cx^=g}bPJeG=R8S`L`C22~OC3NeE7 zsPe7h3#yYor8J+K9Em~8tJSURUOgO{ne5a9Q^C;eq&_+q41|I{e>gllCVg6y^xMa? VS0&Q+>7wi`.\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 "" "## Kimlik Doğrulama\n" "- Kimlik doğrulama JWT belirteçleri aracılığıyla gerçekleştirilir. Belirteci, isteklerinizin `X-EVIBES-AUTH` başlığına `Bearer ` biçiminde ekleyin.\n" "- Erişim belirteci ömrü {\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" "- Yenileme belirteci ömrü {\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" "} saattir.\n" "- Yenileme belirteçleri, gelişmiş güvenlik için kullanımdan sonra otomatik olarak döndürülür ve geçersiz kılınır.\n" "\n" diff --git a/evibes/locale/vi_VN/LC_MESSAGES/django.mo b/evibes/locale/vi_VN/LC_MESSAGES/django.mo index f1f402c253ab13f27f6dcb7c1ec11525bad4cbae..5e938b3c8b9717f321ba94a96018f5954f566e82 100644 GIT binary patch delta 632 zcmZvZ%SyvQ6oyYyi6#+kyw#F|mliJwN>xyBAy{`7L_~BYLLbDH3zuP5zJM=~m7s`^ zAmStFR$RLC8|N^kU?BOw^XH#ACzF@%L$~(z{4_DdL%7=94Q|RJn_EN1M5@k!W<0HU zYH9qWbDTIF7n$~?i}51w^>cl1+rQm~B93nzx&NHt;ZJ#_1 z^&BD2#qKdc`V|AYCEcSQZuH16ikv$Ky7Xjw9yUdm(JOS+y@7NtNDm+45N&U0)06f# zcj1ox`}|yWApJ^c&*h;DN9H@sWAa*MmA4=%KPsP*`N>yJmiEdbJ*raNmyeB`_!scX Bs!jj^ delta 621 zcmaLTPbkA-9LMoz!@_Ll@2pLJv*pi0@~4QCKR0u55E7A=b{T074$7a%0a;IrlU+m{ zl!iu0BE@YfM`=YlOCrVl$?v>hJ-wdK@ArMa&-47wd{@4_r~LGY;HhJ{7&~EmnLA3(1q*^oyAG^5H6mF2v_>DXkZIz{y_huBMw%L{|o%bJA(Axe0$ zr3q1pN2s>E#db`}T%)~i+5La@C~|0Vs(Xv-K#%(OBvz2Wq~BQEGgmG|A88GT@dZ`y zPLB|kID$F2f@<#ws%sn|HxqHJ$2(NJ{K!vZlY5nauF^KDlOJF!USmK0%7HXz#yqnP zIh*!iu*7=OUrnW&=Fvhkll~ShFdm$k@@s?B!N5eYW;7I<8j@C5wHz^zrLKxyo4ahO POK7y4x*~S$TFUwZ$=h^k diff --git a/evibes/locale/vi_VN/LC_MESSAGES/django.po b/evibes/locale/vi_VN/LC_MESSAGES/django.po index ac7d4f89..e001c9ec 100644 --- a/evibes/locale/vi_VN/LC_MESSAGES/django.po +++ b/evibes/locale/vi_VN/LC_MESSAGES/django.po @@ -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 `.\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" @@ -201,9 +201,9 @@ msgstr "" "\n" "## Các API có sẵn - **REST API:** Giao diện RESTful đầy đủ (tài liệu này) - **GraphQL API:** Có sẵn tại `/graphql/` với giao diện GraphiQL cho các truy vấn tương tác ## Xác thực - Xác thực được xử lý thông qua token JWT. Bao gồm token trong tiêu đề `X-EVIBES-AUTH` của yêu cầu của bạn theo định dạng `Bearer `.\n" "- Thời hạn sử dụng của token truy cập là {\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\"}. - Thời hạn sử dụng của token làm mới là {\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" "} giờ. - Token làm mới được tự động xoay vòng và vô hiệu hóa sau khi sử dụng để tăng cường bảo mật. ## Quốc tế hóa (i18n) - Đặt tiêu đề `Accept-Language` để chỉ định ngôn ngữ ưa thích của bạn (ví dụ: `Accept-Language: en-US`).\n" "- Các ngôn ngữ có sẵn có thể được lấy từ điểm cuối `/app/languages/`. - Tất cả nội dung hiển thị cho người dùng đều hỗ trợ nhiều ngôn ngữ ngay từ đầu. ## Định dạng phản hồi API hỗ trợ nhiều định dạng phản hồi: - **JSON** (mặc định, định dạng camelCase) - **XML** (thêm `?format=xml` hoặc đặt `Accept: application/xml`)\n" "- **YAML** (thêm `?format=yaml` hoặc đặt `Accept: application/x-yaml`) ## Sức khỏe & Giám sát - Kiểm tra sức khỏe: `/health/` - Chỉ số Prometheus (bảo vệ bằng basic-auth): `/prometheus/` ## Phiên bản Phiên bản API hiện tại: {EVIBES_VERSION}\n" diff --git a/evibes/locale/zh_Hans/LC_MESSAGES/django.mo b/evibes/locale/zh_Hans/LC_MESSAGES/django.mo index ef86cd4d02afa7715765b5164a1c1233987b5455..53efaf86fb45b481a5124d02c8ed246392d91ae7 100644 GIT binary patch delta 578 zcmZ{h%SyvQ6ox0M#Af2H1uykhqzXbQ5)^c2pbsD-;>vwrqPP~^gn11&lC|_H#Dyyt ziqM7l27bdFPAF(#@_*+)b1o!5#e1>-J$Y`=@iII)XPZM}$(WU3Kx;~eO8avC za(H0_E*rC|B*l1%diA~9JJIYJlu%~Nm*YD&0OcCQ5`H;oOR1@p{Xr>S)S?}lp+4?N z+(Y+>b99Jaq4OvcAZBd{`l4W72XgmOFU29j+dW06x9E;B3n355(*KZjB-_@CnwakU z*8N-_AD!du>bHet0whysNP6IPW#=-!@xPRC5FAK)K+*$}-CWvui){7L_)OfFeW=Rp TbuqSMH?;@uu`{aj%_8{)`6rwo delta 568 zcmaLTF-QV&6vy%ZnH|+-rBGpJp4iYLA_Ya0(d5t=4bk8r;gE*d(9jUI1d?2bL=dz@ z(U3zHSRyUe&?XH9LDWznP8BUd)b~#}d+_J;es}M^JMJa&9&tXo?0LZz=Ja#+jb5KW z-yuX7;Rt*10*A1QgZOR4CMO&eYn?)Lqk(eZ5LGN;8(v!Z7Dvcc97C06hw(W)wMiid z3dnMCh911a7JNnxYnETwN>-dKKn-Pf%WSSH9``nt+_YysDd04@WLA_w^9If9W=$E5 zX1zkRbAJcr7aUj~Tb`oaTt*jOTRtEwMIGh*kGWzCg>wV{KVlct>L{l^P`>-uTxfb!9L1>pP4((}K+h~M#>e%$6MAL@F7K eWishGGo)o3cNELoy`yo9x#i9^?kM{EBI+Lsmu?6E diff --git a/evibes/locale/zh_Hans/LC_MESSAGES/django.po b/evibes/locale/zh_Hans/LC_MESSAGES/django.po index 0653ba03..45baf191 100644 --- a/evibes/locale/zh_Hans/LC_MESSAGES/django.po +++ b/evibes/locale/zh_Hans/LC_MESSAGES/django.po @@ -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 `.\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 `。\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" diff --git a/evibes/pagination.py b/evibes/pagination.py index 0a509595..ad0376cb 100644 --- a/evibes/pagination.py +++ b/evibes/pagination.py @@ -17,9 +17,9 @@ class CustomPagination(PageNumberPagination): "backward": self.get_previous_link(), }, "counts": { - "total_pages": None or self.page.paginator.num_pages, # type: ignore [union-attr] + "total_pages": None or self.page.paginator.num_pages, "page_size": None or self.page_size, - "total_items": None or self.page.paginator.count, # type: ignore [union-attr] + "total_items": None or self.page.paginator.count, }, "data": data, } diff --git a/evibes/settings/base.py b/evibes/settings/base.py index 15c94f21..4b062315 100644 --- a/evibes/settings/base.py +++ b/evibes/settings/base.py @@ -348,7 +348,7 @@ LANGUAGE_URL_OVERRIDES: dict[str, str] = { code.split("-")[0]: code for code, _ in LANGUAGES if "-" in code } -CURRENCY_CODE: str = dict(CURRENCIES_BY_LANGUAGES).get(LANGUAGE_CODE) # type: ignore[assignment] +CURRENCY_CODE: str = dict(CURRENCIES_BY_LANGUAGES).get(LANGUAGE_CODE) MODELTRANSLATION_FALLBACK_LANGUAGES: tuple[str, ...] = (LANGUAGE_CODE, "en-us", "de-de") @@ -435,7 +435,7 @@ if getenv("SENTRY_DSN"): request = event.get("request", {}) data = request.get("data", {}) if data: - request["data"] = scrub_sensitive(data) # type: ignore [arg-type] + request["data"] = scrub_sensitive(data) event["request"] = request return event diff --git a/evibes/settings/drf.py b/evibes/settings/drf.py index 9bfcdec7..d67eceb4 100644 --- a/evibes/settings/drf.py +++ b/evibes/settings/drf.py @@ -11,6 +11,11 @@ from evibes.settings.base import ( SECRET_KEY, ) +JSON_CAMEL_CASE = { + "RENDERER_CLASS": "drf_orjson_renderer.renderers.ORJSONRenderer", + "PARSER_CLASS": "drf_orjson_renderer.parsers.ORJSONParser", +} + REST_FRAMEWORK: dict[str, str | int | list[str] | tuple[str, ...] | dict[str, bool]] = { "DEFAULT_PAGINATION_CLASS": "evibes.pagination.CustomPagination", "PAGE_SIZE": 30, @@ -22,12 +27,12 @@ REST_FRAMEWORK: dict[str, str | int | list[str] | tuple[str, ...] | dict[str, bo "rest_framework.renderers.MultiPartRenderer", "rest_framework_xml.renderers.XMLRenderer", "rest_framework_yaml.renderers.YAMLRenderer", + "djangorestframework_camel_case.render.CamelCaseBrowsableAPIRenderer", ), "DEFAULT_PARSER_CLASSES": ( "djangorestframework_camel_case.parser.CamelCaseJSONParser", "djangorestframework_camel_case.parser.CamelCaseMultiPartParser", - "rest_framework.parsers.FormParser", - "rest_framework.parsers.MultiPartParser", + "djangorestframework_camel_case.parser.CamelCaseFormParser", "rest_framework_xml.parsers.XMLParser", "rest_framework_yaml.parsers.YAMLParser", ), @@ -39,9 +44,7 @@ REST_FRAMEWORK: dict[str, str | int | list[str] | tuple[str, ...] | dict[str, bo } SIMPLE_JWT: dict[str, timedelta | str | bool] = { - "ACCESS_TOKEN_LIFETIME": timedelta(hours=8) - if not DEBUG # noqa: F405 - else timedelta(hours=88), + "ACCESS_TOKEN_LIFETIME": timedelta(hours=8) if not DEBUG else timedelta(hours=88), "REFRESH_TOKEN_LIFETIME": timedelta(days=8), "ROTATE_REFRESH_TOKENS": True, "BLACKLIST_AFTER_ROTATION": True, @@ -76,10 +79,10 @@ eVibes is a powerful e-commerce platform that allows you to launch and manage an ## Authentication - Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer `. - Access token lifetime is { - SIMPLE_JWT.get("ACCESS_TOKEN_LIFETIME").total_seconds() // 60 if not DEBUG else 3600 # type: ignore [union-attr] + SIMPLE_JWT.get("ACCESS_TOKEN_LIFETIME").total_seconds() // 60 if not DEBUG else 3600 } {"minutes" if not DEBUG else "hours"}. - Refresh token lifetime is { - SIMPLE_JWT.get("REFRESH_TOKEN_LIFETIME").total_seconds() // 3600 # type: ignore [union-attr] + SIMPLE_JWT.get("REFRESH_TOKEN_LIFETIME").total_seconds() // 3600 } hours. - Refresh tokens are automatically rotated and invalidated after usage for enhanced security. @@ -104,7 +107,7 @@ Current API version: {EVIBES_VERSION} SPECTACULAR_SETTINGS = { "DEFAULT_GENERATOR_CLASS": "drf_spectacular_websocket.schemas.WsSchemaGenerator", - "TITLE": f"{PROJECT_NAME} API", # type: ignore [index] + "TITLE": f"{PROJECT_NAME} API", "DESCRIPTION": SPECTACULAR_DESCRIPTION, "VERSION": EVIBES_VERSION, # noqa: F405 "TOS": "https://evibes.wiseless.xyz/terms-of-service", @@ -124,7 +127,7 @@ SPECTACULAR_SETTINGS = { }, "SERVERS": [ { - "url": f"https://api.{BASE_DOMAIN}/", # type: ignore [index] + "url": f"https://api.{BASE_DOMAIN}/", "description": "Production Server", }, {"url": "http://api.localhost:8000/", "description": "Development Server"}, diff --git a/pyproject.toml b/pyproject.toml index 0d48cc86..f04df32d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,27 +14,27 @@ dependencies = [ "coverage==7.13.0", "click==8.3.1", "cryptography==46.0.3", - "django==5.2.8", + "django==5.2.9", "django-cacheops==7.2", "django-constance==4.3.4", "django-cors-headers==4.9.0", - "django-dbbackup==5.0.1", + "django-dbbackup==5.1.0", "django-elasticsearch-dsl==8.2", "django-extensions==4.1", "django-filter==25.2", "django-health-check==3.20.0", "django-import-export[all]>=4.3.14", - "django-json-widget==2.1.0", + "django-json-widget==2.1.1", "django-mailbox==4.10.1", "django-model-utils==5.0.0", - "django-modeltranslation==0.19.17", + "django-modeltranslation==0.19.19", "django-mptt==0.18.0", "django-prometheus==2.4.1", "django-redis==6.0.0", "django-ratelimit==4.1.0", "django-storages==1.14.6", "django-summernote==0.8.20.0", - "django-unfold==0.73.1", + "django-unfold==0.74.1", "django-unfold-markdown==0.1.2", "django-widget-tweaks==1.5.0", "django-md-field==0.1.0", @@ -48,8 +48,9 @@ dependencies = [ "docutils==0.22.3", "drf-spectacular[sidecar]==0.29.0", "drf-spectacular-websocket>=1.3.1", + "drf-orjson-renderer>=1.8.0", "elasticsearch-dsl==8.18.0", - "filelock==3.20.0", + "filelock==3.20.1", "filetype==1.2.0", "graphene-django==3.2.3", "graphene-file-upload==1.3.0", @@ -65,10 +66,10 @@ dependencies = [ "python-slugify==8.0.4", "psutil==7.1.3", "psycopg2==2.9.11", - "pymdown-extensions==10.18", + "pymdown-extensions==10.19.1", "redis==7.1.0", "requests==2.32.5", - "sentry-sdk[django,celery,opentelemetry]==2.47.0", + "sentry-sdk[django,celery,opentelemetry]==2.48.0", "six==1.17.0", "swapper==1.4.0", "uvicorn==0.38.0", @@ -88,10 +89,19 @@ worker = [ linting = [ "ruff==0.14.9", "basedpyright>=1.36.1", - "pyright==1.1.387", + "pyright==1.1.407", "celery-types>=0.23.0", + "django-stubs==5.2.8", + "djangorestframework-stubs==3.16.6", + "types-requests==2.32.4.20250913", + "types-redis==4.6.0.20241004", + "types-paramiko==4.0.0.20250822", + "types-psutil==7.1.3.20251211", + "types-pillow==10.2.0.20240822", + "types-docutils==0.22.3.20251115", + "types-six==1.17.0.20251009", ] -openai = ["openai==2.12.0"] +openai = ["openai==2.13.0"] jupyter = ["jupyter==1.1.1"] [tool.uv] @@ -115,3 +125,22 @@ known-first-party = ["evibes", "engine"] [tool.ruff.format] quote-style = "double" indent-style = "space" + +[tool.pyright] +typeCheckingMode = "strict" +pythonVersion = "3.12" +useLibraryCodeForTypes = true +reportMissingTypeStubs = "none" +exclude = [ + "**/__pycache__/**", + "**/.venv/**", + "**/.uv/**", + "media/**", + "static/**", + "storefront/**", + "**/migrations/**", +] +extraPaths = ["./evibes", "./engine"] + +[tool.django-stubs] +django_settings_module = "evibes.settings" \ No newline at end of file diff --git a/pyrightconfig.json b/pyrightconfig.json deleted file mode 100644 index 591101b0..00000000 --- a/pyrightconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/microsoft/pyright/main/packages/pyright/schema/pyrightconfig.schema.json", - "typeCheckingMode": "strict", - "pythonVersion": "3.12", - "useLibraryCodeForTypes": true, - "reportMissingTypeStubs": "warning", - "exclude": [ - "**/__pycache__/**", - "**/.venv/**", - "**/.uv/**", - "media/**", - "static/**", - "storefront/**", - "**/migrations/**" - ], - "executionEnvironments": [ - { - "root": "./", - "pythonVersion": "3.12", - "extraPaths": ["./evibes", "./engine"] - } - ] -} diff --git a/uv.lock b/uv.lock index f3bffb9c..0f37be72 100644 --- a/uv.lock +++ b/uv.lock @@ -699,19 +699,19 @@ wheels = [ [[package]] name = "debugpy" -version = "1.8.18" +version = "1.8.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/62/1a/7cb5531840d7ba5d9329644109e62adee41f2f0083d9f8a4039f01de58cf/debugpy-1.8.18.tar.gz", hash = "sha256:02551b1b84a91faadd2db9bc4948873f2398190c95b3cc6f97dc706f43e8c433", size = 1644467, upload-time = "2025-12-10T19:48:07.236Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/75/9e12d4d42349b817cd545b89247696c67917aab907012ae5b64bbfea3199/debugpy-1.8.19.tar.gz", hash = "sha256:eea7e5987445ab0b5ed258093722d5ecb8bb72217c5c9b1e21f64efe23ddebdb", size = 1644590, upload-time = "2025-12-15T21:53:28.044Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/01/439626e3572a33ac543f25bc1dac1e80bc01c7ce83f3c24dc4441302ca13/debugpy-1.8.18-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:530c38114725505a7e4ea95328dbc24aabb9be708c6570623c8163412e6d1d6b", size = 2549961, upload-time = "2025-12-10T19:48:21.73Z" }, - { url = "https://files.pythonhosted.org/packages/cd/73/1eeaa15c20a2b627be57a65bc1ebf2edd8d896950eac323588b127d776f2/debugpy-1.8.18-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:a114865099283cbed4c9330cb0c9cb7a04cfa92e803577843657302d526141ec", size = 4309855, upload-time = "2025-12-10T19:48:23.41Z" }, - { url = "https://files.pythonhosted.org/packages/e4/6f/2da8ded21ae55df7067e57bd7f67ffed7e08b634f29bdba30c03d3f19918/debugpy-1.8.18-cp312-cp312-win32.whl", hash = "sha256:4d26736dfabf404e9f3032015ec7b0189e7396d0664e29e5bdbe7ac453043c95", size = 5280577, upload-time = "2025-12-10T19:48:25.386Z" }, - { url = "https://files.pythonhosted.org/packages/f5/8e/ebe887218c5b84f9421de7eb7bb7cdf196e84535c3f504a562219297d755/debugpy-1.8.18-cp312-cp312-win_amd64.whl", hash = "sha256:7e68ba950acbcf95ee862210133681f408cbb78d1c9badbb515230ec55ed6487", size = 5322458, upload-time = "2025-12-10T19:48:28.049Z" }, - { url = "https://files.pythonhosted.org/packages/fe/3f/45af037e91e308274a092eb6a86282865fb1f11148cdb7616e811aae33d7/debugpy-1.8.18-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:75d14dd04b617ee38e46786394ec0dd5e1ac5e3d10ffb034fd6c7b72111174c2", size = 2538826, upload-time = "2025-12-10T19:48:29.434Z" }, - { url = "https://files.pythonhosted.org/packages/cc/f4/2de6bf624de05134d1bbe0a8750d484363cd212c3ade3d04f5c77d47d0ce/debugpy-1.8.18-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:1b224887af5121fa702f9f542968170d104e3f9cac827d85fdefe89702dc235c", size = 4292542, upload-time = "2025-12-10T19:48:30.836Z" }, - { url = "https://files.pythonhosted.org/packages/93/54/89de7ef84d5ac39fc64a773feaedd902536cc5295814cd22d19c6d9dea35/debugpy-1.8.18-cp313-cp313-win32.whl", hash = "sha256:636a5445a3336e4aba323a3545ca2bb373b04b0bc14084a4eb20c989db44429f", size = 5280460, upload-time = "2025-12-10T19:48:32.696Z" }, - { url = "https://files.pythonhosted.org/packages/4f/59/651329e618406229edbef6508a5aa05e43cd027f042740c5b27e46854b23/debugpy-1.8.18-cp313-cp313-win_amd64.whl", hash = "sha256:6da217ac8c1152d698b9809484d50c75bef9cc02fd6886a893a6df81ec952ff8", size = 5322399, upload-time = "2025-12-10T19:48:35.057Z" }, - { url = "https://files.pythonhosted.org/packages/dc/0d/bf7ac329c132436c57124202b5b5ccd6366e5d8e75eeb184cf078c826e8d/debugpy-1.8.18-py2.py3-none-any.whl", hash = "sha256:ab8cf0abe0fe2dfe1f7e65abc04b1db8740f9be80c1274acb625855c5c3ece6e", size = 5286576, upload-time = "2025-12-10T19:48:56.071Z" }, + { url = "https://files.pythonhosted.org/packages/4a/15/d762e5263d9e25b763b78be72dc084c7a32113a0bac119e2f7acae7700ed/debugpy-1.8.19-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:bccb1540a49cde77edc7ce7d9d075c1dbeb2414751bc0048c7a11e1b597a4c2e", size = 2549995, upload-time = "2025-12-15T21:53:43.773Z" }, + { url = "https://files.pythonhosted.org/packages/a7/88/f7d25c68b18873b7c53d7c156ca7a7ffd8e77073aa0eac170a9b679cf786/debugpy-1.8.19-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:e9c68d9a382ec754dc05ed1d1b4ed5bd824b9f7c1a8cd1083adb84b3c93501de", size = 4309891, upload-time = "2025-12-15T21:53:45.26Z" }, + { url = "https://files.pythonhosted.org/packages/c5/4f/a65e973aba3865794da65f71971dca01ae66666132c7b2647182d5be0c5f/debugpy-1.8.19-cp312-cp312-win32.whl", hash = "sha256:6599cab8a783d1496ae9984c52cb13b7c4a3bd06a8e6c33446832a5d97ce0bee", size = 5286355, upload-time = "2025-12-15T21:53:46.763Z" }, + { url = "https://files.pythonhosted.org/packages/d8/3a/d3d8b48fec96e3d824e404bf428276fb8419dfa766f78f10b08da1cb2986/debugpy-1.8.19-cp312-cp312-win_amd64.whl", hash = "sha256:66e3d2fd8f2035a8f111eb127fa508469dfa40928a89b460b41fd988684dc83d", size = 5328239, upload-time = "2025-12-15T21:53:48.868Z" }, + { url = "https://files.pythonhosted.org/packages/71/3d/388035a31a59c26f1ecc8d86af607d0c42e20ef80074147cd07b180c4349/debugpy-1.8.19-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:91e35db2672a0abaf325f4868fcac9c1674a0d9ad9bb8a8c849c03a5ebba3e6d", size = 2538859, upload-time = "2025-12-15T21:53:50.478Z" }, + { url = "https://files.pythonhosted.org/packages/4a/19/c93a0772d0962294f083dbdb113af1a7427bb632d36e5314297068f55db7/debugpy-1.8.19-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:85016a73ab84dea1c1f1dcd88ec692993bcbe4532d1b49ecb5f3c688ae50c606", size = 4292575, upload-time = "2025-12-15T21:53:51.821Z" }, + { url = "https://files.pythonhosted.org/packages/5c/56/09e48ab796b0a77e3d7dc250f95251832b8bf6838c9632f6100c98bdf426/debugpy-1.8.19-cp313-cp313-win32.whl", hash = "sha256:b605f17e89ba0ecee994391194285fada89cee111cfcd29d6f2ee11cbdc40976", size = 5286209, upload-time = "2025-12-15T21:53:53.602Z" }, + { url = "https://files.pythonhosted.org/packages/fb/4e/931480b9552c7d0feebe40c73725dd7703dcc578ba9efc14fe0e6d31cfd1/debugpy-1.8.19-cp313-cp313-win_amd64.whl", hash = "sha256:c30639998a9f9cd9699b4b621942c0179a6527f083c72351f95c6ab1728d5b73", size = 5328206, upload-time = "2025-12-15T21:53:55.433Z" }, + { url = "https://files.pythonhosted.org/packages/25/3e/e27078370414ef35fafad2c06d182110073daaeb5d3bf734b0b1eeefe452/debugpy-1.8.19-py2.py3-none-any.whl", hash = "sha256:360ffd231a780abbc414ba0f005dad409e71c78637efe8f2bd75837132a41d38", size = 5292321, upload-time = "2025-12-15T21:54:16.024Z" }, ] [[package]] @@ -752,16 +752,16 @@ wheels = [ [[package]] name = "django" -version = "5.2.8" +version = "5.2.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "asgiref" }, { name = "sqlparse" }, { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/a2/933dbbb3dd9990494960f6e64aca2af4c0745b63b7113f59a822df92329e/django-5.2.8.tar.gz", hash = "sha256:23254866a5bb9a2cfa6004e8b809ec6246eba4b58a7589bc2772f1bcc8456c7f", size = 10849032, upload-time = "2025-11-05T14:07:32.778Z" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/1c/188ce85ee380f714b704283013434976df8d3a2df8e735221a02605b6794/django-5.2.9.tar.gz", hash = "sha256:16b5ccfc5e8c27e6c0561af551d2ea32852d7352c67d452ae3e76b4f6b2ca495", size = 10848762, upload-time = "2025-12-02T14:01:08.418Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/3d/a035a4ee9b1d4d4beee2ae6e8e12fe6dee5514b21f62504e22efcbd9fb46/django-5.2.8-py3-none-any.whl", hash = "sha256:37e687f7bd73ddf043e2b6b97cfe02fcbb11f2dbb3adccc6a2b18c6daa054d7f", size = 8289692, upload-time = "2025-11-05T14:07:28.761Z" }, + { url = "https://files.pythonhosted.org/packages/17/b0/7f42bfc38b8f19b78546d47147e083ed06e12fc29c42da95655e0962c6c2/django-5.2.9-py3-none-any.whl", hash = "sha256:3a4ea88a70370557ab1930b332fd2887a9f48654261cdffda663fef5976bb00a", size = 8290652, upload-time = "2025-12-02T14:01:03.485Z" }, ] [[package]] @@ -832,14 +832,14 @@ wheels = [ [[package]] name = "django-dbbackup" -version = "5.0.1" +version = "5.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1e/c8/e8d0352f3b5f6f3a0b12ea56a47fc9808aa1bb8753f6d362b7acadec72c6/django_dbbackup-5.0.1.tar.gz", hash = "sha256:52e1ed0c8082eb29b2e96231db0101a47a34442176542c27659992918ae9ef2a", size = 25316, upload-time = "2025-11-07T11:05:05.679Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/97/0504a820ea4a3550386fdfb73d7808d3458e4882d33f0b7cef23439d3b4a/django_dbbackup-5.1.0.tar.gz", hash = "sha256:66c236bbfa0c9bda33a61d30be8c5961d70fa73fed2fe7f829559ac216354130", size = 26361, upload-time = "2025-12-17T13:23:12.072Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/b1/b0bbab8cf34fb8ca09f19d054b1c44f061b5188f4aa40cc6b274de566ac1/django_dbbackup-5.0.1-py3-none-any.whl", hash = "sha256:5f9f764fcd9be3c7d6acde31ad3a20ec9093fc42014cd3e84e71eae9201d675f", size = 33403, upload-time = "2025-11-07T11:05:04.265Z" }, + { url = "https://files.pythonhosted.org/packages/da/a3/62fc9ecb4222fffdb1a56f187888c4e237edb763dbafc64677115d0788d7/django_dbbackup-5.1.0-py3-none-any.whl", hash = "sha256:611291606bf6a80903733a99235963e65236c23bca26c2edca453b928b504c67", size = 34612, upload-time = "2025-12-17T13:23:10.538Z" }, ] [[package]] @@ -924,11 +924,11 @@ wheels = [ [[package]] name = "django-json-widget" -version = "2.1.0" +version = "2.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/84/db3338004d664cad952119a44254987fe23805243b167c5211aa52c0f5e4/django_json_widget-2.1.0.tar.gz", hash = "sha256:0f040b8b329d5032dc1136cf50c01dc7563a07b8f0c3f5324b9051bc3e6eaa83", size = 383610, upload-time = "2025-10-24T15:12:16.258Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/30/923ff229ee284bf2fac7a289ca446fb2725d94b2a34c7cb006c4f811e6c0/django_json_widget-2.1.1.tar.gz", hash = "sha256:dc8102e2fa9accd0f661ea1988c9389f8fbbcb8a4bb9cbfb8fa0525b3c1265c1", size = 384026, upload-time = "2025-12-12T11:22:05.953Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/c5/313336b98874ae1e8776e62777a75ce0c97ab47b66475bc7979f2e7176b4/django_json_widget-2.1.0-py2.py3-none-any.whl", hash = "sha256:fc30781292000c745449632d0f2d6ddd8f2415172664ae9fad42f1cd407a5612", size = 293397, upload-time = "2025-10-24T15:12:13.209Z" }, + { url = "https://files.pythonhosted.org/packages/19/6a/bdbcc079d11d312e463565819089fe83ae6c7f17f274effa4777ca069f64/django_json_widget-2.1.1-py2.py3-none-any.whl", hash = "sha256:2fa3d6fb6dba9436a29ad2cee23fa794381f54a6678ec7d74e990ae081d9800b", size = 293721, upload-time = "2025-12-12T11:22:04.195Z" }, ] [[package]] @@ -963,14 +963,15 @@ wheels = [ [[package]] name = "django-modeltranslation" -version = "0.19.17" +version = "0.19.19" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a7/32/34f33d0a375087197e1e7b6e27a87332c3dfaa970cb38ec353b6198b855b/django_modeltranslation-0.19.17.tar.gz", hash = "sha256:13bd9cab4e4aed0bef5624c17a7da2ac8c5538f0650adbd89ce8c878cbef02fd", size = 77741, upload-time = "2025-09-14T10:14:36.05Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/af/3c34fca94fccae681a15734bc6557cf9be958d1d063ddbb233580b894054/django_modeltranslation-0.19.19.tar.gz", hash = "sha256:26dd8454f19540a2eb05e303608a2d89dd80aacb75ab95f8ea272cf4324d2644", size = 77750, upload-time = "2025-12-15T10:25:38.112Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/87/f8cf0626e502fd6fd996b8dc590985ed5002b63dfb4442f954670bd101b7/django_modeltranslation-0.19.17-py3-none-any.whl", hash = "sha256:fda198c08b4ede0c2fd09b795ab420a04c7b5a868315fdf4aade0d0a526c269f", size = 93423, upload-time = "2025-09-14T10:14:34.536Z" }, + { url = "https://files.pythonhosted.org/packages/a7/2a/fdf265e91e37ee363b2c45f3d2a01752a3b38ab082a3ec0b0677105bd367/django_modeltranslation-0.19.19-py3-none-any.whl", hash = "sha256:55ac2ce47486b9e8ca18b155f7705170a53b7e1346bf7bf89304e99787486e8f", size = 93441, upload-time = "2025-12-15T10:25:35.942Z" }, ] [[package]] @@ -1032,6 +1033,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1f/21/3cedee63417bc5553eed0c204be478071c9ab208e5e259e97287590194f1/django_storages-1.14.6-py3-none-any.whl", hash = "sha256:11b7b6200e1cb5ffcd9962bd3673a39c7d6a6109e8096f0e03d46fab3d3aabd9", size = 33095, upload-time = "2025-04-02T02:34:53.291Z" }, ] +[[package]] +name = "django-stubs" +version = "5.2.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, + { name = "django-stubs-ext" }, + { name = "types-pyyaml" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6c/75/97626224fd8f1787bb6f7f06944efcfddd5da7764bf741cf7f59d102f4a0/django_stubs-5.2.8.tar.gz", hash = "sha256:9bba597c9a8ed8c025cae4696803d5c8be1cf55bfc7648a084cbf864187e2f8b", size = 257709, upload-time = "2025-12-01T08:13:09.569Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/3f/7c9543ad5ade5ce1d33d187a3abd82164570314ebee72c6206ab5c044ebf/django_stubs-5.2.8-py3-none-any.whl", hash = "sha256:a3c63119fd7062ac63d58869698d07c9e5ec0561295c4e700317c54e8d26716c", size = 508136, upload-time = "2025-12-01T08:13:07.963Z" }, +] + +[[package]] +name = "django-stubs-ext" +version = "5.2.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/14/a2/d67f4a5200ff7626b104eddceaf529761cba4ed318a73ffdb0677551be73/django_stubs_ext-5.2.8.tar.gz", hash = "sha256:b39938c46d7a547cd84e4a6378dbe51a3dd64d70300459087229e5fee27e5c6b", size = 6487, upload-time = "2025-12-01T08:12:37.486Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/2d/cb0151b780c3730cf0f2c0fcb1b065a5e88f877cf7a9217483c375353af1/django_stubs_ext-5.2.8-py3-none-any.whl", hash = "sha256:1dd5470c9675591362c78a157a3cf8aec45d0e7a7f0cf32f227a1363e54e0652", size = 9949, upload-time = "2025-12-01T08:12:36.397Z" }, +] + [[package]] name = "django-summernote" version = "0.8.20.0" @@ -1056,14 +1085,14 @@ wheels = [ [[package]] name = "django-unfold" -version = "0.73.1" +version = "0.74.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/80/fb57c7016a784f86ab5e73a7e843941daad9feea1d44b31a8f40f24d190e/django_unfold-0.73.1.tar.gz", hash = "sha256:2c1bbf24d2fc162fe5d0e19b27c1f8287fdd5343b1ffe2b78ee26586ed1a4837", size = 1103069, upload-time = "2025-12-09T09:11:29.087Z" } +sdist = { url = "https://files.pythonhosted.org/packages/78/88/d98c21ed315e5cb025f45aaea1e95d35c0fd11fb9123cb4c1278c33e70ad/django_unfold-0.74.1.tar.gz", hash = "sha256:573f793f975b9dbe324859121a179ae3f4d600d580e28e038736d7a2696e86dc", size = 1103394, upload-time = "2025-12-15T17:06:36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/79/89/4d5716871f9c7aea6c2a567ac297380efa870c4641641a87b45a7b8587c0/django_unfold-0.73.1-py3-none-any.whl", hash = "sha256:7241275b75f0784a28410afa6bb4660f427eb7b62d48726195b35374887f017d", size = 1216980, upload-time = "2025-12-09T09:11:27.761Z" }, + { url = "https://files.pythonhosted.org/packages/2d/21/1c5482019bf2b454ac3e67cf0de456eb3dccc2f478a865a2f8a4fba28ef7/django_unfold-0.74.1-py3-none-any.whl", hash = "sha256:0b0a4b13c568309f3bb0a14d5bd7353b47b676d97695954d9631245df84e18f3", size = 1217338, upload-time = "2025-12-15T17:06:34.418Z" }, ] [[package]] @@ -1149,6 +1178,22 @@ crypto = [ { name = "cryptography" }, ] +[[package]] +name = "djangorestframework-stubs" +version = "3.16.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django-stubs" }, + { name = "requests" }, + { name = "types-pyyaml" }, + { name = "types-requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/ed/6e16dbe8e79af9d2cdbcbd89553e59d18ecab7e9820ebb751085fc29fc0e/djangorestframework_stubs-3.16.6.tar.gz", hash = "sha256:b8d3e73604280f69c628ff7900f0e84703d9ff47cd050fccb5f751438e4c5813", size = 32274, upload-time = "2025-12-03T22:26:23.238Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/e3/d75f9e06d13d7fe8ed25473627c277992b7fad80747a4eaa1c7faa97e09e/djangorestframework_stubs-3.16.6-py3-none-any.whl", hash = "sha256:9bf2e5c83478edca3b8eb5ffd673737243ade16ce4b47b633a4ea62fe6924331", size = 56506, upload-time = "2025-12-03T22:26:21.88Z" }, +] + [[package]] name = "djangorestframework-xml" version = "2.0.0" @@ -1182,6 +1227,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/11/a8/c6a4b901d17399c77cd81fb001ce8961e9f5e04d3daf27e8925cb012e163/docutils-0.22.3-py3-none-any.whl", hash = "sha256:bd772e4aca73aff037958d44f2be5229ded4c09927fcf8690c577b66234d6ceb", size = 633032, upload-time = "2025-11-06T02:35:52.391Z" }, ] +[[package]] +name = "drf-orjson-renderer" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, + { name = "djangorestframework" }, + { name = "orjson" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b4/2d/97e1d2f2db68c7893b08295e8d4125da000985d6ad8b73f148a60fa599fe/drf_orjson_renderer-1.8.0.tar.gz", hash = "sha256:0cd506cc13471526b7ea679d56b7a346f033fab2103c9fa10f6d7c6fa60b6d22", size = 9650, upload-time = "2025-12-17T18:35:22.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/1a/8dab7b29cd33f94b927fba554ba4dfc4483f8e215e0e3ecaea88bdc045cb/drf_orjson_renderer-1.8.0-py3-none-any.whl", hash = "sha256:386ef0feda21147a490886a233b34b2ec0baf874a1de07e689aa8bc264c9baff", size = 7704, upload-time = "2025-12-17T18:35:21.085Z" }, +] + [[package]] name = "drf-spectacular" version = "0.29.0" @@ -1328,6 +1387,7 @@ dependencies = [ { name = "djangorestframework-xml" }, { name = "djangorestframework-yaml" }, { name = "docutils" }, + { name = "drf-orjson-renderer" }, { name = "drf-spectacular", extra = ["sidecar"] }, { name = "drf-spectacular-websocket" }, { name = "elasticsearch-dsl" }, @@ -1369,8 +1429,17 @@ jupyter = [ linting = [ { name = "basedpyright" }, { name = "celery-types" }, + { name = "django-stubs" }, + { name = "djangorestframework-stubs" }, { name = "pyright" }, { name = "ruff" }, + { name = "types-docutils" }, + { name = "types-paramiko" }, + { name = "types-pillow" }, + { name = "types-psutil" }, + { name = "types-redis" }, + { name = "types-requests" }, + { name = "types-six" }, ] openai = [ { name = "openai" }, @@ -1396,30 +1465,31 @@ requires-dist = [ { name = "colorlog", specifier = "==6.10.1" }, { name = "coverage", specifier = "==7.13.0" }, { name = "cryptography", specifier = "==46.0.3" }, - { name = "django", specifier = "==5.2.8" }, + { name = "django", specifier = "==5.2.9" }, { name = "django-cacheops", specifier = "==7.2" }, { name = "django-celery-beat", marker = "extra == 'worker'", specifier = "==2.8.1" }, { name = "django-celery-results", marker = "extra == 'worker'", specifier = "==2.6.0" }, { name = "django-constance", specifier = "==4.3.4" }, { name = "django-cors-headers", specifier = "==4.9.0" }, - { name = "django-dbbackup", specifier = "==5.0.1" }, + { name = "django-dbbackup", specifier = "==5.1.0" }, { name = "django-elasticsearch-dsl", specifier = "==8.2" }, { name = "django-extensions", specifier = "==4.1" }, { name = "django-filter", specifier = "==25.2" }, { name = "django-health-check", specifier = "==3.20.0" }, { name = "django-import-export", extras = ["all"], specifier = ">=4.3.14" }, - { name = "django-json-widget", specifier = "==2.1.0" }, + { name = "django-json-widget", specifier = "==2.1.1" }, { name = "django-mailbox", specifier = "==4.10.1" }, { name = "django-md-field", specifier = "==0.1.0" }, { name = "django-model-utils", specifier = "==5.0.0" }, - { name = "django-modeltranslation", specifier = "==0.19.17" }, + { name = "django-modeltranslation", specifier = "==0.19.19" }, { name = "django-mptt", specifier = "==0.18.0" }, { name = "django-prometheus", specifier = "==2.4.1" }, { name = "django-ratelimit", specifier = "==4.1.0" }, { name = "django-redis", specifier = "==6.0.0" }, { name = "django-storages", specifier = "==1.14.6" }, + { name = "django-stubs", marker = "extra == 'linting'", specifier = "==5.2.8" }, { name = "django-summernote", specifier = "==0.8.20.0" }, - { name = "django-unfold", specifier = "==0.73.1" }, + { name = "django-unfold", specifier = "==0.74.1" }, { name = "django-unfold-markdown", specifier = "==0.1.2" }, { name = "django-widget-tweaks", specifier = "==1.5.0" }, { name = "djangoql", specifier = "==0.18.1" }, @@ -1427,20 +1497,22 @@ requires-dist = [ { name = "djangorestframework-camel-case", specifier = "==1.4.2" }, { name = "djangorestframework-recursive", specifier = "==0.1.2" }, { name = "djangorestframework-simplejwt", extras = ["crypto"], specifier = "==5.5.1" }, + { name = "djangorestframework-stubs", marker = "extra == 'linting'", specifier = "==3.16.6" }, { name = "djangorestframework-xml", specifier = "==2.0.0" }, { name = "djangorestframework-yaml", specifier = "==2.0.0" }, { name = "docutils", specifier = "==0.22.3" }, + { name = "drf-orjson-renderer", specifier = ">=1.8.0" }, { name = "drf-spectacular", extras = ["sidecar"], specifier = "==0.29.0" }, { name = "drf-spectacular-websocket", specifier = ">=1.3.1" }, { name = "elasticsearch-dsl", specifier = "==8.18.0" }, - { name = "filelock", specifier = "==3.20.0" }, + { name = "filelock", specifier = "==3.20.1" }, { name = "filetype", specifier = "==1.2.0" }, { name = "graphene-django", specifier = "==3.2.3" }, { name = "graphene-file-upload", specifier = "==1.3.0" }, { name = "gunicorn", specifier = "==23.0.0" }, { name = "httpx", specifier = "==0.28.1" }, { name = "jupyter", marker = "extra == 'jupyter'", specifier = "==1.1.1" }, - { name = "openai", marker = "extra == 'openai'", specifier = "==2.12.0" }, + { name = "openai", marker = "extra == 'openai'", specifier = "==2.13.0" }, { name = "paramiko", specifier = "==4.0.0" }, { name = "pillow", specifier = "==12.0.0" }, { name = "pip", specifier = ">=25.3" }, @@ -1449,17 +1521,24 @@ requires-dist = [ { name = "psycopg2", specifier = "==2.9.11" }, { name = "pygraphviz", marker = "sys_platform != 'win32' and extra == 'graph'", specifier = "==1.14" }, { name = "pyjwt", specifier = "==2.10.1" }, - { name = "pymdown-extensions", specifier = "==10.18" }, - { name = "pyright", marker = "extra == 'linting'", specifier = "==1.1.387" }, + { name = "pymdown-extensions", specifier = "==10.19.1" }, + { name = "pyright", marker = "extra == 'linting'", specifier = "==1.1.407" }, { name = "pytest", specifier = "==9.0.2" }, { name = "pytest-django", specifier = "==4.11.1" }, { name = "python-slugify", specifier = "==8.0.4" }, { name = "redis", specifier = "==7.1.0" }, { name = "requests", specifier = "==2.32.5" }, { name = "ruff", marker = "extra == 'linting'", specifier = "==0.14.9" }, - { name = "sentry-sdk", extras = ["django", "celery", "opentelemetry"], specifier = "==2.47.0" }, + { name = "sentry-sdk", extras = ["django", "celery", "opentelemetry"], specifier = "==2.48.0" }, { name = "six", specifier = "==1.17.0" }, { name = "swapper", specifier = "==1.4.0" }, + { name = "types-docutils", marker = "extra == 'linting'", specifier = "==0.22.3.20251115" }, + { name = "types-paramiko", marker = "extra == 'linting'", specifier = "==4.0.0.20250822" }, + { name = "types-pillow", marker = "extra == 'linting'", specifier = "==10.2.0.20240822" }, + { name = "types-psutil", marker = "extra == 'linting'", specifier = "==7.1.3.20251211" }, + { name = "types-redis", marker = "extra == 'linting'", specifier = "==4.6.0.20241004" }, + { name = "types-requests", marker = "extra == 'linting'", specifier = "==2.32.4.20250913" }, + { name = "types-six", marker = "extra == 'linting'", specifier = "==1.17.0.20251009" }, { name = "uvicorn", specifier = "==0.38.0" }, { name = "websockets", specifier = "==15.0.1" }, { name = "whitenoise", specifier = ">=6.11.0" }, @@ -1499,11 +1578,11 @@ wheels = [ [[package]] name = "filelock" -version = "3.20.0" +version = "3.20.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/23/ce7a1126827cedeb958fc043d61745754464eb56c5937c35bbf2b8e26f34/filelock-3.20.1.tar.gz", hash = "sha256:b8360948b351b80f420878d8516519a2204b07aefcdcfd24912a5d33127f188c", size = 19476, upload-time = "2025-12-15T23:54:28.027Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7f/a1a97644e39e7316d850784c642093c99df1290a460df4ede27659056834/filelock-3.20.1-py3-none-any.whl", hash = "sha256:15d9e9a67306188a44baa72f569d2bfd803076269365fdea0934385da4dc361a", size = 16666, upload-time = "2025-12-15T23:54:26.874Z" }, ] [[package]] @@ -2497,7 +2576,7 @@ wheels = [ [[package]] name = "notebook" -version = "7.5.0" +version = "7.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-server" }, @@ -2506,9 +2585,9 @@ dependencies = [ { name = "notebook-shim" }, { name = "tornado" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/89/ac/a97041621250a4fc5af379fb377942841eea2ca146aab166b8fcdfba96c2/notebook-7.5.0.tar.gz", hash = "sha256:3b27eaf9913033c28dde92d02139414c608992e1df4b969c843219acf2ff95e4", size = 14052074, upload-time = "2025-11-19T08:36:20.093Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/a9/882707b0aa639e6d7d3e7df4bfbe07479d832e9a8f02d8471002a4ea6d65/notebook-7.5.1.tar.gz", hash = "sha256:b2fb4cef4d47d08c33aecce1c6c6e84be05436fbd791f88fce8df9fbca088b75", size = 14058696, upload-time = "2025-12-16T07:38:59.223Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/96/00df2a4760f10f5af0f45c4955573cae6189931f9a30265a35865f8c1031/notebook-7.5.0-py3-none-any.whl", hash = "sha256:3300262d52905ca271bd50b22617681d95f08a8360d099e097726e6d2efb5811", size = 14460968, upload-time = "2025-11-19T08:36:15.869Z" }, + { url = "https://files.pythonhosted.org/packages/d1/86/ca516cb58ad2cb2064124d31cf0fd8b012fca64bebeb26da2d2ddf03fc79/notebook-7.5.1-py3-none-any.whl", hash = "sha256:f4e2451c19910c33b88709b84537e11f6368c1cdff1aa0c43db701aea535dd44", size = 14468080, upload-time = "2025-12-16T07:38:55.644Z" }, ] [[package]] @@ -2575,7 +2654,7 @@ sdist = { url = "https://files.pythonhosted.org/packages/97/73/8ade73f6749177003 [[package]] name = "openai" -version = "2.12.0" +version = "2.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -2587,9 +2666,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/86/f9/fb8abeb4cdba6f24daf3d7781f42ceb1be1ff579eb20705899e617dd95f1/openai-2.12.0.tar.gz", hash = "sha256:cc6dcbcb8bccf05976d983f6516c5c1f447b71c747720f1530b61e8f858bcbc9", size = 626183, upload-time = "2025-12-15T16:17:15.097Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/39/8e347e9fda125324d253084bb1b82407e5e3c7777a03dc398f79b2d95626/openai-2.13.0.tar.gz", hash = "sha256:9ff633b07a19469ec476b1e2b5b26c5ef700886524a7a72f65e6f0b5203142d5", size = 626583, upload-time = "2025-12-16T18:19:44.387Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/a1/f055214448cb4b176e89459d889af9615fe7d927634fb5a2cecfb7674bc5/openai-2.12.0-py3-none-any.whl", hash = "sha256:7177998ce49ba3f90bcce8b5769a6666d90b1f328f0518d913aaec701271485a", size = 1066590, upload-time = "2025-12-15T16:17:13.301Z" }, + { url = "https://files.pythonhosted.org/packages/bb/d5/eb52edff49d3d5ea116e225538c118699ddeb7c29fa17ec28af14bc10033/openai-2.13.0-py3-none-any.whl", hash = "sha256:746521065fed68df2f9c2d85613bb50844343ea81f60009b60e6a600c9352c79", size = 1066837, upload-time = "2025-12-16T18:19:43.124Z" }, ] [[package]] @@ -2673,6 +2752,44 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7a/5e/5958555e09635d09b75de3c4f8b9cae7335ca545d77392ffe7331534c402/opentelemetry_semantic_conventions-0.60b1-py3-none-any.whl", hash = "sha256:9fa8c8b0c110da289809292b0591220d3a7b53c1526a23021e977d68597893fb", size = 219982, upload-time = "2025-12-11T13:32:36.955Z" }, ] +[[package]] +name = "orjson" +version = "3.11.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/04/b8/333fdb27840f3bf04022d21b654a35f58e15407183aeb16f3b41aa053446/orjson-3.11.5.tar.gz", hash = "sha256:82393ab47b4fe44ffd0a7659fa9cfaacc717eb617c93cde83795f14af5c2e9d5", size = 5972347, upload-time = "2025-12-06T15:55:39.458Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a4/8052a029029b096a78955eadd68ab594ce2197e24ec50e6b6d2ab3f4e33b/orjson-3.11.5-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:334e5b4bff9ad101237c2d799d9fd45737752929753bf4faf4b207335a416b7d", size = 245347, upload-time = "2025-12-06T15:54:22.061Z" }, + { url = "https://files.pythonhosted.org/packages/64/67/574a7732bd9d9d79ac620c8790b4cfe0717a3d5a6eb2b539e6e8995e24a0/orjson-3.11.5-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:ff770589960a86eae279f5d8aa536196ebda8273a2a07db2a54e82b93bc86626", size = 129435, upload-time = "2025-12-06T15:54:23.615Z" }, + { url = "https://files.pythonhosted.org/packages/52/8d/544e77d7a29d90cf4d9eecd0ae801c688e7f3d1adfa2ebae5e1e94d38ab9/orjson-3.11.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed24250e55efbcb0b35bed7caaec8cedf858ab2f9f2201f17b8938c618c8ca6f", size = 132074, upload-time = "2025-12-06T15:54:24.694Z" }, + { url = "https://files.pythonhosted.org/packages/6e/57/b9f5b5b6fbff9c26f77e785baf56ae8460ef74acdb3eae4931c25b8f5ba9/orjson-3.11.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a66d7769e98a08a12a139049aac2f0ca3adae989817f8c43337455fbc7669b85", size = 130520, upload-time = "2025-12-06T15:54:26.185Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6d/d34970bf9eb33f9ec7c979a262cad86076814859e54eb9a059a52f6dc13d/orjson-3.11.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86cfc555bfd5794d24c6a1903e558b50644e5e68e6471d66502ce5cb5fdef3f9", size = 136209, upload-time = "2025-12-06T15:54:27.264Z" }, + { url = "https://files.pythonhosted.org/packages/e7/39/bc373b63cc0e117a105ea12e57280f83ae52fdee426890d57412432d63b3/orjson-3.11.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a230065027bc2a025e944f9d4714976a81e7ecfa940923283bca7bbc1f10f626", size = 139837, upload-time = "2025-12-06T15:54:28.75Z" }, + { url = "https://files.pythonhosted.org/packages/cb/aa/7c4818c8d7d324da220f4f1af55c343956003aa4d1ce1857bdc1d396ba69/orjson-3.11.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b29d36b60e606df01959c4b982729c8845c69d1963f88686608be9ced96dbfaa", size = 137307, upload-time = "2025-12-06T15:54:29.856Z" }, + { url = "https://files.pythonhosted.org/packages/46/bf/0993b5a056759ba65145effe3a79dd5a939d4a070eaa5da2ee3180fbb13f/orjson-3.11.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c74099c6b230d4261fdc3169d50efc09abf38ace1a42ea2f9994b1d79153d477", size = 139020, upload-time = "2025-12-06T15:54:31.024Z" }, + { url = "https://files.pythonhosted.org/packages/65/e8/83a6c95db3039e504eda60fc388f9faedbb4f6472f5aba7084e06552d9aa/orjson-3.11.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e697d06ad57dd0c7a737771d470eedc18e68dfdefcdd3b7de7f33dfda5b6212e", size = 141099, upload-time = "2025-12-06T15:54:32.196Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b4/24fdc024abfce31c2f6812973b0a693688037ece5dc64b7a60c1ce69e2f2/orjson-3.11.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e08ca8a6c851e95aaecc32bc44a5aa75d0ad26af8cdac7c77e4ed93acf3d5b69", size = 413540, upload-time = "2025-12-06T15:54:33.361Z" }, + { url = "https://files.pythonhosted.org/packages/d9/37/01c0ec95d55ed0c11e4cae3e10427e479bba40c77312b63e1f9665e0737d/orjson-3.11.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e8b5f96c05fce7d0218df3fdfeb962d6b8cfff7e3e20264306b46dd8b217c0f3", size = 151530, upload-time = "2025-12-06T15:54:34.6Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d4/f9ebc57182705bb4bbe63f5bbe14af43722a2533135e1d2fb7affa0c355d/orjson-3.11.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ddbfdb5099b3e6ba6d6ea818f61997bb66de14b411357d24c4612cf1ebad08ca", size = 141863, upload-time = "2025-12-06T15:54:35.801Z" }, + { url = "https://files.pythonhosted.org/packages/0d/04/02102b8d19fdcb009d72d622bb5781e8f3fae1646bf3e18c53d1bc8115b5/orjson-3.11.5-cp312-cp312-win32.whl", hash = "sha256:9172578c4eb09dbfcf1657d43198de59b6cef4054de385365060ed50c458ac98", size = 135255, upload-time = "2025-12-06T15:54:37.209Z" }, + { url = "https://files.pythonhosted.org/packages/d4/fb/f05646c43d5450492cb387de5549f6de90a71001682c17882d9f66476af5/orjson-3.11.5-cp312-cp312-win_amd64.whl", hash = "sha256:2b91126e7b470ff2e75746f6f6ee32b9ab67b7a93c8ba1d15d3a0caaf16ec875", size = 133252, upload-time = "2025-12-06T15:54:38.401Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a6/7b8c0b26ba18c793533ac1cd145e131e46fcf43952aa94c109b5b913c1f0/orjson-3.11.5-cp312-cp312-win_arm64.whl", hash = "sha256:acbc5fac7e06777555b0722b8ad5f574739e99ffe99467ed63da98f97f9ca0fe", size = 126777, upload-time = "2025-12-06T15:54:39.515Z" }, + { url = "https://files.pythonhosted.org/packages/10/43/61a77040ce59f1569edf38f0b9faadc90c8cf7e9bec2e0df51d0132c6bb7/orjson-3.11.5-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3b01799262081a4c47c035dd77c1301d40f568f77cc7ec1bb7db5d63b0a01629", size = 245271, upload-time = "2025-12-06T15:54:40.878Z" }, + { url = "https://files.pythonhosted.org/packages/55/f9/0f79be617388227866d50edd2fd320cb8fb94dc1501184bb1620981a0aba/orjson-3.11.5-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:61de247948108484779f57a9f406e4c84d636fa5a59e411e6352484985e8a7c3", size = 129422, upload-time = "2025-12-06T15:54:42.403Z" }, + { url = "https://files.pythonhosted.org/packages/77/42/f1bf1549b432d4a78bfa95735b79b5dac75b65b5bb815bba86ad406ead0a/orjson-3.11.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:894aea2e63d4f24a7f04a1908307c738d0dce992e9249e744b8f4e8dd9197f39", size = 132060, upload-time = "2025-12-06T15:54:43.531Z" }, + { url = "https://files.pythonhosted.org/packages/25/49/825aa6b929f1a6ed244c78acd7b22c1481fd7e5fda047dc8bf4c1a807eb6/orjson-3.11.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ddc21521598dbe369d83d4d40338e23d4101dad21dae0e79fa20465dbace019f", size = 130391, upload-time = "2025-12-06T15:54:45.059Z" }, + { url = "https://files.pythonhosted.org/packages/42/ec/de55391858b49e16e1aa8f0bbbb7e5997b7345d8e984a2dec3746d13065b/orjson-3.11.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cce16ae2f5fb2c53c3eafdd1706cb7b6530a67cc1c17abe8ec747f5cd7c0c51", size = 135964, upload-time = "2025-12-06T15:54:46.576Z" }, + { url = "https://files.pythonhosted.org/packages/1c/40/820bc63121d2d28818556a2d0a09384a9f0262407cf9fa305e091a8048df/orjson-3.11.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e46c762d9f0e1cfb4ccc8515de7f349abbc95b59cb5a2bd68df5973fdef913f8", size = 139817, upload-time = "2025-12-06T15:54:48.084Z" }, + { url = "https://files.pythonhosted.org/packages/09/c7/3a445ca9a84a0d59d26365fd8898ff52bdfcdcb825bcc6519830371d2364/orjson-3.11.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7345c759276b798ccd6d77a87136029e71e66a8bbf2d2755cbdde1d82e78706", size = 137336, upload-time = "2025-12-06T15:54:49.426Z" }, + { url = "https://files.pythonhosted.org/packages/9a/b3/dc0d3771f2e5d1f13368f56b339c6782f955c6a20b50465a91acb79fe961/orjson-3.11.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75bc2e59e6a2ac1dd28901d07115abdebc4563b5b07dd612bf64260a201b1c7f", size = 138993, upload-time = "2025-12-06T15:54:50.939Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a2/65267e959de6abe23444659b6e19c888f242bf7725ff927e2292776f6b89/orjson-3.11.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:54aae9b654554c3b4edd61896b978568c6daa16af96fa4681c9b5babd469f863", size = 141070, upload-time = "2025-12-06T15:54:52.414Z" }, + { url = "https://files.pythonhosted.org/packages/63/c9/da44a321b288727a322c6ab17e1754195708786a04f4f9d2220a5076a649/orjson-3.11.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4bdd8d164a871c4ec773f9de0f6fe8769c2d6727879c37a9666ba4183b7f8228", size = 413505, upload-time = "2025-12-06T15:54:53.67Z" }, + { url = "https://files.pythonhosted.org/packages/7f/17/68dc14fa7000eefb3d4d6d7326a190c99bb65e319f02747ef3ebf2452f12/orjson-3.11.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a261fef929bcf98a60713bf5e95ad067cea16ae345d9a35034e73c3990e927d2", size = 151342, upload-time = "2025-12-06T15:54:55.113Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c5/ccee774b67225bed630a57478529fc026eda33d94fe4c0eac8fe58d4aa52/orjson-3.11.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c028a394c766693c5c9909dec76b24f37e6a1b91999e8d0c0d5feecbe93c3e05", size = 141823, upload-time = "2025-12-06T15:54:56.331Z" }, + { url = "https://files.pythonhosted.org/packages/67/80/5d00e4155d0cd7390ae2087130637671da713959bb558db9bac5e6f6b042/orjson-3.11.5-cp313-cp313-win32.whl", hash = "sha256:2cc79aaad1dfabe1bd2d50ee09814a1253164b3da4c00a78c458d82d04b3bdef", size = 135236, upload-time = "2025-12-06T15:54:57.507Z" }, + { url = "https://files.pythonhosted.org/packages/95/fe/792cc06a84808dbdc20ac6eab6811c53091b42f8e51ecebf14b540e9cfe4/orjson-3.11.5-cp313-cp313-win_amd64.whl", hash = "sha256:ff7877d376add4e16b274e35a3f58b7f37b362abf4aa31863dadacdd20e3a583", size = 133167, upload-time = "2025-12-06T15:54:58.71Z" }, + { url = "https://files.pythonhosted.org/packages/46/2c/d158bd8b50e3b1cfdcf406a7e463f6ffe3f0d167b99634717acdaf5e299f/orjson-3.11.5-cp313-cp313-win_arm64.whl", hash = "sha256:59ac72ea775c88b163ba8d21b0177628bd015c5dd060647bbab6e22da3aad287", size = 126712, upload-time = "2025-12-06T15:54:59.892Z" }, +] + [[package]] name = "packaging" version = "25.0" @@ -3075,15 +3192,15 @@ wheels = [ [[package]] name = "pymdown-extensions" -version = "10.18" +version = "10.19.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d4/95/e4fa281e3f13b3d9c4aaebb21ef44879840325fa418276dd921209a5e9f9/pymdown_extensions-10.18.tar.gz", hash = "sha256:20252abe6367354b24191431617a072ee6be9f68c5afcc74ea5573508a61f9e5", size = 847697, upload-time = "2025-12-07T17:22:12.857Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/2d/9f30cee56d4d6d222430d401e85b0a6a1ae229819362f5786943d1a8c03b/pymdown_extensions-10.19.1.tar.gz", hash = "sha256:4969c691009a389fb1f9712dd8e7bd70dcc418d15a0faf70acb5117d022f7de8", size = 847839, upload-time = "2025-12-14T17:25:24.42Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/a4/aa2bada4a2fd648f40f19affa55d2c01dc7ff5ea9cffd3dfdeb6114951db/pymdown_extensions-10.18-py3-none-any.whl", hash = "sha256:090bca72be43f7d3186374e23c782899dbef9dc153ef24c59dcd3c346f9ffcae", size = 266703, upload-time = "2025-12-07T17:22:11.22Z" }, + { url = "https://files.pythonhosted.org/packages/fb/35/b763e8fbcd51968329b9adc52d188fc97859f85f2ee15fe9f379987d99c5/pymdown_extensions-10.19.1-py3-none-any.whl", hash = "sha256:e8698a66055b1dc0dca2a7f2c9d0ea6f5faa7834a9c432e3535ab96c0c4e509b", size = 266693, upload-time = "2025-12-14T17:25:22.999Z" }, ] [[package]] @@ -3113,15 +3230,15 @@ wheels = [ [[package]] name = "pyright" -version = "1.1.387" +version = "1.1.407" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/32/e7187478d3105d6d7edc9b754d56472ee06557c25cc404911288fee1796a/pyright-1.1.387.tar.gz", hash = "sha256:577de60224f7fe36505d5b181231e3a395d427b7873be0bbcaa962a29ea93a60", size = 21939, upload-time = "2024-10-30T08:46:31.44Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/1b/0aa08ee42948b61745ac5b5b5ccaec4669e8884b53d31c8ec20b2fcd6b6f/pyright-1.1.407.tar.gz", hash = "sha256:099674dba5c10489832d4a4b2d302636152a9a42d317986c38474c76fe562262", size = 4122872, upload-time = "2025-10-24T23:17:15.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/18/c497df36641b0572f5bd59ae147b08ccaa6b8086397d50e1af97cc2ddcf6/pyright-1.1.387-py3-none-any.whl", hash = "sha256:6a1f495a261a72e12ad17e20d1ae3df4511223c773b19407cfa006229b1b08a5", size = 18577, upload-time = "2024-10-30T08:46:29.701Z" }, + { url = "https://files.pythonhosted.org/packages/dc/93/b69052907d032b00c40cb656d21438ec00b3a471733de137a3f65a49a0a0/pyright-1.1.407-py3-none-any.whl", hash = "sha256:6dd419f54fcc13f03b52285796d65e639786373f433e243f8b94cf93a7444d21", size = 5997008, upload-time = "2025-10-24T23:17:13.159Z" }, ] [[package]] @@ -3459,15 +3576,15 @@ wheels = [ [[package]] name = "sentry-sdk" -version = "2.47.0" +version = "2.48.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4a/2a/d225cbf87b6c8ecce5664db7bcecb82c317e448e3b24a2dcdaacb18ca9a7/sentry_sdk-2.47.0.tar.gz", hash = "sha256:8218891d5e41b4ea8d61d2aed62ed10c80e39d9f2959d6f939efbf056857e050", size = 381895, upload-time = "2025-12-03T14:06:36.846Z" } +sdist = { url = "https://files.pythonhosted.org/packages/40/f0/0e9dc590513d5e742d7799e2038df3a05167cba084c6ca4f3cdd75b55164/sentry_sdk-2.48.0.tar.gz", hash = "sha256:5213190977ff7fdff8a58b722fb807f8d5524a80488626ebeda1b5676c0c1473", size = 384828, upload-time = "2025-12-16T14:55:41.722Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/ac/d6286ea0d49e7b58847faf67b00e56bb4ba3d525281e2ac306e1f1f353da/sentry_sdk-2.47.0-py2.py3-none-any.whl", hash = "sha256:d72f8c61025b7d1d9e52510d03a6247b280094a327dd900d987717a4fce93412", size = 411088, upload-time = "2025-12-03T14:06:35.374Z" }, + { url = "https://files.pythonhosted.org/packages/4d/19/8d77f9992e5cbfcaa9133c3bf63b4fbbb051248802e1e803fed5c552fbb2/sentry_sdk-2.48.0-py2.py3-none-any.whl", hash = "sha256:6b12ac256769d41825d9b7518444e57fa35b5642df4c7c5e322af4d2c8721172", size = 414555, upload-time = "2025-12-16T14:55:40.152Z" }, ] [package.optional-dependencies] @@ -3615,21 +3732,21 @@ wheels = [ [[package]] name = "tornado" -version = "6.5.3" +version = "6.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7f/2e/3d22d478f27cb4b41edd4db7f10cd7846d0a28ea443342de3dba97035166/tornado-6.5.3.tar.gz", hash = "sha256:16abdeb0211796ffc73765bc0a20119712d68afeeaf93d1a3f2edf6b3aee8d5a", size = 513348, upload-time = "2025-12-11T04:16:42.225Z" } +sdist = { url = "https://files.pythonhosted.org/packages/37/1d/0a336abf618272d53f62ebe274f712e213f5a03c0b2339575430b8362ef2/tornado-6.5.4.tar.gz", hash = "sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7", size = 513632, upload-time = "2025-12-15T19:21:03.836Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/e9/bf22f66e1d5d112c0617974b5ce86666683b32c09b355dfcd59f8d5c8ef6/tornado-6.5.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2dd7d7e8d3e4635447a8afd4987951e3d4e8d1fb9ad1908c54c4002aabab0520", size = 443860, upload-time = "2025-12-11T04:16:26.638Z" }, - { url = "https://files.pythonhosted.org/packages/ca/9c/594b631f0b8dc5977080c7093d1e96f1377c10552577d2c31bb0208c9362/tornado-6.5.3-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:5977a396f83496657779f59a48c38096ef01edfe4f42f1c0634b791dde8165d0", size = 442118, upload-time = "2025-12-11T04:16:28.32Z" }, - { url = "https://files.pythonhosted.org/packages/78/f6/685b869f5b5b9d9547571be838c6106172082751696355b60fc32a4988ed/tornado-6.5.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f72ac800be2ac73ddc1504f7aa21069a4137e8d70c387172c063d363d04f2208", size = 445700, upload-time = "2025-12-11T04:16:29.64Z" }, - { url = "https://files.pythonhosted.org/packages/91/4c/f0d19edf24912b7f21ae5e941f7798d132ad4d9b71441c1e70917a297265/tornado-6.5.3-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c43c4fc4f5419c6561cfb8b884a8f6db7b142787d47821e1a0e1296253458265", size = 445041, upload-time = "2025-12-11T04:16:30.799Z" }, - { url = "https://files.pythonhosted.org/packages/eb/2b/e02da94f4a4aef2bb3b923c838ef284a77548a5f06bac2a8682b36b4eead/tornado-6.5.3-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de8b3fed4b3afb65d542d7702ac8767b567e240f6a43020be8eaef59328f117b", size = 445270, upload-time = "2025-12-11T04:16:32.316Z" }, - { url = "https://files.pythonhosted.org/packages/58/e2/7a7535d23133443552719dba526dacbb7415f980157da9f14950ddb88ad6/tornado-6.5.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dbc4b4c32245b952566e17a20d5c1648fbed0e16aec3fc7e19f3974b36e0e47c", size = 445957, upload-time = "2025-12-11T04:16:33.913Z" }, - { url = "https://files.pythonhosted.org/packages/a0/1f/9ff92eca81ff17a86286ec440dcd5eab0400326eb81761aa9a4eecb1ffb9/tornado-6.5.3-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:db238e8a174b4bfd0d0238b8cfcff1c14aebb4e2fcdafbf0ea5da3b81caceb4c", size = 445371, upload-time = "2025-12-11T04:16:35.093Z" }, - { url = "https://files.pythonhosted.org/packages/70/b1/1d03ae4526a393b0b839472a844397337f03c7f3a1e6b5c82241f0e18281/tornado-6.5.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:892595c100cd9b53a768cbfc109dfc55dec884afe2de5290611a566078d9692d", size = 445348, upload-time = "2025-12-11T04:16:36.679Z" }, - { url = "https://files.pythonhosted.org/packages/4b/7d/7c181feadc8941f418d0d26c3790ee34ffa4bd0a294bc5201d44ebd19c1e/tornado-6.5.3-cp39-abi3-win32.whl", hash = "sha256:88141456525fe291e47bbe1ba3ffb7982549329f09b4299a56813923af2bd197", size = 446433, upload-time = "2025-12-11T04:16:38.332Z" }, - { url = "https://files.pythonhosted.org/packages/34/98/4f7f938606e21d0baea8c6c39a7c8e95bdf8e50b0595b1bb6f0de2af7a6e/tornado-6.5.3-cp39-abi3-win_amd64.whl", hash = "sha256:ba4b513d221cc7f795a532c1e296f36bcf6a60e54b15efd3f092889458c69af1", size = 446842, upload-time = "2025-12-11T04:16:39.867Z" }, - { url = "https://files.pythonhosted.org/packages/7a/27/0e3fca4c4edf33fb6ee079e784c63961cd816971a45e5e4cacebe794158d/tornado-6.5.3-cp39-abi3-win_arm64.whl", hash = "sha256:278c54d262911365075dd45e0b6314308c74badd6ff9a54490e7daccdd5ed0ea", size = 445863, upload-time = "2025-12-11T04:16:41.099Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a9/e94a9d5224107d7ce3cc1fab8d5dc97f5ea351ccc6322ee4fb661da94e35/tornado-6.5.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9", size = 443909, upload-time = "2025-12-15T19:20:48.382Z" }, + { url = "https://files.pythonhosted.org/packages/db/7e/f7b8d8c4453f305a51f80dbb49014257bb7d28ccb4bbb8dd328ea995ecad/tornado-6.5.4-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843", size = 442163, upload-time = "2025-12-15T19:20:49.791Z" }, + { url = "https://files.pythonhosted.org/packages/ba/b5/206f82d51e1bfa940ba366a8d2f83904b15942c45a78dd978b599870ab44/tornado-6.5.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17", size = 445746, upload-time = "2025-12-15T19:20:51.491Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/1a3338e0bd30ada6ad4356c13a0a6c35fbc859063fa7eddb309183364ac1/tornado-6.5.4-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335", size = 445083, upload-time = "2025-12-15T19:20:52.778Z" }, + { url = "https://files.pythonhosted.org/packages/50/d4/e51d52047e7eb9a582da59f32125d17c0482d065afd5d3bc435ff2120dc5/tornado-6.5.4-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f", size = 445315, upload-time = "2025-12-15T19:20:53.996Z" }, + { url = "https://files.pythonhosted.org/packages/27/07/2273972f69ca63dbc139694a3fc4684edec3ea3f9efabf77ed32483b875c/tornado-6.5.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84", size = 446003, upload-time = "2025-12-15T19:20:56.101Z" }, + { url = "https://files.pythonhosted.org/packages/d1/83/41c52e47502bf7260044413b6770d1a48dda2f0246f95ee1384a3cd9c44a/tornado-6.5.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f", size = 445412, upload-time = "2025-12-15T19:20:57.398Z" }, + { url = "https://files.pythonhosted.org/packages/10/c7/bc96917f06cbee182d44735d4ecde9c432e25b84f4c2086143013e7b9e52/tornado-6.5.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8", size = 445392, upload-time = "2025-12-15T19:20:58.692Z" }, + { url = "https://files.pythonhosted.org/packages/0c/1a/d7592328d037d36f2d2462f4bc1fbb383eec9278bc786c1b111cbbd44cfa/tornado-6.5.4-cp39-abi3-win32.whl", hash = "sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1", size = 446481, upload-time = "2025-12-15T19:21:00.008Z" }, + { url = "https://files.pythonhosted.org/packages/d6/6d/c69be695a0a64fd37a97db12355a035a6d90f79067a3cf936ec2b1dc38cd/tornado-6.5.4-cp39-abi3-win_amd64.whl", hash = "sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc", size = 446886, upload-time = "2025-12-15T19:21:01.287Z" }, + { url = "https://files.pythonhosted.org/packages/50/49/8dc3fd90902f70084bd2cd059d576ddb4f8bb44c2c7c0e33a11422acb17e/tornado-6.5.4-cp39-abi3-win_arm64.whl", hash = "sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1", size = 445910, upload-time = "2025-12-15T19:21:02.571Z" }, ] [[package]] @@ -3653,6 +3770,122 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, ] +[[package]] +name = "types-cffi" +version = "1.17.0.20250915" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "types-setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/98/ea454cea03e5f351323af6a482c65924f3c26c515efd9090dede58f2b4b6/types_cffi-1.17.0.20250915.tar.gz", hash = "sha256:4362e20368f78dabd5c56bca8004752cc890e07a71605d9e0d9e069dbaac8c06", size = 17229, upload-time = "2025-09-15T03:01:25.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/ec/092f2b74b49ec4855cdb53050deb9699f7105b8fda6fe034c0781b8687f3/types_cffi-1.17.0.20250915-py3-none-any.whl", hash = "sha256:cef4af1116c83359c11bb4269283c50f0688e9fc1d7f0eeb390f3661546da52c", size = 20112, upload-time = "2025-09-15T03:01:24.187Z" }, +] + +[[package]] +name = "types-docutils" +version = "0.22.3.20251115" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/d7/576ec24bf61a280f571e1f22284793adc321610b9bcfba1bf468cf7b334f/types_docutils-0.22.3.20251115.tar.gz", hash = "sha256:0f79ea6a7bd4d12d56c9f824a0090ffae0ea4204203eb0006392906850913e16", size = 56828, upload-time = "2025-11-15T02:59:57.371Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/01/61ac9eb38f1f978b47443dc6fd2e0a3b0f647c2da741ddad30771f1b2b6f/types_docutils-0.22.3.20251115-py3-none-any.whl", hash = "sha256:c6e53715b65395d00a75a3a8a74e352c669bc63959e65a207dffaa22f4a2ad6e", size = 91951, upload-time = "2025-11-15T02:59:56.413Z" }, +] + +[[package]] +name = "types-paramiko" +version = "4.0.0.20250822" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/b8/c6ff3b10c2f7b9897650af746f0dc6c5cddf054db857bc79d621f53c7d22/types_paramiko-4.0.0.20250822.tar.gz", hash = "sha256:1b56b0cbd3eec3d2fd123c9eb2704e612b777e15a17705a804279ea6525e0c53", size = 28730, upload-time = "2025-08-22T03:03:43.262Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/a1/b3774ed924a66ee2c041224d89c36f0c21f4f6cf75036d6ee7698bf8a4b9/types_paramiko-4.0.0.20250822-py3-none-any.whl", hash = "sha256:55bdb14db75ca89039725ec64ae3fa26b8d57b6991cfb476212fa8f83a59753c", size = 38833, upload-time = "2025-08-22T03:03:42.072Z" }, +] + +[[package]] +name = "types-pillow" +version = "10.2.0.20240822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/4a/4495264dddaa600d65d68bcedb64dcccf9d9da61adff51f7d2ffd8e4c9ce/types-Pillow-10.2.0.20240822.tar.gz", hash = "sha256:559fb52a2ef991c326e4a0d20accb3bb63a7ba8d40eb493e0ecb0310ba52f0d3", size = 35389, upload-time = "2024-08-22T02:32:48.15Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/23/e81a5354859831fcf54d488d33b80ba6133ea84f874a9c0ec40a4881e133/types_Pillow-10.2.0.20240822-py3-none-any.whl", hash = "sha256:d9dab025aba07aeb12fd50a6799d4eac52a9603488eca09d7662543983f16c5d", size = 54354, upload-time = "2024-08-22T02:32:46.664Z" }, +] + +[[package]] +name = "types-psutil" +version = "7.1.3.20251211" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d2/d5/85165865b060fed80b5991574c2ae0ddfd4786398dc8bceddfe0a8960b74/types_psutil-7.1.3.20251211.tar.gz", hash = "sha256:2c25f8fd3a1a4aebdffb861b97755c9a2d5d8019dd6ec1a2f2a77ec796652c89", size = 25198, upload-time = "2025-12-11T03:16:44.651Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/61/658be05b56aeec195386b3f5c48cfa5bdaf8e989de3e4d802eeba457bd05/types_psutil-7.1.3.20251211-py3-none-any.whl", hash = "sha256:369872d955d7d47d77f4832b41e2300f832126e3fa97eb107d2d6a294c23c650", size = 32055, upload-time = "2025-12-11T03:16:43.864Z" }, +] + +[[package]] +name = "types-pyopenssl" +version = "24.1.0.20240722" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "types-cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/93/29/47a346550fd2020dac9a7a6d033ea03fccb92fa47c726056618cc889745e/types-pyOpenSSL-24.1.0.20240722.tar.gz", hash = "sha256:47913b4678a01d879f503a12044468221ed8576263c1540dcb0484ca21b08c39", size = 8458, upload-time = "2024-07-22T02:32:22.558Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/05/c868a850b6fbb79c26f5f299b768ee0adc1f9816d3461dcf4287916f655b/types_pyOpenSSL-24.1.0.20240722-py3-none-any.whl", hash = "sha256:6a7a5d2ec042537934cfb4c9d4deb0e16c4c6250b09358df1f083682fe6fda54", size = 7499, upload-time = "2024-07-22T02:32:21.232Z" }, +] + +[[package]] +name = "types-pyyaml" +version = "6.0.12.20250915" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/69/3c51b36d04da19b92f9e815be12753125bd8bc247ba0470a982e6979e71c/types_pyyaml-6.0.12.20250915.tar.gz", hash = "sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3", size = 17522, upload-time = "2025-09-15T03:01:00.728Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/e0/1eed384f02555dde685fff1a1ac805c1c7dcb6dd019c916fe659b1c1f9ec/types_pyyaml-6.0.12.20250915-py3-none-any.whl", hash = "sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6", size = 20338, upload-time = "2025-09-15T03:00:59.218Z" }, +] + +[[package]] +name = "types-redis" +version = "4.6.0.20241004" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "types-pyopenssl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/95/c054d3ac940e8bac4ca216470c80c26688a0e79e09f520a942bb27da3386/types-redis-4.6.0.20241004.tar.gz", hash = "sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e", size = 49679, upload-time = "2024-10-04T02:43:59.224Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/82/7d25dce10aad92d2226b269bce2f85cfd843b4477cd50245d7d40ecf8f89/types_redis-4.6.0.20241004-py3-none-any.whl", hash = "sha256:ef5da68cb827e5f606c8f9c0b49eeee4c2669d6d97122f301d3a55dc6a63f6ed", size = 58737, upload-time = "2024-10-04T02:43:57.968Z" }, +] + +[[package]] +name = "types-requests" +version = "2.32.4.20250913" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/27/489922f4505975b11de2b5ad07b4fe1dca0bca9be81a703f26c5f3acfce5/types_requests-2.32.4.20250913.tar.gz", hash = "sha256:abd6d4f9ce3a9383f269775a9835a4c24e5cd6b9f647d64f88aa4613c33def5d", size = 23113, upload-time = "2025-09-13T02:40:02.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/20/9a227ea57c1285986c4cf78400d0a91615d25b24e257fd9e2969606bdfae/types_requests-2.32.4.20250913-py3-none-any.whl", hash = "sha256:78c9c1fffebbe0fa487a418e0fa5252017e9c60d1a2da394077f1780f655d7e1", size = 20658, upload-time = "2025-09-13T02:40:01.115Z" }, +] + +[[package]] +name = "types-setuptools" +version = "80.9.0.20250822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/bd/1e5f949b7cb740c9f0feaac430e301b8f1c5f11a81e26324299ea671a237/types_setuptools-80.9.0.20250822.tar.gz", hash = "sha256:070ea7716968ec67a84c7f7768d9952ff24d28b65b6594797a464f1b3066f965", size = 41296, upload-time = "2025-08-22T03:02:08.771Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/2d/475bf15c1cdc172e7a0d665b6e373ebfb1e9bf734d3f2f543d668b07a142/types_setuptools-80.9.0.20250822-py3-none-any.whl", hash = "sha256:53bf881cb9d7e46ed12c76ef76c0aaf28cfe6211d3fab12e0b83620b1a8642c3", size = 63179, upload-time = "2025-08-22T03:02:07.643Z" }, +] + +[[package]] +name = "types-six" +version = "1.17.0.20251009" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/f7/448215bc7695cfa0c8a7e0dcfa54fe31b1d52fb87004fed32e659dd85c80/types_six-1.17.0.20251009.tar.gz", hash = "sha256:efe03064ecd0ffb0f7afe133990a2398d8493d8d1c1cc10ff3dfe476d57ba44f", size = 15552, upload-time = "2025-10-09T02:54:26.02Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/2f/94baa623421940e3eb5d2fc63570ebb046f2bb4d9573b8787edab3ed2526/types_six-1.17.0.20251009-py3-none-any.whl", hash = "sha256:2494f4c2a58ada0edfe01ea84b58468732e43394c572d9cf5b1dd06d86c487a3", size = 19935, upload-time = "2025-10-09T02:54:25.096Z" }, +] + [[package]] name = "typing-extensions" version = "4.15.0"