From 996362d9f19bd8c8d42df2e6ab2c1ec1a3f9250b Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Wed, 15 Oct 2025 16:15:23 +0300 Subject: [PATCH] Features: 1) Add `save_response` method to save vendor responses with optional gzip compression; 2) Introduce `VendorDebuggingError` for debugging-specific exceptions; 3) Add imports for `config` and `settings` for enhanced configuration support; Fixes: None; Extra: Improve exception handling with `suppress(Exception)` block; add detailed docstring to `VendorDebuggingError`. --- core/vendors/__init__.py | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/core/vendors/__init__.py b/core/vendors/__init__.py index a460d850..444b3750 100644 --- a/core/vendors/__init__.py +++ b/core/vendors/__init__.py @@ -4,6 +4,8 @@ from decimal import Decimal from math import ceil, log10 from typing import Any +from constance import config +from django.conf import settings from django.db import IntegrityError, transaction from django.db.models import QuerySet @@ -59,6 +61,14 @@ class VendorError(Exception): pass +class VendorDebuggingError(VendorError): + """ + Custom exception raised when a debugging operation fails + """ + + pass + + class VendorInactiveError(VendorError): pass @@ -87,6 +97,39 @@ class AbstractVendor: def __str__(self) -> str: return self.vendor_name or self.get_vendor_instance().name + def save_response(self, data: dict[Any, Any]) -> None: + with suppress(Exception): + if settings.DEBUG or config.SAVE_VENDORS_RESPONSES: + import gzip + from io import BytesIO + from django.core.files.base import ContentFile + from datetime import datetime + + vendor_instance = self.get_vendor_instance() + + json_data = json.dumps(data, indent=2, ensure_ascii=False, default=str) + json_bytes = json_data.encode("utf-8") + + size_threshold = 1024 * 1024 # 1MB + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + + if len(json_bytes) > size_threshold: + buffer = BytesIO() + with gzip.GzipFile(fileobj=buffer, mode="wb", compresslevel=9) as gz_file: + gz_file.write(json_bytes) + + compressed_data = buffer.getvalue() + filename = f"response_{timestamp}.json.gz" + content = ContentFile(compressed_data) + else: + filename = f"response_{timestamp}.json" + content = ContentFile(json_bytes) + + vendor_instance.last_processing_response.save(filename, content, save=True) + + return + raise VendorDebuggingError("Could not save response") + @staticmethod def chunk_data(data: list[Any] | None = None, num_chunks: int = 20) -> list[list[Any]] | list[Any]: if not data: