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 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: