feat: adds Wikipedia Component and deprecates the wikipedia API tool component (#5871)

* update

* Update test_wikipedia_api.py

* [autofix.ci] apply automated fixes

* Update src/backend/base/langflow/components/tools/wikipedia.py

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>

* Update test_wikipedia_api.py

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
Edwin Jose 2025-01-22 13:29:53 -05:00 • committed by GitHub
commit dcd68c5f4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 141 additions and 75 deletions

View file

@ -25,6 +25,7 @@ from .serp_api import SerpAPIComponent
from .tavily import TavilySearchComponent from .tavily import TavilySearchComponent
from .tavily_search import TavilySearchToolComponent from .tavily_search import TavilySearchToolComponent
from .wikidata_api import WikidataAPIComponent from .wikidata_api import WikidataAPIComponent
from .wikipedia import WikipediaComponent
from .wikipedia_api import WikipediaAPIComponent from .wikipedia_api import WikipediaAPIComponent
from .wolfram_alpha_api import WolframAlphaAPIComponent from .wolfram_alpha_api import WolframAlphaAPIComponent
from .yahoo import YfinanceComponent from .yahoo import YfinanceComponent
@ -62,6 +63,7 @@ __all__ = [
"TavilySearchToolComponent", "TavilySearchToolComponent",
"WikidataAPIComponent", "WikidataAPIComponent",
"WikipediaAPIComponent", "WikipediaAPIComponent",
"WikipediaComponent",
"WolframAlphaAPIComponent", "WolframAlphaAPIComponent",
"YfinanceComponent", "YfinanceComponent",
"YfinanceToolComponent", "YfinanceToolComponent",

View file

@ -0,0 +1,55 @@
from langchain_community.utilities.wikipedia import WikipediaAPIWrapper
from langflow.custom import Component
from langflow.inputs import BoolInput, IntInput, MessageTextInput, MultilineInput
from langflow.io import Output
from langflow.schema import Data
from langflow.schema.message import Message
class WikipediaComponent(Component):
display_name = "Wikipedia"
description = "Call Wikipedia API."
icon = "Wikipedia"
inputs = [
MultilineInput(
name="input_value",
display_name="Input",
tool_mode=True,
),
MessageTextInput(name="lang", display_name="Language", value="en"),
IntInput(name="k", display_name="Number of results", value=4, required=True),
BoolInput(name="load_all_available_meta", display_name="Load all available meta", value=False, advanced=True),
IntInput(
name="doc_content_chars_max", display_name="Document content characters max", value=4000, advanced=True
),
]
outputs = [
Output(display_name="Data", name="data", method="fetch_content"),
Output(display_name="Text", name="text", method="fetch_content_text"),
]
def fetch_content(self) -> list[Data]:
wrapper = self._build_wrapper()
docs = wrapper.load(self.input_value)
data = [Data.from_document(doc) for doc in docs]
self.status = data
return data
def fetch_content_text(self) -> Message:
data = self.fetch_content()
result_string = ""
for item in data:
result_string += item.text + "\n"
self.status = result_string
return Message(text=result_string)
def _build_wrapper(self) -> WikipediaAPIWrapper:
return WikipediaAPIWrapper(
top_k_results=self.k,
lang=self.lang,
load_all_available_meta=self.load_all_available_meta,
doc_content_chars_max=self.doc_content_chars_max,
)

View file

@ -1,23 +1,25 @@
from typing import cast
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities.wikipedia import WikipediaAPIWrapper from langchain_community.utilities.wikipedia import WikipediaAPIWrapper
from langflow.custom import Component from langflow.base.langchain_utilities.model import LCToolComponent
from langflow.field_typing import Tool
from langflow.inputs import BoolInput, IntInput, MessageTextInput, MultilineInput from langflow.inputs import BoolInput, IntInput, MessageTextInput, MultilineInput
from langflow.io import Output
from langflow.schema import Data from langflow.schema import Data
from langflow.schema.message import Message
class WikipediaAPIComponent(Component): class WikipediaAPIComponent(LCToolComponent):
display_name = "Wikipedia API" display_name = "Wikipedia API [Deprecated]"
description = "Call Wikipedia API." description = "Call Wikipedia API."
name = "WikipediaAPI" name = "WikipediaAPI"
icon = "Wikipedia" icon = "Wikipedia"
legacy = True
inputs = [ inputs = [
MultilineInput( MultilineInput(
name="input_value", name="input_value",
display_name="Input", display_name="Input",
tool_mode=True,
), ),
MessageTextInput(name="lang", display_name="Language", value="en"), MessageTextInput(name="lang", display_name="Language", value="en"),
IntInput(name="k", display_name="Number of results", value=4, required=True), IntInput(name="k", display_name="Number of results", value=4, required=True),
@ -27,25 +29,16 @@ class WikipediaAPIComponent(Component):
), ),
] ]
outputs = [ def run_model(self) -> list[Data]:
Output(display_name="Data", name="data", method="fetch_content"),
Output(display_name="Text", name="text", method="fetch_content_text"),
]
def fetch_content(self) -> list[Data]:
wrapper = self._build_wrapper() wrapper = self._build_wrapper()
docs = wrapper.load(self.input_value) docs = wrapper.load(self.input_value)
data = [Data.from_document(doc) for doc in docs] data = [Data.from_document(doc) for doc in docs]
self.status = data self.status = data
return data return data
def fetch_content_text(self) -> Message: def build_tool(self) -> Tool:
data = self.fetch_content() wrapper = self._build_wrapper()
result_string = "" return cast("Tool", WikipediaQueryRun(api_wrapper=wrapper))
for item in data:
result_string += item.text + "\n"
self.status = result_string
return Message(text=result_string)
def _build_wrapper(self) -> WikipediaAPIWrapper: def _build_wrapper(self) -> WikipediaAPIWrapper:
return WikipediaAPIWrapper( return WikipediaAPIWrapper(

View file

@ -1,24 +1,45 @@
from unittest.mock import MagicMock from unittest.mock import MagicMock
import pytest import pytest
from langflow.components.tools import WikipediaAPIComponent from langflow.components.tools import WikipediaComponent
from langflow.custom import Component from langflow.custom import Component
from langflow.custom.utils import build_custom_component_template from langflow.custom.utils import build_custom_component_template
from langflow.schema import Data from langflow.schema import Data
from langflow.schema.message import Message from langflow.schema.message import Message
# Import the base test class
from tests.base import ComponentTestBaseWithoutClient
def test_wikipedia_initialization():
component = WikipediaAPIComponent() class TestWikipediaComponent(ComponentTestBaseWithoutClient):
assert component.display_name == "Wikipedia API" @pytest.fixture
def component_class(self):
"""Fixture to create a WikipediaComponent instance."""
return WikipediaComponent
@pytest.fixture
def default_kwargs(self):
"""Return the default kwargs for the component."""
return {
"input_value": "test query",
"lang": "en",
"k": 3,
}
@pytest.fixture
def file_names_mapping(self):
"""Return an empty list since this component doesn't have version-specific files."""
return []
def test_wikipedia_initialization(self, component_class):
component = component_class()
assert component.display_name == "Wikipedia"
assert component.description == "Call Wikipedia API." assert component.description == "Call Wikipedia API."
assert component.icon == "Wikipedia" assert component.icon == "Wikipedia"
def test_wikipedia_template(self, component_class):
def test_wikipedia_template(): component = component_class()
wikipedia = WikipediaAPIComponent() frontend_node, _ = build_custom_component_template(Component(_code=component._code))
component = Component(_code=wikipedia._code)
frontend_node, _ = build_custom_component_template(component)
# Verify basic structure # Verify basic structure
assert isinstance(frontend_node, dict) assert isinstance(frontend_node, dict)
@ -32,14 +53,12 @@ def test_wikipedia_template():
for input_name in expected_inputs: for input_name in expected_inputs:
assert input_name in input_names assert input_name in input_names
@pytest.fixture @pytest.fixture
def mock_wikipedia_wrapper(mocker): def mock_wikipedia_wrapper(self, mocker):
return mocker.patch("langchain_community.utilities.wikipedia.WikipediaAPIWrapper") return mocker.patch("langchain_community.utilities.wikipedia.WikipediaAPIWrapper")
def test_fetch_content(self, component_class, mock_wikipedia_wrapper):
def test_fetch_content(mock_wikipedia_wrapper): component = component_class()
component = WikipediaAPIComponent()
component.input_value = "test query" component.input_value = "test query"
component.k = 3 component.k = 3
component.lang = "en" component.lang = "en"
@ -64,9 +83,8 @@ def test_fetch_content(mock_wikipedia_wrapper):
assert len(result) == 1 assert len(result) == 1
assert result[0].text == "Test content" assert result[0].text == "Test content"
def test_fetch_content_text(self, component_class):
def test_fetch_content_text(): component = component_class()
component = WikipediaAPIComponent()
component.fetch_content = MagicMock(return_value=[Data(text="First result"), Data(text="Second result")]) component.fetch_content = MagicMock(return_value=[Data(text="First result"), Data(text="Second result")])
result = component.fetch_content_text() result = component.fetch_content_text()
@ -74,10 +92,8 @@ def test_fetch_content_text():
assert isinstance(result, Message) assert isinstance(result, Message)
assert result.text == "First result\nSecond result\n" assert result.text == "First result\nSecond result\n"
def test_wikipedia_error_handling(self, component_class):
def test_wikipedia_error_handling(): component = component_class()
component = WikipediaAPIComponent()
# Mock _build_wrapper to raise exception # Mock _build_wrapper to raise exception
component._build_wrapper = MagicMock(side_effect=Exception("API Error")) component._build_wrapper = MagicMock(side_effect=Exception("API Error"))