[docs]classVespaRetriever(BaseRetriever):"""`Vespa` retriever."""app:Any"""Vespa application to query."""body:Dict"""Body of the query."""content_field:str"""Name of the content field."""metadata_fields:Sequence[str]"""Names of the metadata fields."""def_query(self,body:Dict)->List[Document]:response=self.app.query(body)ifnotstr(response.status_code).startswith("2"):raiseRuntimeError("Could not retrieve data from Vespa. Error code: {}".format(response.status_code))root=response.json["root"]if"errors"inroot:raiseRuntimeError(json.dumps(root["errors"]))docs=[]forchildinresponse.hits:page_content=child["fields"].pop(self.content_field,"")ifself.metadata_fields=="*":metadata=child["fields"]else:metadata={mf:child["fields"].get(mf)formfinself.metadata_fields}metadata["id"]=child["id"]docs.append(Document(page_content=page_content,metadata=metadata))returndocsdef_get_relevant_documents(self,query:str,*,run_manager:CallbackManagerForRetrieverRun)->List[Document]:body=self.body.copy()body["query"]=queryreturnself._query(body)
[docs]defget_relevant_documents_with_filter(self,query:str,*,_filter:Optional[str]=None)->List[Document]:body=self.body.copy()_filter=f" and {_filter}"if_filterelse""body["yql"]=body["yql"]+_filterbody["query"]=queryreturnself._query(body)
[docs]@classmethoddeffrom_params(cls,url:str,content_field:str,*,k:Optional[int]=None,metadata_fields:Union[Sequence[str],Literal["*"]]=(),sources:Union[Sequence[str],Literal["*"],None]=None,_filter:Optional[str]=None,yql:Optional[str]=None,**kwargs:Any,)->VespaRetriever:"""Instantiate retriever from params. Args: url (str): Vespa app URL. content_field (str): Field in results to return as Document page_content. k (Optional[int]): Number of Documents to return. Defaults to None. metadata_fields(Sequence[str] or "*"): Fields in results to include in document metadata. Defaults to empty tuple (). sources (Sequence[str] or "*" or None): Sources to retrieve from. Defaults to None. _filter (Optional[str]): Document filter condition expressed in YQL. Defaults to None. yql (Optional[str]): Full YQL query to be used. Should not be specified if _filter or sources are specified. Defaults to None. kwargs (Any): Keyword arguments added to query body. Returns: VespaRetriever: Instantiated VespaRetriever. """try:fromvespa.applicationimportVespaexceptImportError:raiseImportError("pyvespa is not installed, please install with `pip install pyvespa`")app=Vespa(url)body=kwargs.copy()ifyqland(sourcesor_filter):raiseValueError("yql should only be specified if both sources and _filter are not ""specified.")else:ifmetadata_fields=="*":_fields="*"body["summary"]="short"else:_fields=", ".join([content_field]+list(metadata_fieldsor[]))_sources=", ".join(sources)ifisinstance(sources,Sequence)else"*"_filter=f" and {_filter}"if_filterelse""yql=f"select {_fields} from sources {_sources} where userQuery(){_filter}"body["yql"]=yqlifk:body["hits"]=kreturncls(app=app,body=body,content_field=content_field,metadata_fields=metadata_fields,)