Skip to main content

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:

  1. Primary: DDGS SERP results (ddgs / legacy duckduckgo-search)

    • Tries multiple backends (default: lite, html, auto)
    • Retries with exponential backoff + jitter (configurable)
    • Returns normalized items (title, url, snippet) with a source tag like ddgs:lite
  2. 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"
  3. 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 Results and RelatedTopics
    • 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: str
  • url: str
  • snippet: 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.27
    • ddgs>=9.0.0

Note: This library relies on the unofficial ddgs package 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

duckduckgo_async_search-1.0.0.tar.gz (9.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

duckduckgo_async_search-1.0.0-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

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

Hashes for duckduckgo_async_search-1.0.0.tar.gz
Algorithm Hash digest
SHA256 59e9f6c1454b6eabccf963921c9e99a421b9a722e07dd6812d52348ff4f741f9
MD5 244a3a534331acf3d080f39318589f24
BLAKE2b-256 b06cee318a4cfc99adb5b3e7445a57cddc49d908de7abafeed2183ff72c2151f

See more details on using hashes here.

File details

Details for the file duckduckgo_async_search-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for duckduckgo_async_search-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f0b2c4213683e37e9aa238c046db65a53ca0eb396e8d8470577fda62dbf423c3
MD5 3184255e00c8efcc2c4aa502c34bcfcc
BLAKE2b-256 76e805a3fba81208f949c98c33371284fbbb58fb323b268d8ff2175e0a4ed6ce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page