""" Utility functions for BrighterTrading. """ import datetime import math import numpy as np import pandas as pd def sanitize_for_json(value): """ Convert a value to a JSON-serializable type. Handles numpy types, pandas types, datetime, inf, nan, and nested structures. :param value: Any value that needs to be JSON serialized :return: JSON-serializable value """ # Handle None if value is None: return None # Handle pandas NA/NaT (safely check for scalar values only) try: if pd.isna(value) and not isinstance(value, (dict, list, tuple, set)): return None except (TypeError, ValueError): pass # pd.isna fails on some types, that's fine # Handle numpy integer types if isinstance(value, np.integer): return int(value) # Handle numpy floating types elif isinstance(value, np.floating): float_val = float(value) if math.isinf(float_val) or math.isnan(float_val): return None return float_val # Handle numpy boolean elif isinstance(value, np.bool_): return bool(value) # Handle numpy arrays elif isinstance(value, np.ndarray): return [sanitize_for_json(v) for v in value.tolist()] # Handle pandas Timestamp elif isinstance(value, pd.Timestamp): return value.isoformat() # Handle datetime objects elif isinstance(value, (datetime.datetime, datetime.date)): return value.isoformat() # Handle pandas Timedelta elif isinstance(value, pd.Timedelta): return str(value) # Handle regular floats with inf/nan elif isinstance(value, float): if math.isinf(value) or math.isnan(value): return None return value # Handle bytes elif isinstance(value, bytes): try: return value.decode('utf-8') except UnicodeDecodeError: return value.hex() # Handle nested dicts elif isinstance(value, dict): return {str(k): sanitize_for_json(v) for k, v in value.items()} # Handle lists elif isinstance(value, list): return [sanitize_for_json(v) for v in value] # Handle tuples elif isinstance(value, tuple): return tuple(sanitize_for_json(v) for v in value) # Handle sets elif isinstance(value, set): return [sanitize_for_json(v) for v in value] # Return other types as-is (str, int, bool, etc.) return value def sanitize_dict_for_json(data: dict) -> dict: """ Sanitize a dictionary for JSON serialization. Convenience wrapper around sanitize_for_json for dictionaries. :param data: Dictionary to sanitize :return: JSON-serializable dictionary """ return sanitize_for_json(data)