"""Tool registry: Plugin string → tool class.""" from __future__ import annotations from typing import Optional, Type from tools.base import BaseTool from tools.inout import InputDataTool, OutputDataTool, TextInputTool, BrowseTool from tools.preparation import ( FilterTool, FormulaTool, SelectTool, SortTool, SampleTool, UniqueTool, GenerateRowsTool, MultiRowFormulaTool, MultiFieldFormulaTool, RecordIDTool, AutoFieldTool, ) from tools.join import JoinTool, JoinMultipleTool, UnionTool, AppendFieldsTool, FindReplaceTool from tools.parse import DateTimeTool, RegExTool, TextToColumnsTool from tools.transform import SummarizeTool, CrossTabTool, TransposeTool class _PassthroughTool(BaseTool): def execute(self, inputs): df = next(iter(inputs.values())) if inputs else __import__("polars").DataFrame() return {"Output": df} class _NullTool(BaseTool): def execute(self, inputs): return {} _REGISTRY: dict[str, Type[BaseTool]] = { # In/Out "AlteryxBasePluginsGui.DbFileInput.DbFileInput": InputDataTool, "AlteryxBasePluginsGui.DbFileOutput.DbFileOutput": OutputDataTool, "AlteryxBasePluginsGui.TextInput.TextInput": TextInputTool, "AlteryxBasePluginsGui.BrowseV2.BrowseV2": BrowseTool, # Preparation "AlteryxBasePluginsGui.Filter.Filter": FilterTool, "AlteryxBasePluginsGui.Formula.Formula": FormulaTool, "AlteryxBasePluginsGui.AlteryxSelect.AlteryxSelect": SelectTool, "AlteryxBasePluginsGui.Sort.Sort": SortTool, "AlteryxBasePluginsGui.Sample.Sample": SampleTool, "AlteryxBasePluginsGui.Unique.Unique": UniqueTool, "AlteryxBasePluginsGui.GenerateRows.GenerateRows": GenerateRowsTool, "AlteryxBasePluginsGui.MultiRowFormula.MultiRowFormula": MultiRowFormulaTool, "AlteryxBasePluginsGui.MultiFieldFormula.MultiFieldFormula": MultiFieldFormulaTool, "AlteryxBasePluginsGui.RecordID.RecordID": RecordIDTool, "AlteryxBasePluginsGui.AutoField.AutoField": AutoFieldTool, # Join "AlteryxBasePluginsGui.Join.Join": JoinTool, "AlteryxBasePluginsGui.JoinMultiple.JoinMultiple": JoinMultipleTool, "AlteryxBasePluginsGui.Union.Union": UnionTool, "AlteryxBasePluginsGui.AppendFields.AppendFields": AppendFieldsTool, "AlteryxBasePluginsGui.FindReplace.FindReplace": FindReplaceTool, # Parse "AlteryxBasePluginsGui.DateTime.DateTime": DateTimeTool, "AlteryxBasePluginsGui.RegEx.RegEx": RegExTool, "AlteryxBasePluginsGui.TextToColumns.TextToColumns": TextToColumnsTool, # Transform "AlteryxSpatialPluginsGui.Summarize.Summarize": SummarizeTool, "AlteryxBasePluginsGui.CrossTab.CrossTab": CrossTabTool, "AlteryxBasePluginsGui.Transpose.Transpose": TransposeTool, # Documentation / no-op "AlteryxGuiToolkit.ToolContainer.ToolContainer": _PassthroughTool, "AlteryxGuiToolkit.TextBox.TextBox": _NullTool, "AlteryxGuiToolkit.Comment.Comment": _NullTool, "AlteryxBasePluginsGui.AlteryxAnnotation.AlteryxAnnotation": _NullTool, } def get_tool_class(plugin: str) -> Optional[Type[BaseTool]]: """Return the tool class for a given Plugin string, or None if unsupported.""" if not plugin: return None cls = _REGISTRY.get(plugin) if cls is not None: return cls # Partial match fallback — useful for minor version differences in plugin names for key, cls in _REGISTRY.items(): if plugin.endswith(key.split(".")[-1]) or key in plugin: return cls return None def register_tool(plugin: str, cls: Type[BaseTool]) -> None: """Register a custom tool class for a given Plugin string.""" _REGISTRY[plugin] = cls __all__ = ["get_tool_class", "register_tool", "BaseTool"]