Files
open-webui/backend/open_webui/retrieval/web/openserp.py
T
crustopher-lgtmandcrustopher-lgtm 5efe0951d5 feat: add OpenSERP self-hosted web search backend (#27437)
Add self-hosted OpenSERP as a web search engine option. OpenSERP
provides browser-rendered search across Google, Bing, Yandex, Baidu,
DuckDuckGo, and Ecosia with no API keys required.

- New module: retrieval/web/openserp.py (async, uses aiohttp session pool)
- Config: OPENSERP_BASE_URL env var (defaults to http://localhost:7070)
- Routing: search_web() dispatch for 'openserp' engine
- Follows existing patterns (searxng, brave)

Co-authored-by: crustopher-lgtm <crustopher-lgtm@users.noreply.github.com>
2026-07-26 18:52:08 -04:00

46 lines
1.3 KiB
Python

from __future__ import annotations
import logging
from open_webui.retrieval.web.main import SearchResult, get_filtered_results
from open_webui.utils.session_pool import get_session
log = logging.getLogger(__name__)
async def search_openserp(
base_url: str,
query: str,
count: int,
filter_list: list[str | None] | None = None,
) -> list[SearchResult]:
"""Query an OpenSERP instance and return normalised results.
OpenSERP aggregates results from 6 engines (google, bing, yandex,
baidu, duckduckgo, ecosia) at once via ``/mega/search``.
No API key is required -- only a reachable OpenSERP base URL.
"""
url = f"{base_url.rstrip('/')}/mega/search"
params = {"text": query, "limit": count}
log.debug("searching OpenSERP at %s", url)
session = await get_session()
async with session.get(url, params=params) as response:
response.raise_for_status()
payload = await response.json()
results = payload.get("results", [])
if filter_list:
results = get_filtered_results(results, filter_list)
return [
SearchResult(
link=item.get("url", ""),
title=item.get("title"),
snippet=item.get("snippet"),
)
for item in results[:count]
]