Source code for langchain_community.utilities.google_serper
"""Util that calls Google Search using the Serper.dev API."""fromtypingimportAny,Dict,List,Optionalimportaiohttpimportrequestsfromlangchain_core.utilsimportget_from_dict_or_envfrompydanticimportBaseModel,ConfigDict,model_validatorfromtyping_extensionsimportLiteral
[docs]classGoogleSerperAPIWrapper(BaseModel):"""Wrapper around the Serper.dev Google Search API. You can create a free API key at https://serper.dev. To use, you should have the environment variable ``SERPER_API_KEY`` set with your API key, or pass `serper_api_key` as a named parameter to the constructor. Example: .. code-block:: python from langchain_community.utilities import GoogleSerperAPIWrapper google_serper = GoogleSerperAPIWrapper() """k:int=10gl:str="us"hl:str="en"# "places" and "images" is available from Serper but not implemented in the# parser of run(). They can be used in results()type:Literal["news","search","places","images"]="search"result_key_for_type:dict={"news":"news","places":"places","images":"images","search":"organic",}tbs:Optional[str]=Noneserper_api_key:Optional[str]=Noneaiosession:Optional[aiohttp.ClientSession]=Nonemodel_config=ConfigDict(arbitrary_types_allowed=True,)@model_validator(mode="before")@classmethoddefvalidate_environment(cls,values:Dict)->Any:"""Validate that api key exists in environment."""serper_api_key=get_from_dict_or_env(values,"serper_api_key","SERPER_API_KEY")values["serper_api_key"]=serper_api_keyreturnvalues
[docs]defresults(self,query:str,**kwargs:Any)->Dict:"""Run query through GoogleSearch."""returnself._google_serper_api_results(query,gl=self.gl,hl=self.hl,num=self.k,tbs=self.tbs,search_type=self.type,**kwargs,)
[docs]defrun(self,query:str,**kwargs:Any)->str:"""Run query through GoogleSearch and parse result."""results=self._google_serper_api_results(query,gl=self.gl,hl=self.hl,num=self.k,tbs=self.tbs,search_type=self.type,**kwargs,)returnself._parse_results(results)
[docs]asyncdefaresults(self,query:str,**kwargs:Any)->Dict:"""Run query through GoogleSearch."""results=awaitself._async_google_serper_search_results(query,gl=self.gl,hl=self.hl,num=self.k,search_type=self.type,tbs=self.tbs,**kwargs,)returnresults
[docs]asyncdefarun(self,query:str,**kwargs:Any)->str:"""Run query through GoogleSearch and parse result async."""results=awaitself._async_google_serper_search_results(query,gl=self.gl,hl=self.hl,num=self.k,search_type=self.type,tbs=self.tbs,**kwargs,)returnself._parse_results(results)
def_parse_snippets(self,results:dict)->List[str]:snippets=[]ifresults.get("answerBox"):answer_box=results.get("answerBox",{})ifanswer_box.get("answer"):return[answer_box.get("answer")]elifanswer_box.get("snippet"):return[answer_box.get("snippet").replace("\n"," ")]elifanswer_box.get("snippetHighlighted"):returnanswer_box.get("snippetHighlighted")ifresults.get("knowledgeGraph"):kg=results.get("knowledgeGraph",{})title=kg.get("title")entity_type=kg.get("type")ifentity_type:snippets.append(f"{title}: {entity_type}.")description=kg.get("description")ifdescription:snippets.append(description)forattribute,valueinkg.get("attributes",{}).items():snippets.append(f"{title}{attribute}: {value}.")forresultinresults[self.result_key_for_type[self.type]][:self.k]:if"snippet"inresult:snippets.append(result["snippet"])forattribute,valueinresult.get("attributes",{}).items():snippets.append(f"{attribute}: {value}.")iflen(snippets)==0:return["No good Google Search Result was found"]returnsnippetsdef_parse_results(self,results:dict)->str:return" ".join(self._parse_snippets(results))def_google_serper_api_results(self,search_term:str,search_type:str="search",**kwargs:Any)->dict:headers={"X-API-KEY":self.serper_api_keyor"","Content-Type":"application/json",}params={"q":search_term,**{key:valueforkey,valueinkwargs.items()ifvalueisnotNone},}response=requests.post(f"https://google.serper.dev/{search_type}",headers=headers,params=params)response.raise_for_status()search_results=response.json()returnsearch_resultsasyncdef_async_google_serper_search_results(self,search_term:str,search_type:str="search",**kwargs:Any)->dict:headers={"X-API-KEY":self.serper_api_keyor"","Content-Type":"application/json",}url=f"https://google.serper.dev/{search_type}"params={"q":search_term,**{key:valueforkey,valueinkwargs.items()ifvalueisnotNone},}ifnotself.aiosession:asyncwithaiohttp.ClientSession()assession:asyncwithsession.post(url,params=params,headers=headers,raise_for_status=False)asresponse:search_results=awaitresponse.json()else:asyncwithself.aiosession.post(url,params=params,headers=headers,raise_for_status=True)asresponse:search_results=awaitresponse.json()returnsearch_results