open-webui/backend/open_webui/retrieval/web/duckduckgo.py
Timothy Jaeryang Baek 0fa4dea5ff refac
2026-09-06 17:21:57 -04:00

56 lines
1.8 KiB
Python

from __future__ import annotations
import logging
import urllib.request
from open_webui.env import USE_SLIM
from open_webui.retrieval.web.main import SearchResult, get_filtered_results
log = logging.getLogger(__name__)
def search_duckduckgo(
query: str,
count: int,
filter_list: list[str] | None = None,
concurrent_requests: int | None = None,
backend: str | None = 'auto',
) -> list[SearchResult]:
"""
Search using DuckDuckGo's Search API and return the results as a list of SearchResult objects.
Args:
query (str): The query to search for
count (int): The number of results to return
backend (str): The search backend to use (auto, duckduckgo, google, brave, etc.)
Returns:
list[SearchResult]: A list of search results
"""
if USE_SLIM:
raise ValueError(
'DDGS is unavailable in slim. Configure another web search provider in Admin Settings > Web Search.'
)
from ddgs import DDGS
# The ddgs library (primp-based) does not auto-detect proxy env vars.
# Resolve via stdlib getproxies() — same pattern as the other loaders.
env_proxies = urllib.request.getproxies()
proxy = env_proxies.get('https') or env_proxies.get('http')
with DDGS(proxy=proxy) as ddgs:
if concurrent_requests:
ddgs.threads = concurrent_requests
search_results = ddgs.text(query, safesearch='moderate', max_results=count, backend=backend or 'auto')
if filter_list:
search_results = get_filtered_results(search_results, filter_list)
# Return the list of search results
return [
SearchResult(
link=result['href'],
title=result.get('title'),
snippet=result.get('body'),
)
for result in search_results
]