Source code for streamlit_rich_message_history.enums

"""
Component type definitions and registry for the streamlit_rich_message_history package.

This module defines the core component types and provides a registry system
for extending the package with custom component types, detectors, and renderers.
"""

from enum import Enum
from typing import Any, Callable, Dict, Optional


[docs] class ComponentType(Enum): """ Enum defining the possible message component types. These types correspond to different ways content can be displayed in messages, such as text, dataframes, charts, etc. Attributes: TEXT: Plain text content DATAFRAME: Pandas DataFrame display SERIES: Pandas Series display MATPLOTLIB_FIGURE: Matplotlib plot PLOTLY_FIGURE: Plotly chart NUMBER: Numeric value ERROR: Error message CODE: Code snippet with syntax highlighting METRIC: Metric with optional delta TABLE: Static table display JSON: JSON data viewer HTML: HTML content LIST: List of items TUPLE: Tuple of items DICT: Dictionary of items """ TEXT = "text" DATAFRAME = "dataframe" SERIES = "series" MATPLOTLIB_FIGURE = "matplotlib_figure" PLOTLY_FIGURE = "plotly_figure" NUMBER = "number" ERROR = "error" CODE = "code" METRIC = "metric" TABLE = "table" JSON = "json" HTML = "html" LIST = "list" TUPLE = "tuple" DICT = "dict"
[docs] class ComponentRegistry: """ Registry to manage custom component types, detectors, and renderers. This class provides static methods for registering and retrieving: - Custom component types (extending ComponentType) - Type detection functions that identify content types - Rendering functions that display specific content types The registry is a central point for extending the package with custom components. """ _custom_types: Dict[str, ComponentType] = {} _type_detectors: Dict[ComponentType, Callable[[Any, Dict[str, Any]], bool]] = {} _renderers: Dict[ComponentType, Callable[[Any, Dict[str, Any]], None]] = {}
[docs] @classmethod def register_component_type(cls, name: str) -> ComponentType: """ Register a new component type with the given name. If a component type with this name already exists, returns the existing type with a warning instead of raising an exception. Args: name: String identifier for the new component type Returns: ComponentType: The newly created component type or existing component type Examples: >>> IMAGE_TYPE = ComponentRegistry.register_component_type("image") >>> # IMAGE_TYPE can now be used like a standard ComponentType >>> # Registering the same type again will return the existing type >>> SAME_IMAGE_TYPE = ComponentRegistry.register_component_type("image") >>> # A warning will be printed and SAME_IMAGE_TYPE == IMAGE_TYPE """ # Check if the type already exists existing_types = [t.value for t in ComponentType] + list( cls._custom_types.keys() ) if name in existing_types: import warnings warnings.warn( f"Component type '{name}' already exists, returning existing type" ) # Return the existing type if name in cls._custom_types: return cls._custom_types[name] else: # Find and return the enum value from ComponentType for t in ComponentType: if t.value == name: return t # Create a new ComponentType dynamically custom_type = object.__new__(ComponentType) custom_type._name_ = name.upper() custom_type._value_ = name cls._custom_types[name] = custom_type return custom_type
[docs] @classmethod def register_detector( cls, comp_type: ComponentType, detector: Callable[[Any, Dict[str, Any]], bool] ) -> None: """ Register a detector function for a component type. The detector function determines if content should be treated as this component type. Args: comp_type: The component type to register a detector for detector: Function that takes content and kwargs and returns True if the content should be handled as this component type Examples: >>> def image_detector(content, kwargs): return isinstance(content, PIL.Image.Image) >>> ComponentRegistry.register_detector(IMAGE_TYPE, image_detector) """ cls._type_detectors[comp_type] = detector
[docs] @classmethod def register_renderer( cls, comp_type: ComponentType, renderer: Callable[[Any, Dict[str, Any]], None] ) -> None: """ Register a renderer function for a component type. The renderer function handles displaying the content in a Streamlit app. Args: comp_type: The component type to register a renderer for renderer: Function that takes content and kwargs and renders it in Streamlit Examples: >>> def image_renderer(content, kwargs): st.image(content, **{k: v for k, v in kwargs.items() if k in ['caption', 'width', 'use_column_width']}) >>> ComponentRegistry.register_renderer(IMAGE_TYPE, image_renderer) """ cls._renderers[comp_type] = renderer
[docs] @classmethod def get_custom_type(cls, name: str) -> Optional[ComponentType]: """ Get a custom component type by name. Args: name: String identifier of the component type Returns: ComponentType: The component type if found, None otherwise """ return cls._custom_types.get(name)
[docs] @classmethod def get_all_types(cls) -> list: """ Get all component types (built-in and custom). Returns: list: List containing all ComponentType values """ return list(ComponentType) + list(cls._custom_types.values())
[docs] @classmethod def get_detector(cls, comp_type: ComponentType) -> Optional[Callable]: """ Get the detector function for a component type. Args: comp_type: The component type to get the detector for Returns: Callable: The detector function if registered, None otherwise """ return cls._type_detectors.get(comp_type)
[docs] @classmethod def get_renderer(cls, comp_type: ComponentType) -> Optional[Callable]: """ Get the renderer function for a component type. Args: comp_type: The component type to get the renderer for Returns: Callable: The renderer function if registered, None otherwise """ return cls._renderers.get(comp_type)