Source code for streamlit_rich_message_history.builtin_components

"""
Built-in component registration for the streamlit_rich_message_history package.
"""

import streamlit as st

from .enums import ComponentType
from .registry import ComponentRegistry


# Add an initial initialization function that can be called when components.py is loaded.
[docs] def register_builtin_components(): """Register all built-in component detectors and renderers.""" # Text def detect_text(content, kwargs): if not isinstance(content, str): return False return not any(kwargs.get(k) for k in ["is_error", "is_code", "is_html"]) ComponentRegistry.register_detector(ComponentType.TEXT, detect_text) ComponentRegistry.register_renderer(ComponentType.TEXT, lambda c, k: st.markdown(c)) # Error ComponentRegistry.register_detector( ComponentType.ERROR, lambda c, k: isinstance(c, str) and k.get("is_error", False), ) ComponentRegistry.register_renderer(ComponentType.ERROR, lambda c, k: st.error(c)) # Code ComponentRegistry.register_detector( ComponentType.CODE, lambda c, k: isinstance(c, str) and k.get("is_code", False) ) ComponentRegistry.register_renderer( ComponentType.CODE, lambda c, k: st.code(c, language=k.get("language", "python")), ) # HTML ComponentRegistry.register_detector( ComponentType.HTML, lambda c, k: isinstance(c, str) and k.get("is_html", False) ) ComponentRegistry.register_renderer( ComponentType.HTML, lambda c, k: st.html( c, height=k.get("height"), scrolling=k.get("scrolling", False) ), ) # Number def detect_number(content, kwargs): return isinstance(content, (int, float)) and not kwargs.get("is_metric", False) ComponentRegistry.register_detector(ComponentType.NUMBER, detect_number) def render_number(content, kwargs): format_str = kwargs.get("format", None) title = kwargs.get("title", "Result") if format_str: st.write(f"{title}: {format_str.format(content)}") else: st.write(f"{title}: {content}") ComponentRegistry.register_renderer(ComponentType.NUMBER, render_number) # Metric ComponentRegistry.register_detector( ComponentType.METRIC, lambda c, k: k.get("is_metric", False) ) def render_metric(content, kwargs): st.metric( label=kwargs.get("title", "Metric"), value=content, delta=kwargs.get("delta"), delta_color=kwargs.get("delta_color", "normal"), ) ComponentRegistry.register_renderer(ComponentType.METRIC, render_metric) # Table ComponentRegistry.register_detector( ComponentType.TABLE, lambda c, k: k.get("is_table", False) ) ComponentRegistry.register_renderer(ComponentType.TABLE, lambda c, k: st.table(c)) # JSON ComponentRegistry.register_detector( ComponentType.JSON, lambda c, k: isinstance(c, (dict, list)) and k.get("is_json", False), ) ComponentRegistry.register_renderer(ComponentType.JSON, lambda c, k: st.json(c)) # Collections ComponentRegistry.register_detector( ComponentType.LIST, lambda c, k: isinstance(c, list) and not k.get("is_table") and not k.get("is_json"), ) ComponentRegistry.register_detector( ComponentType.TUPLE, lambda c, k: isinstance(c, tuple) and not k.get("is_table") ) ComponentRegistry.register_detector( ComponentType.DICT, lambda c, k: isinstance(c, dict) and not k.get("is_json") )
# The rendering of collections relies on the MessageComponent class internal loop. # To keep dependencies light, we will let pandas, matplotlib, and plotly be registered # lazily or through safe imports.
[docs] def register_pandas_components(): """Register Pandas related components.""" try: import pandas as pd ComponentRegistry.register_detector( ComponentType.DATAFRAME, lambda c, k: isinstance(c, pd.DataFrame) ) ComponentRegistry.register_renderer( ComponentType.DATAFRAME, lambda c, k: st.dataframe( c, use_container_width=k.get("use_container_width", True), height=k.get("height"), ), ) ComponentRegistry.register_detector( ComponentType.SERIES, lambda c, k: isinstance(c, pd.Series) ) ComponentRegistry.register_renderer( ComponentType.SERIES, lambda c, k: st.dataframe(c.to_frame()) ) except ImportError: pass
[docs] def register_matplotlib_components(): """Register Matplotlib related components.""" try: import matplotlib.pyplot as plt ComponentRegistry.register_detector( ComponentType.MATPLOTLIB_FIGURE, lambda c, k: isinstance(c, plt.Figure) ) ComponentRegistry.register_renderer( ComponentType.MATPLOTLIB_FIGURE, lambda c, k: st.pyplot(c) ) except ImportError: pass
[docs] def register_plotly_components(): """Register Plotly related components.""" try: import plotly.graph_objects as go def detect_plotly(c, k): if isinstance(c, go.Figure): return True if isinstance(c, dict) and isinstance( getattr(c, "data", None), (list, tuple) ): return True return False ComponentRegistry.register_detector(ComponentType.PLOTLY_FIGURE, detect_plotly) ComponentRegistry.register_renderer( ComponentType.PLOTLY_FIGURE, lambda c, k: st.plotly_chart( c, use_container_width=k.get("use_container_width", True), height=k.get("height"), ), ) except ImportError: pass
[docs] def initialize_builtins(): register_builtin_components() register_pandas_components() register_matplotlib_components() register_plotly_components()