
Security News
npm Adopts OIDC for Trusted Publishing in CI/CD Workflows
npm now supports Trusted Publishing with OIDC, enabling secure package publishing directly from CI/CD workflows without relying on long-lived tokens.
Asynchronous DuckDuckGo Search API: A FastAPI service for async access to DuckDuckGo’s text, image, video, and news searches. Uses a custom aDDGS class with aiohttp and asyncio for concurrent queries. Supports advanced syntax and proxies.
This FastAPI-based application provides a standalone interface to DuckDuckGo's core search functionalities, including text search, image search, video search, and news search. It uses asynchronous programming to efficiently query DuckDuckGo's search engine, offering a robust and scalable solution. The API is built on top of the aDDGS
class from the asyncddgs
module, which handles the asynchronous interactions with DuckDuckGo and can also be used directly in Python code for custom applications.
Note: This API is not affiliated with DuckDuckGo and is intended for educational purposes only. Users must comply with DuckDuckGo's Terms of Service when utilizing this API.
The asyncddgs
module is published on PyPI and can be installed using pip. Python 3.9 or higher is required.
To install the module:
pip install asyncddgs
This command installs the asyncddgs
module and its core dependencies, including aiohttp
, lxml
, and others necessary for the aDDGS
class to function.
If you plan to run the FastAPI application, additional dependencies are required:
pip install fastapi uvicorn
fastapi
: High-performance web framework for the API.uvicorn
: ASGI server to run FastAPI.Alternatively, you can use the aDDGS
class directly in your asynchronous Python code without the FastAPI app, requiring only the base asyncddgs
installation.
Verify Installation:
pip list
Confirm that asyncddgs
, and optionally fastapi
and uvicorn
, are installed.
aDDGS
ClassThe aDDGS
class is the core of the asyncddgs
module, providing asynchronous methods to perform searches on DuckDuckGo. It leverages aiohttp
for HTTP requests and includes features like rate limiting, proxy support, and customizable headers, making it suitable for both standalone use and integration into applications like the FastAPI app.
The aDDGS
class is initialized with parameters that configure its behavior:
from asyncddgs import aDDGS
async with aDDGS(
headers=None,
proxy=None,
timeout=10,
verify=True,
enable_rate_limit=True,
min_request_interval=20.0,
delay_if_needed=0.75
) as ddgs:
# Use the instance here
pass
Parameters:
headers
: dict[str, str] | None
Custom headers for HTTP requests (e.g., {"Accept": "application/json"}
). Defaults to a predefined User-Agent mimicking Chrome 100 if not specified.
proxy
: str | None
Proxy URL (e.g., "http://user:pass@example.com:3128"
) for routing requests. Supports HTTP, HTTPS, and SOCKS5. Overrides the aDDGS_PROXY
environment variable if set. Defaults to None
.
timeout
: int | None
Total timeout in seconds for each HTTP request (connection and read). Defaults to 10 seconds.
verify
: bool
Whether to verify SSL certificates. Set to False
for self-signed certificates or certain proxies (reduces security). Defaults to True
.
enable_rate_limit
: bool
Enables rate limiting to avoid exceeding DuckDuckGo's request limits. Defaults to True
.
min_request_interval
: float
Minimum interval in seconds between requests when rate limiting is enabled. Defaults to 20.0 seconds.
delay_if_needed
: float
Delay in seconds to sleep if the time since the last request is less than min_request_interval
. Defaults to 0.75 seconds.
These parameters allow customization for specific use cases, such as adjusting request rates or routing through proxies.
The initialization parameters provide fine-grained control over the aDDGS
instance:
"socks5://user:pass@example.com:1080"
.enable_rate_limit
, min_request_interval
, and delay_if_needed
to balance speed and compliance with DuckDuckGo's policies.The class includes internal methods that support its functionality:
_sleep
:
Manages rate limiting by sleeping asynchronously if requests are made too quickly, based on min_request_interval
and delay_if_needed
.
_get_url
:
A generic method to make HTTP requests (GET, POST, etc.) with customizable parameters (e.g., headers, data, proxy). Returns an aiohttp.ClientResponse
object.
_get_vqd
:
Extracts the 'vqd' token required for image, video, and news searches by querying DuckDuckGo with the search keywords.
These methods are used internally by the search methods but are critical to understanding the class's operation.
The aDDGS
class provides four primary asynchronous search methods:
The text
method performs a text search on DuckDuckGo, returning web page titles, URLs, and snippets.
async def text(
keywords: str,
region: str = "wt-wt",
safesearch: str = "moderate",
timelimit: str | None = None,
backend: str = "auto",
max_results: int | None = None,
max_pages: int = 5
) -> list[dict[str, str]]
Parameter | Type | Description | Possible Values | Default |
---|---|---|---|---|
keywords | str | Search query (required). | Any string (e.g., "python" , "site:python.org" ) | Required |
region | str | Region code for localized results. | "wt-wt" (worldwide), "us-en" , "uk-en" , "de-de" , etc. | "wt-wt" |
safesearch | str | Filters explicit content. | "on" , "moderate" , "off" | "moderate" |
timelimit | str | None | Limits results by publication time. | "d" (day), "w" (week), "m" (month), "y" (year) | None |
backend | str | Specifies the DuckDuckGo backend to use. | "auto" (randomly selects "html" or "lite" ), "html" , "lite" | "auto" |
max_results | int | None | Maximum number of results to return. | Any positive integer (e.g., 10 ) | None (first page) |
max_pages | int | Maximum number of result pages to fetch. | Any positive integer (e.g., 5 ) | 5 |
Returns: List of dictionaries with title
, href
, and body
.
Behavior: Supports two backends ("html" and "lite") for parsing results, with pagination and deduplication.
import asyncio
from asyncddgs import aDDGS
async def main():
async with aDDGS() as ddgs:
# Search for "python programming" with specific parameters
text_results = await ddgs.text(
keywords="python programming",
region="us-en",
safesearch="off",
timelimit="m",
backend="html",
max_results=5,
max_pages=3
)
for result in text_results:
print(f"Title: {result['title']}")
print(f"URL: {result['href']}")
print(f"Snippet: {result['body']}\n")
if __name__ == "__main__":
asyncio.run(main())
The images
method searches for images with extensive filtering options.
async def images(
keywords: str,
region: str = "wt-wt",
safesearch: str = "moderate",
timelimit: str | None = None,
size: str | None = None,
color: str | None = None,
type_image: str | None = None,
layout: str | None = None,
license_image: str | None = None,
max_results: int | None = None,
max_pages: int = 5
) -> list[dict[str, str]]
Parameter | Type | Description | Possible Values | Default |
---|---|---|---|---|
keywords | str | Search query (required). | Any string (e.g., "sunset" ) | Required |
region | str | Region code for localized results. | "wt-wt" , "us-en" , "uk-en" , etc. | "wt-wt" |
safesearch | str | Filters explicit content. | "on" , "moderate" , "off" | "moderate" |
timelimit | str | None | Limits results by time. | "Day" , "Week" , "Month" , "Year" | None |
size | str | None | Filters by image size. | "Small" , "Medium" , "Large" , "Wallpaper" | None |
color | str | None | Filters by image color. | "color" , "Monochrome" , "Red" , "Orange" , "Yellow" , "Green" , "Blue" , "Purple" , "Pink" , "Brown" , "Black" , "Gray" , "Teal" , "White" | None |
type_image | str | None | Filters by image type. | "photo" , "clipart" , "gif" , "transparent" , "line" | None |
layout | str | None | Filters by image layout. | "Square" , "Tall" , "Wide" | None |
license_image | str | None | Filters by image license. | "any" , "Public" , "Share" , "ShareCommercially" , "Modify" , "ModifyCommercially" | None |
max_results | int | None | Maximum number of results. | Any positive integer (e.g., 10 ) | None |
max_pages | int | Maximum pages to fetch. | Any positive integer (e.g., 5 ) | 5 |
title
, image
, thumbnail
, url
, height
, width
, and source
.import asyncio
from asyncddgs import aDDGS
async def main():
async with aDDGS() as ddgs:
# Search for "sunset" images with filters
image_results = await ddgs.images(
keywords="sunset",
region="wt-wt",
safesearch="moderate",
timelimit="Week",
size="Large",
color="Orange",
type_image="photo",
layout="Wide",
license_image="Share",
max_results=4,
max_pages=2
)
for result in image_results:
print(f"Title: {result['title']}")
print(f"Image URL: {result['image']}")
print(f"Thumbnail: {result['thumbnail']}")
print(f"Source: {result['source']}\n")
if __name__ == "__main__":
asyncio.run(main())
The videos
method searches for videos with filters for resolution and duration.
async def videos(
keywords: str,
region: str = "wt-wt",
safesearch: str = "moderate",
timelimit: str | None = None,
resolution: str | None = None,
duration: str | None = None,
license_videos: str | None = None,
max_results: int | None = None,
max_pages: int = 8
) -> list[dict[str, str]]
Parameter | Type | Description | Possible Values | Default |
---|---|---|---|---|
keywords | str | Search query (required). | Any string (e.g., "python tutorials" ) | Required |
region | str | Region code for localized results. | "wt-wt" , "us-en" , "uk-en" , etc. | "wt-wt" |
safesearch | str | Filters explicit content. | "on" , "moderate" , "off" | "moderate" |
timelimit | str | None | Limits results by time. | "d" (day), "w" (week), "m" (month) | None |
resolution | str | None | Filters by video resolution. | "high" , "standard" | None |
duration | str | None | Filters by video duration. | "short" , "medium" , "long" | None |
license_videos | str | None | Filters by video license. | "creativeCommon" , "youtube" | None |
max_results | int | None | Maximum number of results. | Any positive integer (e.g., 5 ) | None |
max_pages | int | Maximum pages to fetch. | Any positive integer (e.g., 8 ) | 8 |
content
(video URL), title
, and additional fields.import asyncio
from asyncddgs import aDDGS
async def main():
async with aDDGS() as ddgs:
# Search for "python tutorials" videos with filters
video_results = await ddgs.videos(
keywords="python tutorials",
region="uk-en",
safesearch="on",
timelimit="w",
resolution="high",
duration="medium",
license_videos="youtube",
max_results=3,
max_pages=4
)
for result in video_results:
print(f"Title: {result['title']}")
print(f"Video URL: {result['content']}\n")
if __name__ == "__main__":
asyncio.run(main())
The news
method fetches news articles with filters for recency.
async def news(
keywords: str,
region: str = "wt-wt",
safesearch: str = "moderate",
timelimit: str | None = None,
max_results: int | None = None,
max_pages: int = 5
) -> list[dict[str, str]]
Parameter | Type | Description | Possible Values | Default |
---|---|---|---|---|
keywords | str | Search query (required). | Any string (e.g., "technology" ) | Required |
region | str | Region code for localized results. | "wt-wt" , "us-en" , "uk-en" , etc. | "wt-wt" |
safesearch | str | Filters explicit content. | "on" , "moderate" , "off" | "moderate" |
timelimit | str | None | Limits results by time. | "d" (day), "w" (week), "m" (month) | None |
max_results | int | None | Maximum number of results. | Any positive integer (e.g., 3 ) | None |
max_pages | int | Maximum pages to fetch. | Any positive integer (e.g., 5 ) | 5 |
date
(ISO format), title
, body
, url
, image
(optional), and source
.Common Features: All methods are asynchronous, validate keywords
, use rate limiting, and support pagination via max_results
and max_pages
.
import asyncio
from asyncddgs import aDDGS
async def main():
async with aDDGS() as ddgs:
# Search for "technology" news with filters
news_results = await ddgs.news(
keywords="technology",
region="us-en",
safesearch="moderate",
timelimit="d",
max_results=2,
max_pages=1
)
for result in news_results:
print(f"Title: {result['title']}")
print(f"Date: {result['date']}")
print(f"URL: {result['url']}")
print(f"Source: {result['source']}\n")
if __name__ == "__main__":
asyncio.run(main())
Here’s how to use the aDDGS
class directly:
import asyncio
from asyncddgs import aDDGS
async def main():
async with aDDGS(proxy="http://user:pass@proxy.example.com:3128") as ddgs:
# Text search
text_results = await ddgs.text("python programming", max_results=5)
for result in text_results:
print(f"Title: {result['title']}, URL: {result['href']}")
# Image search
image_results = await ddgs.images("sunset", size="Large", max_results=3)
for result in image_results:
print(f"Image: {result['image']}, Source: {result['source']}")
if __name__ == "__main__":
asyncio.run(main())
This script demonstrates text and image searches with custom configuration (e.g., proxy). Adjust parameters as needed for other search types.
To launch the FastAPI application:
Ensure Dependencies are Installed: Complete the installation steps above.
Start the FastAPI Application:
uvicorn app:app --host 0.0.0.0 --port 8080
app:app
: Refers to the FastAPI instance in app.py
.--host 0.0.0.0
: Allows external access.--port 8080
: Specifies the port.Access the API:
http://localhost:8080
http://localhost:8080/docs
The API exposes four endpoints for searching DuckDuckGo:
Each endpoint accepts a JSON payload with specific parameters, detailed below with request bodies, response formats, parameter explanations, and examples.
/text
)Endpoint: POST /text
Description: Queries DuckDuckGo for text-based search results, returning web page titles, URLs, and snippets. Supports advanced search syntax for precise queries.
Request Body:
{
"keywords": "string", // Required: Search query
"region": "string", // Optional: Region code (default: "wt-wt")
"safesearch": "string", // Optional: Safe search level (default: "moderate")
"timelimit": "string", // Optional: Time filter (e.g., "d", "w", "m", "y")
"backend": "string", // Optional: Backend (default: "auto")
"max_results": integer, // Optional: Maximum number of results
"max_pages": integer // Optional: Maximum pages to fetch (default: 5)
}
Response:
{
"results": [
{
"title": "string",
"href": "string",
"body": "string"
}
]
}
Parameters:
Parameter | Description | Possible Values | Default |
---|---|---|---|
keywords | Search query (required). Supports advanced syntax (see below). | Any string (e.g., "python", "site:python.org") | Required |
region | Region code for localized results. | "wt-wt" (worldwide), "us-en", "uk-en", "de-de", etc. | "wt-wt" |
safesearch | Filters explicit content. | "on", "moderate", "off" | "moderate" |
timelimit | Limits results by publication time. | "d" (day), "w" (week), "m" (month), "y" (year) | None |
backend | Specifies the DuckDuckGo backend to use. | "auto" (random), "html", "lite" | "auto" |
max_results | Maximum number of results to return. | Any integer (e.g., 10) | None |
max_pages | Maximum number of result pages to fetch (each page triggers a request). | Any integer (e.g., 5) | 5 |
Example Request:
curl -X POST "http://localhost:8080/text" -H "Content-Type: application/json" -d '{
"keywords": "python programming site:python.org",
"max_results": 5
}'
Example Response:
{
"results": [
{
"title": "Python",
"href": "https://www.python.org/",
"body": "The official home of the Python Programming Language"
},
{
"title": "Download Python",
"href": "https://www.python.org/downloads/",
"body": "Download the latest version of Python"
}
]
}
Implementation Notes: The text
endpoint uses either the "html" or "lite" backend, implemented in the standalone aDDGS
class within app.py
. If backend
is "auto", it randomly selects between parsing full DuckDuckGo HTML pages (https://html.duckduckgo.com/html
) or the lighter interface (https://lite.duckduckgo.com/lite/
), returning deduplicated results.
/images
)Endpoint: POST /images
Description: Retrieves image results from DuckDuckGo, including metadata like size, color, and license filters.
Request Body:
{
"keywords": "string", // Required: Search query
"region": "string", // Optional: Region code (default: "wt-wt")
"safesearch": "string", // Optional: Safe search level (default: "moderate")
"timelimit": "string", // Optional: Time filter (e.g., "Day", "Week")
"size": "string", // Optional: Image size filter
"color": "string", // Optional: Color filter
"type_image": "string", // Optional: Image type filter
"layout": "string", // Optional: Layout filter
"license_image": "string", // Optional: License filter
"max_results": integer, // Optional: Maximum number of results
"max_pages": integer // Optional: Maximum pages to fetch (default: 5)
}
Response:
{
"results": [
{
"title": "string",
"image": "string",
"thumbnail": "string",
"url": "string",
"height": integer,
"width": integer,
"source": "string"
}
]
}
Parameters:
Parameter | Description | Possible Values | Default |
---|---|---|---|
keywords | Search query (required). | Any string (e.g., "sunset") | Required |
region | Region code for localized results. | "wt-wt", "us-en", "uk-en", etc. | "wt-wt" |
safesearch | Filters explicit content. | "on", "moderate", "off" | "moderate" |
timelimit | Limits results by time. | "Day", "Week", "Month", "Year" | None |
size | Filters by image size. | "Small", "Medium", "Large", "Wallpaper" | None |
color | Filters by image color. | "color", "Monochrome", "Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Pink", "Brown", "Black", "Gray", "Teal", "White" | None |
type_image | Filters by image type. | "photo", "clipart", "gif", "transparent", "line" | None |
layout | Filters by image layout. | "Square", "Tall", "Wide" | None |
license_image | Filters by image license. | "any", "Public", "Share", "ShareCommercially", "Modify", "ModifyCommercially" | None |
max_results | Maximum number of results. | Any integer (e.g., 10) | None |
max_pages | Maximum pages to fetch. | Any integer (e.g., 5) | 5 |
Example Request:
curl -X POST "http://localhost:8080/images" -H "Content-Type: application/json" -d '{
"keywords": "sunset",
"max_results": 10,
"size": "Large",
"color": "Orange"
}'
Example Response:
{
"results": [
{
"title": "Sunset over the ocean",
"image": "https://example.com/image.jpg",
"thumbnail": "https://example.com/thumb.jpg",
"url": "https://example.com",
"height": 1080,
"width": 1920,
"source": "example.com"
}
]
}
Implementation Notes: Uses the images
method from the aDDGS
class in app.py
, querying https://duckduckgo.com/i.js
with a vqd
token. Results are deduplicated by image URL and paginated based on max_results
or max_pages
.
/videos
)Endpoint: POST /videos
Description: Searches for videos on DuckDuckGo, returning video URLs and titles with filters for resolution and duration.
Request Body:
{
"keywords": "string", // Required: Search query
"region": "string", // Optional: Region code (default: "wt-wt")
"safesearch": "string", // Optional: Safe search level (default: "moderate")
"timelimit": "string", // Optional: Time filter (e.g., "d", "w", "m")
"resolution": "string", // Optional: Video resolution filter
"duration": "string", // Optional: Video duration filter
"license_videos": "string", // Optional: Video license filter
"max_results": integer, // Optional: Maximum number of results
"max_pages": integer // Optional: Maximum pages to fetch (default: 8)
}
Response:
{
"results": [
{
"content": "string",
"title": "string"
}
]
}
Parameters:
Parameter | Description | Possible Values | Default |
---|---|---|---|
keywords | Search query (required). | Any string (e.g., "python tutorials") | Required |
region | Region code for localized results. | "wt-wt", "us-en", "uk-en", etc. | "wt-wt" |
safesearch | Filters explicit content. | "on", "moderate", "off" | "moderate" |
timelimit | Limits results by time. | "d" (day), "w" (week), "m" (month) | None |
resolution | Filters by video resolution. | "high", "standard" | None |
duration | Filters by video duration. | "short", "medium", "long" | None |
license_videos | Filters by video license. | "creativeCommon", "youtube" | None |
max_results | Maximum number of results. | Any integer (e.g., 5) | None |
max_pages | Maximum pages to fetch. | Any integer (e.g., 8) | 8 |
Example Request:
curl -X POST "http://localhost:8080/videos" -H "Content-Type: application/json" -d '{
"keywords": "python tutorials",
"max_results": 5,
"duration": "short"
}'
Example Response:
{
"results": [
{
"content": "https://www.youtube.com/watch?v=abc123",
"title": "Python Basics in 5 Minutes"
}
]
}
Implementation Notes: Uses the videos
method from aDDGS
, querying https://duckduckgo.com/v.js
. Results are deduplicated by video URL (content
), with pagination up to max_pages
(default 8).
/news
)Endpoint: POST /news
Description: Fetches news articles from DuckDuckGo, including publication dates, titles, and sources.
Request Body:
{
"keywords": "string", // Required: Search query
"region": "string", // Optional: Region code (default: "wt-wt")
"safesearch": "string", // Optional: Safe search level (default: "moderate")
"timelimit": "string", // Optional: Time filter (e.g., "d", "w", "m")
"max_results": integer, // Optional: Maximum number of results
"max_pages": integer // Optional: Maximum pages to fetch (default: 5)
}
Response:
{
"results": [
{
"date": "string", // ISO format
"title": "string",
"body": "string",
"url": "string",
"image": "string",
"source": "string"
}
]
}
Parameters:
Parameter | Description | Possible Values | Default |
---|---|---|---|
keywords | Search query (required). | Any string (e.g., "technology") | Required |
region | Region code for localized results. | "wt-wt", "us-en", "uk-en", etc. | "wt-wt" |
safesearch | Filters explicit content. | "on", "moderate", "off" | "moderate" |
timelimit | Limits results by time. | "d" (day), "w" (week), "m" (month) | None |
max_results | Maximum number of results. | Any integer (e.g., 3) | None |
max_pages | Maximum pages to fetch. | Any integer (e.g., 5) | 5 |
Example Request:
curl -X POST "http://localhost:8080/news" -H "Content-Type: application/json" -d '{
"keywords": "technology",
"max_results": 3,
"timelimit": "d"
}'
Example Response:
{
"results": [
{
"date": "2025-03-30T12:00:00+00:00",
"title": "New Tech Breakthrough",
"body": "A summary of the article...",
"url": "https://news.example.com/article",
"image": "https://news.example.com/image.jpg",
"source": "Tech News"
}
]
}
Implementation Notes: Queries https://duckduckgo.com/news.js
via the news
method in aDDGS
. Results include ISO-formatted dates and are deduplicated by URL.
The keywords
parameter in the /text
endpoint supports DuckDuckGo's advanced search operators for precise queries. Below is a comprehensive table of operators as of March 31, 2025:
Operator | Example | Result |
---|---|---|
(space) | cats dogs | Results containing "cats" OR "dogs" (implicit OR) |
"exact phrase" | "cats and dogs" | Exact phrase match; falls back to related results if no exact match |
-exclude | cats -dogs | Results with "cats" but fewer or no "dogs" |
+include | cats +dogs | Results with "cats" and more emphasis on "dogs" |
filetype: | cats filetype:pdf | Results in specific file types (pdf, doc, docx, xls, xlsx, ppt, pptx, html) |
site: | dogs site:example.com | Results from a specific site (e.g., example.com) |
-site: | cats -site:example.com | Excludes results from a specific site |
intitle: | intitle:dogs | Results with "dogs" in the page title |
inurl: | inurl:cats | Results with "cats" in the URL |
* (wildcard) | cat* | Matches variations (e.g., "cats", "caterpillar") |
OR | cats OR dogs | Results containing either "cats" or "dogs" (case-sensitive operator) |
() (grouping) | (cats dogs) -mice | Groups terms for complex queries; here, "cats" or "dogs" excluding "mice" |
intext: | intext:programming | Results with "programming" in the body text |
allintitle: | allintitle:cats dogs | All terms must appear in the title |
allinurl: | allinurl:cats dogs | All terms must appear in the URL |
allintext: | allintext:cats dogs | All terms must appear in the body text |
related: | related:python.org | Results related to a specific site |
cache: | cache:example.com | Cached version of a page (if available) |
.. (range) | phones 200..300 | Numeric range search (e.g., prices or years between 200 and 300) |
# (hashtag) | #python | Social media or tagged content related to "python" |
@ (social handle) | @pythondev | Results mentioning a specific social media handle |
Notes:
cats -dogs site:example.com filetype:pdf
).cache:
, related:
) may have limited support due to DuckDuckGo's backend.Implementation Impact: Operators are passed directly to DuckDuckGo via the keywords
field and processed server-side, with backend
options ensuring compatibility.
Proxies route requests through alternative IPs for privacy or bypassing restrictions. Configure via the DDGS_PROXY
environment variable.
Supported Formats:
"http://user:pass@example.com:3128"
"https://user:pass@example.com:3128"
"socks5://user:pass@example.com:1080"
"tb"
(alias for "socks5://127.0.0.1:9150"
, requires Tor locally)Example:
export DDGS_PROXY="http://user:pass@proxy.example.com:3128"
uvicorn src.app:app --host 0.0.0.0 --port 8080
Notes: The aDDGS
class in app.py
applies the proxy to all aiohttp
requests, requiring valid credentials and connectivity.
This API is a standalone implementation built with FastAPI and a custom aDDGS
class (assumed in app.py
).
/docs
.aDDGS
class handles asynchronous requests to DuckDuckGo endpoints (html.duckduckgo.com/html
, i.js
, v.js
, news.js
) using aiohttp
.ValueValidationError
, DuckDuckGoSearchException
, TimeoutException
) map to HTTP status codes (422, 500).Source: This is a custom module not yet published, with all logic contained in app.py
.
Errors return structured responses with HTTP status codes:
keywords
), from ValueValidationError
.DuckDuckGoSearchException
or TimeoutException
.Example Error Response:
{
"detail": "keywords must not be empty or None"
}
Client Handling: Check status codes and detail
for diagnostics; use backoff for 500 errors.
Docker ensures consistent deployment:
Install Docker:
Create a Dockerfile:
FROM python:3.10-slim
WORKDIR /app
COPY app.py /app/app.py
COPY requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8080
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080"]
Create requirements.txt
:
fastapi
uvicorn
pydantic
aiohttp
Build the Image:
docker build -t asyncddgs-app .
Run the Container:
docker run -d -p 8080:8080 asyncddgs-app
Access the API:
http://localhost:8080
With Proxy:
docker run -d -p 8080:8080 -e DDGS_PROXY="http://user:pass@proxy.example.com:3128" asyncddgs-app
This API is not affiliated with DuckDuckGo and is intended for educational purposes only. It is not for commercial use or any purpose violating DuckDuckGo’s Terms of Service. Users must comply with DuckDuckGo’s terms at https://duckduckgo.com.
Updated as of April 01, 2025.
FAQs
Asynchronous DuckDuckGo Search API: A FastAPI service for async access to DuckDuckGo’s text, image, video, and news searches. Uses a custom aDDGS class with aiohttp and asyncio for concurrent queries. Supports advanced syntax and proxies.
We found that AsyncDDGS demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
npm now supports Trusted Publishing with OIDC, enabling secure package publishing directly from CI/CD workflows without relying on long-lived tokens.
Research
/Security News
A RubyGems malware campaign used 60 malicious packages posing as automation tools to steal credentials from social media and marketing tool users.
Security News
The CNA Scorecard ranks CVE issuers by data completeness, revealing major gaps in patch info and software identifiers across thousands of vulnerabilities.