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`.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-10-15 16:15:23 +03:00
parent 6fa037390c
commit 996362d9f1

View file

@ -4,6 +4,8 @@ from decimal import Decimal
from math import ceil, log10 from math import ceil, log10
from typing import Any from typing import Any
from constance import config
from django.conf import settings
from django.db import IntegrityError, transaction from django.db import IntegrityError, transaction
from django.db.models import QuerySet from django.db.models import QuerySet
@ -59,6 +61,14 @@ class VendorError(Exception):
pass pass
class VendorDebuggingError(VendorError):
"""
Custom exception raised when a debugging operation fails
"""
pass
class VendorInactiveError(VendorError): class VendorInactiveError(VendorError):
pass pass
@ -87,6 +97,39 @@ class AbstractVendor:
def __str__(self) -> str: def __str__(self) -> str:
return self.vendor_name or self.get_vendor_instance().name 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 @staticmethod
def chunk_data(data: list[Any] | None = None, num_chunks: int = 20) -> list[list[Any]] | list[Any]: def chunk_data(data: list[Any] | None = None, num_chunks: int = 20) -> list[list[Any]] | list[Any]:
if not data: if not data: