import json import datetime from decimal import Decimal from uuid import UUID class CustomJSONEncoder(json.JSONEncoder): """ Custom JSON encoder that handles various Python types that aren't JSON serializable by default: - datetime.datetime, datetime.date, datetime.time - Decimal - UUID - Sets - Any object with a to_json method - Custom objects with __dict__ attribute """ def default(self, obj): # Handle datetime objects if isinstance(obj, (datetime.datetime, datetime.date)): return obj.isoformat() # Handle time objects if isinstance(obj, datetime.time): return obj.isoformat() # Handle Decimal objects if isinstance(obj, Decimal): return float(obj) # Handle UUID objects if isinstance(obj, UUID): return str(obj) # Handle set objects if isinstance(obj, set): return list(obj) # Handle objects that have implemented a to_json method if hasattr(obj, "to_json"): return obj.to_json() # Try to convert the object to a dict try: return obj.__dict__ except AttributeError: pass # Let the base class handle it or raise TypeError return super().default(obj) def serialize_to_json(data, pretty=False): """ Serialize Python data to JSON string, handling various Python types. Args: data: The Python object to serialize pretty (bool): Whether to format the JSON with indentation for readability Returns: str: JSON string representation of the data """ indent = 2 if pretty else None return json.dumps(data, cls=CustomJSONEncoder, indent=indent)