Spaces:
Runtime error
Runtime error
| """Util that calls DuckDuckGo Search. | |
| No setup required. Free. | |
| https://pypi.org/project/duckduckgo-search/ | |
| """ | |
| from typing import Dict, List, Optional | |
| from langchain_core.pydantic_v1 import BaseModel, Extra, root_validator | |
| class DuckDuckGoSearchAPIWrapper(BaseModel): | |
| """Wrapper for DuckDuckGo Search API. | |
| Free and does not require any setup. | |
| """ | |
| region: Optional[str] = "wt-wt" | |
| safesearch: str = "moderate" | |
| time: Optional[str] = "y" | |
| max_results: int = 5 | |
| class Config: | |
| """Configuration for this pydantic object.""" | |
| extra = Extra.forbid | |
| def validate_environment(cls, values: Dict) -> Dict: | |
| """Validate that python package exists in environment.""" | |
| try: | |
| from duckduckgo_search import DDGS # noqa: F401 | |
| except ImportError: | |
| raise ImportError( | |
| "Could not import duckduckgo-search python package. " | |
| "Please install it with `pip install duckduckgo-search`." | |
| ) | |
| return values | |
| def get_snippets(self, query: str) -> List[str]: | |
| """Run query through DuckDuckGo and return concatenated results.""" | |
| from duckduckgo_search import DDGS | |
| with DDGS() as ddgs: | |
| results = ddgs.text( | |
| query, | |
| region=self.region, | |
| safesearch=self.safesearch, | |
| timelimit=self.time, | |
| ) | |
| if results is None: | |
| return ["No good DuckDuckGo Search Result was found"] | |
| snippets = [] | |
| for i, res in enumerate(results, 1): | |
| if res is not None: | |
| snippets.append(res["body"]) | |
| if len(snippets) == self.max_results: | |
| break | |
| return snippets | |
| def run(self, query: str) -> str: | |
| snippets = self.get_snippets(query) | |
| return " ".join(snippets) | |
| def results( | |
| self, query: str, num_results: int, backend: str = "api" | |
| ) -> List[Dict[str, str]]: | |
| """Run query through DuckDuckGo and return metadata. | |
| Args: | |
| query: The query to search for. | |
| num_results: The number of results to return. | |
| Returns: | |
| A list of dictionaries with the following keys: | |
| snippet - The description of the result. | |
| title - The title of the result. | |
| link - The link to the result. | |
| """ | |
| from duckduckgo_search import DDGS | |
| with DDGS() as ddgs: | |
| results = ddgs.text( | |
| query, | |
| region=self.region, | |
| safesearch=self.safesearch, | |
| timelimit=self.time, | |
| backend=backend, | |
| ) | |
| if results is None: | |
| return [{"Result": "No good DuckDuckGo Search Result was found"}] | |
| def to_metadata(result: Dict) -> Dict[str, str]: | |
| if backend == "news": | |
| return { | |
| "date": result["date"], | |
| "title": result["title"], | |
| "snippet": result["body"], | |
| "source": result["source"], | |
| "link": result["url"], | |
| } | |
| return { | |
| "snippet": result["body"], | |
| "title": result["title"], | |
| "link": result["href"], | |
| } | |
| formatted_results = [] | |
| for i, res in enumerate(results, 1): | |
| if res is not None: | |
| formatted_results.append(to_metadata(res)) | |
| if len(formatted_results) == num_results: | |
| break | |
| return formatted_results | |