from typing import List from duckduckgo_search import DDGS from app.tool.search.base import SearchItem, WebSearchEngine class DuckDuckGoSearchEngine(WebSearchEngine): def perform_search( self, query: str, num_results: int = 10, *args, **kwargs ) -> List[SearchItem]: """ DuckDuckGo search engine. Returns results formatted according to SearchItem model. """ raw_results = DDGS().text(query, max_results=num_results) results = [] for i, item in enumerate(raw_results): if isinstance(item, str): # If it's just a URL results.append( SearchItem( title=f"DuckDuckGo Result {i + 1}", url=item, description=None ) ) elif isinstance(item, dict): # Extract data from the dictionary results.append( SearchItem( title=item.get("title", f"DuckDuckGo Result {i + 1}"), url=item.get("href", ""), description=item.get("body", None), ) ) else: # Try to extract attributes directly try: results.append( SearchItem( title=getattr(item, "title", f"DuckDuckGo Result {i + 1}"), url=getattr(item, "href", ""), description=getattr(item, "body", None), ) ) except Exception: # Fallback results.append( SearchItem( title=f"DuckDuckGo Result {i + 1}", url=str(item), description=None, ) ) return results