From e2fbe9065448e2bc61fcb3c4d16143213057d021 Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:06:37 +0330 Subject: [PATCH] Import source: axon/services/sources/ddg Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- axon/services/sources/ddg.py | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 axon/services/sources/ddg.py diff --git a/axon/services/sources/ddg.py b/axon/services/sources/ddg.py new file mode 100644 index 0000000..67cb3ac --- /dev/null +++ b/axon/services/sources/ddg.py @@ -0,0 +1,48 @@ +import asyncio +import logging + +try: + from ddgs import DDGS +except ImportError: + from duckduckgo_search import DDGS + +from axon.models import SearchResult + +logger = logging.getLogger(__name__) + +_TIMELIMIT = {"day": "d", "week": "w", "month": "m", "year": "y"} + + +async def search_ddg( + query: str, + count: int = 10, + topic: str = "general", + time_range: str | None = None, +) -> list[SearchResult]: + timelimit = _TIMELIMIT.get(time_range) if time_range else None + + def _blocking_search() -> list[dict]: + with DDGS() as ddgs: + if topic == "news": + return list(ddgs.news(query, max_results=count, timelimit=timelimit)) + return list(ddgs.text(query, max_results=count, timelimit=timelimit)) + + try: + raw = await asyncio.to_thread(_blocking_search) + results = [] + for item in raw: + url = item.get("href") or item.get("url", "") + results.append( + SearchResult( + title=item.get("title", ""), + url=url, + content=item.get("body", ""), + score=0.5, + published_date=item.get("date"), + favicon=None, + ) + ) + return results + except Exception as exc: + logger.error("DuckDuckGo search error: %s", exc) + return []