Source code for searx.engines.braveapi
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Engine to search using the Brave (WEB) Search API.
.. _Brave Search API: https://api-dashboard.search.brave.com/documentation
Configuration
=============
The engine has the following mandatory setting:
- :py:obj:`api_key`
Optional settings are:
- :py:obj:`results_per_page`
.. code:: yaml
- name: braveapi
engine: braveapi
api_key: 'YOUR-API-KEY' # required
results_per_page: 20 # optional
The API supports paging and time filters.
"""
import typing as t
from urllib.parse import urlencode
from searx.engines.brave import parse_video_result
from searx.exceptions import SearxEngineAPIException
from searx.result_types import EngineResults
if t.TYPE_CHECKING:
from searx.extended_types import SXNG_Response
from searx.search.processors import OnlineParams
about = {
"website": "https://api.search.brave.com/",
"wikidata_id": None,
"official_api_documentation": "https://api-dashboard.search.brave.com/api-reference/web/search/get",
"use_official_api": True,
"require_api_key": True,
"results": "JSON",
}
api_key: str = ""
"""API key for Brave Search API (required)."""
categories = ["general", "web"]
paging = True
safesearch = True
safesearch_map = {2: "strict", 1: "moderate", 0: "off"}
time_range_support = True
results_per_page: int = 20
"""Maximum number of results per page (default 20)."""
base_url = "https://api.search.brave.com/res/v1/web/search"
"""Base URL for the Brave Search API."""
time_range_map = {"day": "past_day", "week": "past_week", "month": "past_month", "year": "past_year"}
"""Mapping of SearXNG time ranges to Brave API time ranges."""
max_page = 10
[docs]
def setup(_: dict[str, t.Any]) -> bool | None:
"""Initialize the engine."""
if not api_key:
raise SearxEngineAPIException("No API key provided")
[docs]
def request(query: str, params: "OnlineParams") -> None:
"""Create the API request."""
search_args: dict[str, str | int | None] = {
"q": query,
"count": results_per_page,
"offset": params["pageno"] - 1,
"text_decorations": False,
}
# Apply time filter if specified
if params["time_range"]:
search_args["time_range"] = time_range_map.get(params["time_range"])
# Apply SafeSearch
search_args["safesearch"] = safesearch_map.get(params["safesearch"], "off")
params["url"] = f"{base_url}?{urlencode(search_args)}"
params["headers"]["X-Subscription-Token"] = api_key
params["headers"]["Accept"] = "application/json"
[docs]
def response(resp: "SXNG_Response") -> EngineResults:
"""Process the API response and return results."""
data = resp.json()
res = EngineResults()
results_json = (data.get("web") or {}).get("results", [])
for result in results_json:
res.add(parse_video_result(result))
return res