Async DuckDuckGo search helper with SERP wrapper + Instant Answer API fallback.
Project description
duckduckgo-async-search
A tiny, easy-to-use async wrapper around DuckDuckGo search with best-effort fallbacks.
Why this exists
The popular DuckDuckGo search interfaces (ddgs / legacy duckduckgo-search)
are synchronous/blocking by design (network + parsing happen in the calling thread).
In async applications (FastAPI, agents, notebooks, concurrent pipelines), calling them
directly can block the event loop and slow down unrelated tasks.
This library provides a non-blocking async API:
- You call
await DuckDuckGoSearch().top_n_result(...) - Under the hood, blocking SERP calls run in a background worker thread
(via
asyncio.to_thread) so the main event loop stays responsive - Searches can safely run alongside other async tasks
Fallback strategy (best-effort reliability)
DuckDuckGo may rate-limit or intermittently fail depending on IP, region, or network conditions. To improve reliability, searches use a multi-stage approach:
-
Primary: DDGS SERP results (
ddgs/ legacyduckduckgo-search)- Tries multiple backends (default:
lite,html,auto) - Retries with exponential backoff + jitter (configurable)
- Returns normalized items (
title,url,snippet) with asourcetag likeddgs:lite
- Tries multiple backends (default:
-
Secondary: DuckDuckGo HTML SERP fallback
- Fetches and parses the public DuckDuckGo HTML results page
- No additional third-party dependencies
- Best-effort parsing (may break if DuckDuckGo changes markup)
- Returns items with
source="ddg_html_fallback"
-
Final fallback: DuckDuckGo Instant Answer API (JSON)
- More stable and less likely to rate-limit
- Not a full web SERP, but can return useful links from
ResultsandRelatedTopics - Returns items with
source="instant_answer_api"
If all strategies fail or return no items, a clear error is raised.
Output
top_n_result() returns List[DuckDuckGoResult], where each item includes:
title: strurl: strsnippet: str(when available)source: str(which backend produced the item)
Install
pip install duckduckgo-async-search
Colab:
!pip install duckduckgo-async-search
Requirements
- Python: 3.9 or newer
- Dependencies:
httpx>=0.27ddgs>=9.0.0
Note: This library relies on the unofficial
ddgspackage to fetch DuckDuckGo search results.
DuckDuckGo may apply rate limits or blocking, so occasional retries or empty results are expected.
Dependencies are installed automatically when using:
pip install duckduckgo-async-search
Usage
Jupyter / Colab
from duckduckgo_async_search import top_n_result
async def main():
items = await top_n_result("World's largest mangrove forest", n=5)
for item in items:
print(item.title)
print(item.url)
print(item.snippet)
print(item.source)
print("-" * 30)
await main()
Python script (.py)
import asyncio
from duckduckgo_async_search import top_n_result
async def main():
items = await top_n_result("World's largest mangrove forest", n=5)
for item in items:
print(item.title, item.url, item.source)
if __name__ == "__main__":
asyncio.run(main())
Class usage
from duckduckgo_async_search import DuckDuckGoSearch
async def main():
client = DuckDuckGoSearch(
request_timeout_s = 20.0,
ddg_backends = None, # e.g., ["lite", "html", "auto"]
ddg_pause_s = 1.0, # pause between attempts - 2.0 or 3.0
ddg_max_attempts = 3, # total attempts across all backends
instant_answer_max_bytes = 2_000_000,
html_fallback_max_bytes = 2_500_000,
debug = False
)
items = await client.top_n_result("World's longest beach", n=10)
for item in items:
print(item.title, item.url, item.source)
await main()
Notes
- SERP wrappers can be rate-limited depending on your IP/network.
- Instant Answer API is more reliable but may not reflect “top web results”.
License
MIT License — free for personal and commercial use, modification, and distribution.
Contributing
Source: https://github.com/AbrarJahin/pip-duckduckgo_async_search
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file duckduckgo_async_search-1.0.0.tar.gz.
File metadata
- Download URL: duckduckgo_async_search-1.0.0.tar.gz
- Upload date:
- Size: 9.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59e9f6c1454b6eabccf963921c9e99a421b9a722e07dd6812d52348ff4f741f9
|
|
| MD5 |
244a3a534331acf3d080f39318589f24
|
|
| BLAKE2b-256 |
b06cee318a4cfc99adb5b3e7445a57cddc49d908de7abafeed2183ff72c2151f
|
File details
Details for the file duckduckgo_async_search-1.0.0-py3-none-any.whl.
File metadata
- Download URL: duckduckgo_async_search-1.0.0-py3-none-any.whl
- Upload date:
- Size: 9.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0b2c4213683e37e9aa238c046db65a53ca0eb396e8d8470577fda62dbf423c3
|
|
| MD5 |
3184255e00c8efcc2c4aa502c34bcfcc
|
|
| BLAKE2b-256 |
76e805a3fba81208f949c98c33371284fbbb58fb323b268d8ff2175e0a4ed6ce
|