Files
core/utils/encoders.py

138 lines
3.8 KiB
Python
Raw Normal View History

"""
JSON encoders and utilities
"""
2024-03-06 21:57:04 +03:00
2025-07-31 18:55:59 +03:00
import json
from datetime import date, datetime
from typing import Any, Union
2025-03-20 11:55:21 +03:00
import orjson
def default_json_encoder(obj: Any) -> Any:
"""
2025-07-31 18:55:59 +03:00
Кастомный JSON энкодер для сериализации нестандартных типов.
Args:
obj: Объект для сериализации
Returns:
2025-07-31 18:55:59 +03:00
Сериализованное представление объекта
Raises:
TypeError: Если объект не может быть сериализован
"""
2025-07-31 18:55:59 +03:00
# Обработка datetime
if isinstance(obj, (datetime, date)):
return obj.isoformat()
2025-07-31 18:55:59 +03:00
serialized = False
# Обработка объектов с методом __json__
if hasattr(obj, "__json__"):
2025-07-31 18:55:59 +03:00
try:
result = obj.__json__()
serialized = True
return result
except Exception as _e:
serialized = False
# Обработка объектов с методом to_dict
if hasattr(obj, "to_dict"):
try:
result = obj.to_dict()
serialized = True
return result
except Exception as _e:
serialized = False
# Обработка объектов с методом dict
if hasattr(obj, "dict"):
try:
result = obj.dict()
serialized = True
return result
except Exception as _e:
serialized = False
# Если ни один из методов не сработал, вызываем TypeError
if not serialized:
error_text = f"Object of type {type(obj).__name__} is not JSON serializable"
raise TypeError(error_text)
def orjson_dumps(obj: Any, **kwargs: Any) -> bytes:
"""
2025-07-31 18:55:59 +03:00
Сериализация объекта с помощью orjson.
Args:
obj: Объект для сериализации
2025-07-31 18:55:59 +03:00
**kwargs: Дополнительные параметры
Returns:
2025-07-31 18:55:59 +03:00
bytes: Сериализованный объект
"""
2025-07-31 18:55:59 +03:00
return orjson.dumps(obj, default=default_json_encoder, **kwargs)
def orjson_loads(data: Union[str, bytes]) -> Any:
"""
2025-07-31 18:55:59 +03:00
Десериализация объекта с помощью orjson.
Args:
2025-07-31 18:55:59 +03:00
data: Строка или байты для десериализации
Returns:
Десериализованный объект
2025-03-20 12:52:44 +03:00
"""
return orjson.loads(data)
2025-07-31 18:55:59 +03:00
class JSONEncoder(json.JSONEncoder):
"""
Расширенный JSON энкодер с поддержкой кастомной сериализации.
"""
2025-07-31 18:55:59 +03:00
def default(self, obj: Any) -> Any:
"""
Метод для сериализации нестандартных типов.
2025-07-31 18:55:59 +03:00
Args:
obj: Объект для сериализации
2025-07-31 18:55:59 +03:00
Returns:
Сериализованное представление объекта
"""
try:
return default_json_encoder(obj)
except TypeError:
return super().default(obj)
2025-03-20 12:52:44 +03:00
2025-07-31 18:55:59 +03:00
def fast_json_dumps(obj: Any, **kwargs: Any) -> str:
2025-03-20 12:52:44 +03:00
"""
2025-07-31 18:55:59 +03:00
Быстрая сериализация объекта в JSON-строку.
2025-03-20 12:52:44 +03:00
Args:
obj: Объект для сериализации
2025-07-31 18:55:59 +03:00
**kwargs: Дополнительные параметры
Returns:
2025-07-31 18:55:59 +03:00
str: JSON-строка
"""
2025-07-31 18:55:59 +03:00
return json.dumps(obj, cls=JSONEncoder, **kwargs)
2025-07-31 18:55:59 +03:00
def fast_json_loads(data: str, **kwargs: Any) -> Any:
"""
2025-07-31 18:55:59 +03:00
Быстрая десериализация JSON-строки.
Args:
2025-07-31 18:55:59 +03:00
data: JSON-строка
**kwargs: Дополнительные параметры
Returns:
Десериализованный объект
"""
2025-07-31 18:55:59 +03:00
return json.loads(data, **kwargs)