diff options
| author | Ilya Bogin <ilya.bogin@gmail.com> | 2026-07-15 19:05:41 +0300 |
|---|---|---|
| committer | Bnyro <bnyro@tutanota.com> | 2026-07-30 16:11:42 +0200 |
| commit | 0be6f87801022f6b0640644b5c60364891145345 (patch) | |
| tree | 5cdba8e8afbe01d3f75578e2a6757ad4c3b08787 | |
| parent | ef3a6ea9fd7e4a8cdae705c376bac7b03f31e674 (diff) | |
[feat] engines: add keenable (general)
| -rw-r--r-- | searx/engines/keenable.py | 66 | ||||
| -rw-r--r-- | searx/settings.yml | 6 |
2 files changed, 72 insertions, 0 deletions
diff --git a/searx/engines/keenable.py b/searx/engines/keenable.py new file mode 100644 index 000000000..5c1f11f0e --- /dev/null +++ b/searx/engines/keenable.py @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Keenable is a fast web search with keyless mode support""" + +import typing as t + +from datetime import datetime +from searx.extended_types import SXNG_Response +from searx.result_types import EngineResults +from searx.utils import searxng_useragent + +if t.TYPE_CHECKING: + from searx.search.processors import OnlineParams + +about = { + "website": "https://keenable.ai", + "official_api_documentation": "https://docs.keenable.ai", + "use_official_api": True, + "require_api_key": False, + "results": "JSON", +} +api_key = "" +""" Optional API Key. You can create a key at `the official website +<https://keenable.ai/signup>'_ if you need higher rate limits.""" + +categories = ["general"] + +base_url = "https://api.keenable.ai" +keenable_mode = "pro" + + +def request(query: str, params: "OnlineParams"): + if api_key: + params["url"] = f"{base_url}/v1/search" + params["headers"]["X-API-KEY"] = api_key + else: + params["url"] = f"{base_url}/v1/search/public" + + params["method"] = "POST" + params["headers"]["X-Keenable-Title"] = searxng_useragent() + params["json"] = {"query": query, "mode": keenable_mode} + + +def response(resp: "SXNG_Response") -> EngineResults: + res = EngineResults() + + results: list[dict[str, str]] = resp.json()["results"] # type: ignore[reportAny] + + for result in results: + published = None + pub = result.get("published_at") + if pub: + try: + published = datetime.fromisoformat(pub.rstrip("Z")) + except ValueError: + pass + + res.add( + res.types.MainResult( + url=result["url"], + title=result["title"], + content=result["description"] or result["snippet"], + publishedDate=published, + ) + ) + + return res diff --git a/searx/settings.yml b/searx/settings.yml index ab26f1900..8d615cb87 100644 --- a/searx/settings.yml +++ b/searx/settings.yml @@ -1461,6 +1461,12 @@ engines: description: "Demo index of Kavunka, a statistical search engine" results: HTML + - name: keenable + engine: keenable + shortcut: keen + disabled: true + inactive: true + - name: kozmonavt engine: xpath search_url: https://kozmonavt.su/s?q={query} |
