[docs]classStackExchangeAPIWrapper(BaseModel):"""Wrapper for Stack Exchange API."""client:Any=None#: :meta private:max_results:int=3"""Max number of results to include in output."""query_type:Literal["all","title","body"]="all""""Which part of StackOverflows items to match against. One of 'all', 'title', 'body'. Defaults to 'all'. """fetch_params:Dict[str,Any]=Field(default_factory=dict)"""Additional params to pass to StackApi.fetch."""result_separator:str="\n\n""""Separator between question,answer pairs."""@model_validator(mode="before")@classmethoddefvalidate_environment(cls,values:Dict)->Any:"""Validate that the required Python package exists."""try:fromstackapiimportStackAPIvalues["client"]=StackAPI("stackoverflow")exceptImportError:raiseImportError("The 'stackapi' Python package is not installed. ""Please install it with `pip install stackapi`.")returnvalues
[docs]defrun(self,query:str)->str:"""Run query through StackExchange API and parse results."""query_key="q"ifself.query_type=="all"elseself.query_typeoutput=self.client.fetch("search/excerpts",**{query_key:query},**self.fetch_params)iflen(output["items"])<1:returnf"No relevant results found for '{query}' on Stack Overflow."questions=[itemforiteminoutput["items"]ifitem["item_type"]=="question"][:self.max_results]answers=[itemforiteminoutput["items"]ifitem["item_type"]=="answer"]results=[]forquestioninquestions:res_text=f"Question: {question['title']}\n{question['excerpt']}"relevant_answers=[answerforanswerinanswersifanswer["question_id"]==question["question_id"]]accepted_answers=[answerforanswerinrelevant_answersifanswer["is_accepted"]]ifrelevant_answers:top_answer=(accepted_answers[0]ifaccepted_answerselserelevant_answers[0])excerpt=html.unescape(top_answer["excerpt"])res_text+=f"\nAnswer: {excerpt}"results.append(res_text)returnself.result_separator.join(results)