Source code for src.openCHA.tasks.serpapi

"""
A part of the task implementation is borrowed from LangChain:
https://github.com/langchain-ai/langchain
"""
from typing import Any
from typing import Dict
from typing import List
from typing import Optional

import aiohttp
from openCHA.tasks import BaseTask
from openCHA.utils import get_from_dict_or_env
from pydantic import Extra
from pydantic import Field
from pydantic import model_validator


[docs] class SerpAPI(BaseTask): """ **Description:** This code defines a class named SerpAPI, which is a specific implementation of the abstract BaseTask class. The SerpAPI class represents a task that utilizes the SerpAPI (Google Search API) to perform internet searches and retrieve relevant information. """ name: str = "serpapi" chat_name: str = "InternetSearchSerp" description: str = ( "A low-cost Google Search API." "Useful for when you need to answer questions about current events." ) dependencies: List[str] = [] inputs: List[str] = ["It should be a search query."] outputs: List[str] = [ "It returns a json object containing key: **url**. For example: {'url': 'http://google.com'}" ] output_type: bool = False search_engine: Any = None #: :meta private: params: Dict = Field( default={ "engine": "google", "google_domain": "google.com", "gl": "us", "hl": "en", } ) serpapi_api_key: Optional[str] = None aiosession: Optional[aiohttp.ClientSession] = None
[docs] @model_validator(mode="before") def validate_environment(cls, values: Dict) -> Dict: """ Validate that api key and python package exists in environment. Args: values (Dict): The dictionary of attribute values. Return: Dict: The updated dictionary of attribute values. Raise: ValueError: If the SerpAPI python package is not installed. """ serpapi_api_key = get_from_dict_or_env( values, "serpapi_api_key", "SERPAPI_API_KEY" ) values["serpapi_api_key"] = serpapi_api_key try: from serpapi import GoogleSearch values["search_engine"] = GoogleSearch except ImportError: raise ValueError( "Could not import serpapi python package. " "Please install it with `pip install google-search-results`." ) return values
[docs] def get_params(self, query: str) -> Dict[str, str]: """ Get parameters for SerpAPI. Args: query (str): The search query. Return: Dict[str, str]: The parameters for the SerpAPI. """ _params = { "api_key": self.serpapi_api_key, "q": query, } params = {**self.params, **_params} return params
[docs] def results(self, query: str) -> Dict: """ Run query through SerpAPI and return the raw result. Args: query (str): The search query. Return: Dict: The raw result from the SerpAPI. """ params = self.get_params(query) search = self.search_engine(params) res = search.get_dict() return res
[docs] @staticmethod def _process_response(res: Dict) -> str: """ Process response from SerpAPI. Args: res (Dict): The raw response from the SerpAPI. Return: str: Processed information from the SerpAPI response. """ try: if "answer_box" in res: toret = { "url": res["answer_box"]["link"], # "metadata": res["answer_box"]["snippet"] } else: toret = { "url": res["organic_results"][0]["link"], # "metadata": res["organic_results"][0]["snippet"] } except KeyError: return "Could not get the proper response from the search. Try another search query." return toret
[docs] def _execute( self, inputs: List[Any] = None, ) -> str: """ Run query through SerpAPI and parse result. Args: input (str): The input, which should be a search query. Return: str: The parsed result from the SerpAPI. """ if len(inputs) == 0: return "" return self._process_response(self.results(inputs[0]))
[docs] def explain( self, ) -> str: """ Provide an explanation of the task. Return: str: Explanation of the SerpAPI task. """ return ( "This task searched in the internet using google search engine, returns the url" "and the first top result of the google search." )