Files
Timothy Jaeryang Baek b94245d2ee refac
2026-05-21 16:44:36 +04:00

57 lines
1.8 KiB
Python

from __future__ import annotations
import asyncio
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__)
# Brave free-tier rate limit: 1 request per second.
_RATE_LIMIT_RETRY_DELAY = 1.0
async def search_brave(
api_key: str,
query: str,
count: int,
filter_list: list[str | None] | None = None,
) -> list[SearchResult]:
"""Query the Brave Web Search API and return normalised results.
Retries once on HTTP 429 (rate-limit) after a short delay.
"""
url = 'https://api.search.brave.com/res/v1/web/search'
headers = {
'Accept': 'application/json',
'Accept-Encoding': 'gzip',
'X-Subscription-Token': api_key,
}
params = {'q': query, 'count': count}
session = await get_session()
async with session.get(url, headers=headers, params=params) as response:
if response.status == 429:
log.info('Brave Search rate-limited (429); retrying after %.1fs', _RATE_LIMIT_RETRY_DELAY)
await asyncio.sleep(_RATE_LIMIT_RETRY_DELAY)
async with session.get(url, headers=headers, params=params) as retry_resp:
retry_resp.raise_for_status()
payload = await retry_resp.json()
else:
response.raise_for_status()
payload = await response.json()
web_results = payload.get('web', {}).get('results', [])
if filter_list:
web_results = get_filtered_results(web_results, filter_list)
return [
SearchResult(
link=item.get('url', ''),
title=item.get('title'),
snippet=item.get('description'),
)
for item in web_results[:count]
]