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)