From 568bbdf3e0d7144bd02ed76a47d50f8ee61c1859 Mon Sep 17 00:00:00 2001 From: Julian Risch Date: Fri, 12 Jun 2026 16:41:41 +0200 Subject: [PATCH] chore: deprecate SearchApiWebSearch + update docs Co-Authored-By: Claude Fable 5 --- .../websearch/searchapiwebsearch.mdx | 16 +++++++++++----- .../websearch/searchapiwebsearch.mdx | 16 +++++++++++----- haystack/components/websearch/searchapi.py | 11 ++++++++++- ...ate-searchapi-websearch-4299713d280ac478.yaml | 10 ++++++++++ test/components/websearch/test_searchapi.py | 10 ++++++++-- 5 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 releasenotes/notes/deprecate-searchapi-websearch-4299713d280ac478.yaml diff --git a/docs-website/docs/pipeline-components/websearch/searchapiwebsearch.mdx b/docs-website/docs/pipeline-components/websearch/searchapiwebsearch.mdx index 2c697d0315..75f9125607 100644 --- a/docs-website/docs/pipeline-components/websearch/searchapiwebsearch.mdx +++ b/docs-website/docs/pipeline-components/websearch/searchapiwebsearch.mdx @@ -17,9 +17,9 @@ Search engine using Search API. | **Mandatory init variables** | `api_key`: The SearchAPI API key. Can be set with `SEARCHAPI_API_KEY` env var. | | **Mandatory run variables** | `query`: A string with your query | | **Output variables** | `documents`: A list of documents

`links`: A list of strings of resulting links | -| **API reference** | [Websearch](/reference/websearch-api) | -| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/components/websearch/searchapi.py | -| **Package name** | `haystack-ai` | +| **API reference** | [SearchApi](/reference/integrations-searchapi) | +| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/searchapi | +| **Package name** | `searchapi-haystack` | @@ -38,12 +38,18 @@ To use [Serper Dev](https://serper.dev/?gclid=Cj0KCQiAgqGrBhDtARIsAM5s0_kPElllv3 ## Usage +Install the `searchapi-haystack` package to use the `SearchApiWebSearch` component: + +```shell +pip install searchapi-haystack +``` + ### On its own This is an example of how `SearchApiWebSearch` looks up answers to our query on the web and converts the results into a list of documents with content snippets of the results, as well as URLs as strings. ```python -from haystack.components.websearch import SearchApiWebSearch +from haystack_integrations.components.websearch.searchapi import SearchApiWebSearch web_search = SearchApiWebSearch(api_key=Secret.from_token("")) query = "What is the capital of Germany?" @@ -62,7 +68,7 @@ from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder from haystack.components.fetchers import LinkContentFetcher from haystack.components.converters import HTMLToDocument from haystack.components.generators.chat import OpenAIChatGenerator -from haystack.components.websearch import SearchApiWebSearch +from haystack_integrations.components.websearch.searchapi import SearchApiWebSearch from haystack.dataclasses import ChatMessage web_search = SearchApiWebSearch(api_key=Secret.from_token(""), top_k=2) diff --git a/docs-website/versioned_docs/version-2.30/pipeline-components/websearch/searchapiwebsearch.mdx b/docs-website/versioned_docs/version-2.30/pipeline-components/websearch/searchapiwebsearch.mdx index 2c697d0315..75f9125607 100644 --- a/docs-website/versioned_docs/version-2.30/pipeline-components/websearch/searchapiwebsearch.mdx +++ b/docs-website/versioned_docs/version-2.30/pipeline-components/websearch/searchapiwebsearch.mdx @@ -17,9 +17,9 @@ Search engine using Search API. | **Mandatory init variables** | `api_key`: The SearchAPI API key. Can be set with `SEARCHAPI_API_KEY` env var. | | **Mandatory run variables** | `query`: A string with your query | | **Output variables** | `documents`: A list of documents

`links`: A list of strings of resulting links | -| **API reference** | [Websearch](/reference/websearch-api) | -| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/components/websearch/searchapi.py | -| **Package name** | `haystack-ai` | +| **API reference** | [SearchApi](/reference/integrations-searchapi) | +| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/searchapi | +| **Package name** | `searchapi-haystack` | @@ -38,12 +38,18 @@ To use [Serper Dev](https://serper.dev/?gclid=Cj0KCQiAgqGrBhDtARIsAM5s0_kPElllv3 ## Usage +Install the `searchapi-haystack` package to use the `SearchApiWebSearch` component: + +```shell +pip install searchapi-haystack +``` + ### On its own This is an example of how `SearchApiWebSearch` looks up answers to our query on the web and converts the results into a list of documents with content snippets of the results, as well as URLs as strings. ```python -from haystack.components.websearch import SearchApiWebSearch +from haystack_integrations.components.websearch.searchapi import SearchApiWebSearch web_search = SearchApiWebSearch(api_key=Secret.from_token("")) query = "What is the capital of Germany?" @@ -62,7 +68,7 @@ from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder from haystack.components.fetchers import LinkContentFetcher from haystack.components.converters import HTMLToDocument from haystack.components.generators.chat import OpenAIChatGenerator -from haystack.components.websearch import SearchApiWebSearch +from haystack_integrations.components.websearch.searchapi import SearchApiWebSearch from haystack.dataclasses import ChatMessage web_search = SearchApiWebSearch(api_key=Secret.from_token(""), top_k=2) diff --git a/haystack/components/websearch/searchapi.py b/haystack/components/websearch/searchapi.py index 88694d7501..70cc4b72b8 100644 --- a/haystack/components/websearch/searchapi.py +++ b/haystack/components/websearch/searchapi.py @@ -2,6 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 +import warnings from typing import Any import httpx @@ -29,7 +30,7 @@ class SearchApiWebSearch: from haystack.components.websearch import SearchApiWebSearch from haystack.utils import Secret - websearch = SearchApiWebSearch(top_k=10, api_key=Secret.from_env_var("SERPERDEV_API_KEY")) + websearch = SearchApiWebSearch(top_k=10, api_key=Secret.from_env_var("SEARCHAPI_API_KEY")) results = websearch.run(query="Who is the boyfriend of Olivia Wilde?") assert results["documents"] @@ -57,6 +58,14 @@ def __init__( The default search engine is Google, however, users can change it by setting the `engine` parameter in the `search_params`. """ + warnings.warn( + "`SearchApiWebSearch` will be removed from Haystack in version 3.0, as it is moving to " + "the `searchapi-haystack` package. To continue using it, install that package with " + "`pip install searchapi-haystack` and update your import to " + "`from haystack_integrations.components.websearch.searchapi import SearchApiWebSearch`.", + FutureWarning, + stacklevel=2, + ) self.api_key = api_key self.top_k = top_k diff --git a/releasenotes/notes/deprecate-searchapi-websearch-4299713d280ac478.yaml b/releasenotes/notes/deprecate-searchapi-websearch-4299713d280ac478.yaml new file mode 100644 index 0000000000..5b1fff2591 --- /dev/null +++ b/releasenotes/notes/deprecate-searchapi-websearch-4299713d280ac478.yaml @@ -0,0 +1,10 @@ +--- +deprecations: + - | + ``SearchApiWebSearch`` is deprecated and will be removed from Haystack in version 3.0. It is moving to + the ``searchapi-haystack`` package. To continue using it, install the package with + ``pip install searchapi-haystack`` and update your import as follows: + + .. code-block:: python + + from haystack_integrations.components.websearch.searchapi import SearchApiWebSearch diff --git a/test/components/websearch/test_searchapi.py b/test/components/websearch/test_searchapi.py index 29a9a0d2be..bffd7ee1dd 100644 --- a/test/components/websearch/test_searchapi.py +++ b/test/components/websearch/test_searchapi.py @@ -518,7 +518,10 @@ def test_web_search(self) -> None: results = ws.run(query="Who is CEO of Microsoft?") documents = results["documents"] links = results["links"] - assert len(documents) == len(links) == 10 + # documents can also include answer box, knowledge graph, and related questions, so only + # links (which come from organic results) are guaranteed to be at most top_k + assert 0 < len(documents) <= 10 + assert 0 < len(links) <= 10 assert all(isinstance(doc, Document) for doc in documents) assert all(isinstance(link, str) for link in links) assert all(link.startswith("http") for link in links) @@ -534,7 +537,10 @@ async def test_web_search_async(self) -> None: results = await ws.run_async(query="Who is CEO of Microsoft?") documents = results["documents"] links = results["links"] - assert len(documents) == len(links) == 10 + # documents can also include answer box, knowledge graph, and related questions, so only + # links (which come from organic results) are guaranteed to be at most top_k + assert 0 < len(documents) <= 10 + assert 0 < len(links) <= 10 assert all(isinstance(doc, Document) for doc in documents) assert all(isinstance(link, str) for link in links) assert all(link.startswith("http") for link in links)