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 / DDGS interface is convenient, but it is effectively synchronous/blocking (network + parsing happen in the calling thread). In async apps (FastAPI, agents, notebooks, concurrent pipelines), that 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
  • Requests can run in parallel with other async tasks

Fallback strategy (best-effort reliability)

DuckDuckGo can rate-limit or intermittently fail depending on IP/network conditions. To improve reliability, searches use a two-stage approach:

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

    • Tries multiple backends (default: lite, html, auto)
    • Retries with exponential backoff + jitter (configurable)
    • Returns normalized items (title, url, snippet) and a source tag like duckduckgo_search:lite
  2. Fallback: DuckDuckGo Instant Answer API (JSON)

    • More stable / less likely to rate-limit
    • Not a full web SERP, but returns useful links from Results and RelatedTopics
    • Returns items with source="instant_answer_api"

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

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 largest 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-0.0.4.tar.gz (9.4 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-0.0.4-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

Details for the file duckduckgo_async_search-0.0.4.tar.gz.

File metadata

  • Download URL: duckduckgo_async_search-0.0.4.tar.gz
  • Upload date:
  • Size: 9.4 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-0.0.4.tar.gz
Algorithm Hash digest
SHA256 418d9effa647b8f0eee2598e51e8164226f291a457f807b9f0c8b3636fe11384
MD5 6d993aea8ca8aee145722ade285ba7c4
BLAKE2b-256 a24eb54489bdb706c9ab1bf467cf33346c4e84888f91b1bc452d97f11d338c9d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for duckduckgo_async_search-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 1ea0a0ba69ba700bbaa69753b77d26d54fa05b2f43688b7042f2454759cc4653
MD5 2392899c90099692bad8878a7c643db0
BLAKE2b-256 c5174bdbe16e7e543ccb8e6df85f019fbdf64f7894b2d14426de3a77b7d92f14

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