mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-10 16:48:30 +00:00
Merge pull request #149 from tanys123/feat/serpapi-tools
feat: Add Google Search and Google Shopping tools
This commit is contained in:
@@ -43,4 +43,6 @@ from .tools import (
|
|||||||
YoutubeChannelSearchTool,
|
YoutubeChannelSearchTool,
|
||||||
YoutubeVideoSearchTool,
|
YoutubeVideoSearchTool,
|
||||||
WeaviateVectorSearchTool,
|
WeaviateVectorSearchTool,
|
||||||
|
SerpApiGoogleSearchTool,
|
||||||
|
SerpApiGoogleShoppingTool,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -52,3 +52,5 @@ from .youtube_channel_search_tool.youtube_channel_search_tool import (
|
|||||||
)
|
)
|
||||||
from .youtube_video_search_tool.youtube_video_search_tool import YoutubeVideoSearchTool
|
from .youtube_video_search_tool.youtube_video_search_tool import YoutubeVideoSearchTool
|
||||||
from .weaviate_tool.vector_search import WeaviateVectorSearchTool
|
from .weaviate_tool.vector_search import WeaviateVectorSearchTool
|
||||||
|
from .serpapi_tool.serpapi_google_search_tool import SerpApiGoogleSearchTool
|
||||||
|
from .serpapi_tool.serpapi_google_shopping_tool import SerpApiGoogleShoppingTool
|
||||||
32
src/crewai_tools/tools/serpapi_tool/README.md
Normal file
32
src/crewai_tools/tools/serpapi_tool/README.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# SerpApi Tools
|
||||||
|
|
||||||
|
## Description
|
||||||
|
[SerpApi](https://serpapi.com/) tools are built for searching information in the internet. It currently supports:
|
||||||
|
- Google Search
|
||||||
|
- Google Shopping
|
||||||
|
|
||||||
|
To successfully make use of SerpApi tools, you have to have `SERPAPI_API_KEY` set in the environment. To get the API key, register a free account at [SerpApi](https://serpapi.com/).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
To start using the SerpApi Tools, you must first install the `crewai_tools` package. This can be easily done with the following command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
pip install 'crewai[tools]'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
The following example demonstrates how to initialize the tool
|
||||||
|
|
||||||
|
### Google Search
|
||||||
|
```python
|
||||||
|
from crewai_tools import SerpApiGoogleSearchTool
|
||||||
|
|
||||||
|
tool = SerpApiGoogleSearchTool()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Google Shopping
|
||||||
|
```python
|
||||||
|
from crewai_tools import SerpApiGoogleShoppingTool
|
||||||
|
|
||||||
|
tool = SerpApiGoogleShoppingTool()
|
||||||
|
```
|
||||||
38
src/crewai_tools/tools/serpapi_tool/serpapi_base_tool.py
Normal file
38
src/crewai_tools/tools/serpapi_tool/serpapi_base_tool.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from typing import Optional, Any, Union
|
||||||
|
|
||||||
|
from crewai.tools import BaseTool
|
||||||
|
|
||||||
|
class SerpApiBaseTool(BaseTool):
|
||||||
|
"""Base class for SerpApi functionality with shared capabilities."""
|
||||||
|
|
||||||
|
client: Optional[Any] = None
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from serpapi import Client
|
||||||
|
except ImportError:
|
||||||
|
raise ImportError(
|
||||||
|
"`serpapi` package not found, please install with `pip install serpapi`"
|
||||||
|
)
|
||||||
|
api_key = os.getenv("SERPAPI_API_KEY")
|
||||||
|
if not api_key:
|
||||||
|
raise ValueError(
|
||||||
|
"Missing API key, you can get the key from https://serpapi.com/manage-api-key"
|
||||||
|
)
|
||||||
|
self.client = Client(api_key=api_key)
|
||||||
|
|
||||||
|
def _omit_fields(self, data: Union[dict, list], omit_patterns: list[str]) -> None:
|
||||||
|
if isinstance(data, dict):
|
||||||
|
for field in list(data.keys()):
|
||||||
|
if any(re.compile(p).match(field) for p in omit_patterns):
|
||||||
|
data.pop(field, None)
|
||||||
|
else:
|
||||||
|
if isinstance(data[field], (dict, list)):
|
||||||
|
self._omit_fields(data[field], omit_patterns)
|
||||||
|
elif isinstance(data, list):
|
||||||
|
for item in data:
|
||||||
|
self._omit_fields(item, omit_patterns)
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
from typing import Any, Type, Optional
|
||||||
|
|
||||||
|
import re
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from .serpapi_base_tool import SerpApiBaseTool
|
||||||
|
from serpapi import HTTPError
|
||||||
|
|
||||||
|
class SerpApiGoogleSearchToolSchema(BaseModel):
|
||||||
|
"""Input for Google Search."""
|
||||||
|
search_query: str = Field(..., description="Mandatory search query you want to use to Google search.")
|
||||||
|
location: Optional[str] = Field(None, description="Location you want the search to be performed in.")
|
||||||
|
|
||||||
|
class SerpApiGoogleSearchTool(SerpApiBaseTool):
|
||||||
|
name: str = "Google Search"
|
||||||
|
description: str = (
|
||||||
|
"A tool to perform to perform a Google search with a search_query."
|
||||||
|
)
|
||||||
|
args_schema: Type[BaseModel] = SerpApiGoogleSearchToolSchema
|
||||||
|
|
||||||
|
def _run(
|
||||||
|
self,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Any:
|
||||||
|
try:
|
||||||
|
results = self.client.search({
|
||||||
|
"q": kwargs.get("search_query"),
|
||||||
|
"location": kwargs.get("location"),
|
||||||
|
}).as_dict()
|
||||||
|
|
||||||
|
self._omit_fields(
|
||||||
|
results,
|
||||||
|
[r"search_metadata", r"search_parameters", r"serpapi_.+", r".+_token", r"displayed_link", r"pagination"]
|
||||||
|
)
|
||||||
|
|
||||||
|
return results
|
||||||
|
except HTTPError as e:
|
||||||
|
return f"An error occurred: {str(e)}. Some parameters may be invalid."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
from typing import Any, Type, Optional
|
||||||
|
|
||||||
|
import re
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from .serpapi_base_tool import SerpApiBaseTool
|
||||||
|
from serpapi import HTTPError
|
||||||
|
|
||||||
|
class SerpApiGoogleShoppingToolSchema(BaseModel):
|
||||||
|
"""Input for Google Shopping."""
|
||||||
|
search_query: str = Field(..., description="Mandatory search query you want to use to Google shopping.")
|
||||||
|
location: Optional[str] = Field(None, description="Location you want the search to be performed in.")
|
||||||
|
|
||||||
|
|
||||||
|
class SerpApiGoogleShoppingTool(SerpApiBaseTool):
|
||||||
|
name: str = "Google Shopping"
|
||||||
|
description: str = (
|
||||||
|
"A tool to perform search on Google shopping with a search_query."
|
||||||
|
)
|
||||||
|
args_schema: Type[BaseModel] = SerpApiGoogleShoppingToolSchema
|
||||||
|
|
||||||
|
def _run(
|
||||||
|
self,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Any:
|
||||||
|
try:
|
||||||
|
results = self.client.search({
|
||||||
|
"engine": "google_shopping",
|
||||||
|
"q": kwargs.get("search_query"),
|
||||||
|
"location": kwargs.get("location")
|
||||||
|
}).as_dict()
|
||||||
|
|
||||||
|
self._omit_fields(
|
||||||
|
results,
|
||||||
|
[r"search_metadata", r"search_parameters", r"serpapi_.+", r"filters", r"pagination"]
|
||||||
|
)
|
||||||
|
|
||||||
|
return results
|
||||||
|
except HTTPError as e:
|
||||||
|
return f"An error occurred: {str(e)}. Some parameters may be invalid."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user