import base64 from io import BytesIO from PIL import Image def decode_chart(charts: dict): """ Decodes base64 string charts into PIL Image objects. Also converts Matplotlib Figures into PIL Image objects. If already decoded or None, returns as is. """ if not isinstance(charts, dict): return {} result = {} for name, img_str in charts.items(): # Case 1: Base64 String (from DB) if isinstance(img_str, str) and not img_str.startswith(" dict: """ Ensures all charts in the dict are JSON-serializable base64 strings. Handles: - str: Assumed to be already base64. - plt.Figure: Serialized using savefig. - PIL.Image: Serialized using img.save. """ if not isinstance(charts, dict): return {} result = {} for name, val in charts.items(): if val is None: continue if isinstance(val, str): # already serialized result[name] = val elif hasattr(val, "savefig"): # Matplotlib Figure result[name] = figure_to_base64(val) elif hasattr(val, "save"): # PIL Image try: buf = BytesIO() val.save(buf, format="png") buf.seek(0) result[name] = base64.b64encode(buf.getvalue()).decode("utf-8") except Exception as e: import logging logging.getLogger(__name__).error(f"Failed to serialize PIL image for {name}: {e}") result[name] = None else: result[name] = str(val) return result