# radian/components/base_component.py from abc import ABC, abstractmethod from typing import Dict, Any, Optional import tkinter as tk # A type alias for configuration dictionaries to improve code readability. ConfigType = Dict[str, Any] class BaseComponent(ABC): """ Abstract Base Class for all RADIAN components. This class defines a common interface (a "contract") that each external tool must implement via an adapter class to be managed by the RADIAN framework. It ensures that RADIAN can interact with any component in a standardized way. """ def __init__(self): # Each component instance will manage its own configuration. self.config: ConfigType = self.get_default_config() @abstractmethod def get_name(self) -> str: """ Returns the user-friendly name of the component. This name will be displayed in the RADIAN GUI. Returns: The string name of the component. """ pass @abstractmethod def get_description(self) -> str: """ Returns a brief description of what the component does. This can be used for tooltips or help text in the GUI. Returns: A short string description. """ pass @abstractmethod def get_default_config(self) -> ConfigType: """ Returns a dictionary with the default configuration parameters for the component. This is used to initialize the component's state. Returns: A dictionary representing the default configuration. """ pass def set_config(self, config: ConfigType) -> None: """ Applies a new configuration to the component. This method can be overridden if complex logic is needed when setting a configuration. Args: config: A dictionary with the configuration to apply. """ self.config = config def get_current_config(self) -> ConfigType: """ Returns the current configuration of the component. Returns: The current configuration dictionary. """ return self.config @abstractmethod def get_config_ui(self, parent: tk.Frame) -> Optional[tk.Frame]: """ Creates and returns a Tkinter Frame containing the component's specific configuration UI elements. RADIAN will place this frame in the main content area. If a component has no configurable parameters, this method can return None. Args: parent: The parent Tkinter widget (a Frame) where the UI should be built. Returns: A Tkinter Frame with all the necessary configuration widgets, or None if no GUI configuration is needed. """ pass @abstractmethod def run(self, input_data: Optional[Any] = None) -> Any: """ Executes the main logic of the component. This is the core function for workflow execution. It can accept data from a previous component and return data for the next one. Args: input_data: Data passed from a previous component in a workflow. Returns: The output of the component's processing, to be passed to the next component in a workflow, or None if there is no output. """ pass def get_icon_path(self) -> Optional[str]: """ Returns the absolute path to the component's icon file (e.g., .png, .ico). The recommended size is 32x32 or 64x64. If not implemented or returns None, a default icon will be used. Returns: A string representing the absolute path to the icon, or None. """ return None