ddgs 0.3.1
ddgs: ^0.3.1 copied to clipboard
A professional metasearch library that aggregates results from multiple web search engines including DuckDuckGo, Google, Bing, Brave, Ecosia, Qwant, and more.
DDGS - Dux Distributed Global Search #
A professional metasearch library that aggregates results from multiple web search engines including DuckDuckGo, Google, Bing, Brave, and more.
Features #
- π Multi-Engine Support: Search across 14+ different search engines
- π― Specialized Search: Text, images, videos, and news search capabilities
- π Privacy-Focused: DuckDuckGo as default backend
- π Region Support: Search in different regions and languages
- β‘ Async/Await: Modern asynchronous API
- π‘οΈ Safe Search: Built-in safe search filtering
- π Proxy Support: HTTP, HTTPS, and SOCKS5 proxy support
- π CLI Tool: Command-line interface included
- π¦ Type-Safe Results: Strongly-typed result classes
- πΎ Result Caching: Optional caching with TTL support
- π Rate Limiting: Built-in rate limiter to prevent API abuse
- π― Instant Answers: Direct answers, definitions, and calculations
- π Search Suggestions: Autocomplete support
- β‘ Parallel Search: Batch multiple queries concurrently
Supported Engines #
Text Search:
- DuckDuckGo (recommended)
- Bing
- Brave
- Ecosia (eco-friendly)
- Qwant (privacy-focused)
- StartPage (Google proxy)
- Mojeek
- Wikipedia
- Yahoo
- Yandex
Image Search:
- DuckDuckGo Images
- Google Images
- Qwant Images
Video Search:
- DuckDuckGo Videos
News Search:
- DuckDuckGo News
- Qwant News
Installation #
Add to your pubspec.yaml:
dependencies:
ddgs: ^0.1.3
Or install via command line:
dart pub add ddgs
Quick Start #
Basic Usage #
import 'package:ddgs/ddgs.dart';
void main() async {
final ddgs = DDGS();
try {
final results = await ddgs.text(
'Dart programming',
maxResults: 5,
backend: 'duckduckgo',
);
for (final result in results) {
print('${result['title']}: ${result['href']}');
}
} finally {
ddgs.close();
}
}
Advanced Usage #
import 'package:ddgs/ddgs.dart';
void main() async {
// Configure with custom settings
final ddgs = DDGS(
proxy: 'http://proxy.example.com:8080',
timeout: Duration(seconds: 10),
verify: true,
);
try {
// Text search with filters
final textResults = await ddgs.text(
'machine learning',
region: 'us-en',
safesearch: 'moderate',
timelimit: 'w', // Last week
maxResults: 10,
backend: 'duckduckgo',
);
// Image search
final images = await ddgs.images('nature', maxResults: 20);
// Video search
final videos = await ddgs.videos('tutorial', maxResults: 10);
// News search
final news = await ddgs.news('technology', timelimit: 'd', maxResults: 15);
} finally {
ddgs.close();
}
}
CLI Usage #
Installation #
dart pub get
Basic Commands #
# Text search
dart run ddgs text -q "Dart programming" -m 5 -b duckduckgo
# With JSON output
dart run ddgs text -q "Flutter" -m 5 -b duckduckgo --json
# Image search
dart run ddgs images -q "sunset" -m 10 -b duckduckgo
# Video search
dart run ddgs videos -q "tutorial" -m 5 -b duckduckgo
# News search
dart run ddgs news -q "technology" -m 10 -b duckduckgo
# Save to file
dart run ddgs text -q "AI" -m 20 -b duckduckgo -o results.json --json
CLI Options #
Options:
-q, --query Search query (required)
-m, --max-results Maximum number of results (default: 10)
-b, --backend Search backend (default: duckduckgo)
-r, --region Search region (e.g., us-en, wt-wt)
-s, --safesearch Safe search: on, moderate, off
-t, --timelimit Time limit: d (day), w (week), m (month), y (year)
-o, --output Output file path
--json Output in JSON format
-h, --help Show help
API Reference #
DDGS Class #
// Constructor
DDGS({
String? proxy,
Duration? timeout,
bool verify = true,
});
// Text Search
Future<List<Map<String, dynamic>>> text(
String query, {
String? region,
String? safesearch,
String? timelimit,
int? maxResults,
int? page,
String backend = 'duckduckgo',
});
// Image Search
Future<List<Map<String, dynamic>>> images(
String query, {
String? region,
String? safesearch,
String? timelimit,
String? size,
String? color,
String? type,
String? layout,
String? license,
int? maxResults,
});
// Video Search
Future<List<Map<String, dynamic>>> videos(
String query, {
String? region,
String? safesearch,
String? timelimit,
String? resolution,
String? duration,
String? license,
int? maxResults,
});
// News Search
Future<List<Map<String, dynamic>>> news(
String query, {
String? region,
String? safesearch,
String? timelimit,
int? maxResults,
});
// Close HTTP client
void close();
Testing #
# Run all tests
dart test
# Run with verbose output
dart test --reporter=expanded
# Run with coverage
dart test --coverage=coverage
# Analyze code
dart analyze
# Format code
dart format .
Exception Handling #
import 'package:ddgs/ddgs.dart';
void main() async {
final ddgs = DDGS();
try {
final results = await ddgs.text('query');
} on RatelimitException catch (e) {
print('Rate limit exceeded: $e');
} on TimeoutException catch (e) {
print('Request timeout: $e');
} on DDGSException catch (e) {
print('Search error: $e');
} finally {
ddgs.close();
}
}
Configuration #
Proxy Support #
// HTTP Proxy
final ddgs = DDGS(proxy: 'http://proxy.example.com:8080');
// HTTPS Proxy
final ddgs = DDGS(proxy: 'https://proxy.example.com:8443');
// SOCKS5 Proxy (for Tor, etc.)
final ddgs = DDGS(proxy: 'socks5h://127.0.0.1:9150');
Timeout Configuration #
final ddgs = DDGS(timeout: Duration(seconds: 30));
SSL Verification #
// Disable SSL verification (not recommended)
final ddgs = DDGS(verify: false);
Contributing #
Contributions are welcome! Please read CONTRIBUTING.md for details.
Development Setup #
- Clone the repository
- Install dependencies:
dart pub get - Run tests:
dart test - Format code:
dart format . - Analyze:
dart analyze
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments #
- Original Python implementation inspiration
- DuckDuckGo for privacy-focused search
- All contributors to this project
Support #
- π Documentation
- π Issue Tracker
- π¬ Discussions
Roadmap #
- β Books search implementation
- β Enhanced rate limiting
- β More search engines (Google, Ecosia, Qwant, StartPage)
- β Type-safe result classes
- β Result caching
- β Instant answers API
- β Search suggestions/autocomplete
- β Parallel batch search
- β Maps search integration
- β Translations support
- β Streaming results API
Advanced Features #
Type-Safe Results #
import 'package:ddgs/ddgs.dart';
void main() async {
final ddgs = DDGS();
try {
// Get strongly-typed results
final results = await ddgs.textTyped('Dart programming');
for (final result in results) {
// IDE autocompletion works!
print('Title: ${result.title}');
print('URL: ${result.href}');
print('Body: ${result.body}');
}
} finally {
ddgs.close();
}
}
Search Options #
import 'package:ddgs/ddgs.dart';
void main() async {
final ddgs = DDGS();
// Create custom search options
final options = SearchOptions(
region: SearchRegion.ukEnglish,
safeSearch: SafeSearchLevel.strict,
timeLimit: TimeLimit.week,
maxResults: 20,
);
// Or use presets
final quickResults = await ddgs.textTyped(
'Flutter widgets',
options: SearchOptions.quick,
);
final comprehensiveResults = await ddgs.textTyped(
'Machine learning',
options: SearchOptions.comprehensive,
);
ddgs.close();
}
Instant Answers #
import 'package:ddgs/ddgs.dart';
void main() async {
final ddgs = DDGS();
// Get instant answer (definitions, calculations, etc.)
final answer = await ddgs.instantAnswer('what is the speed of light');
if (answer != null && answer.hasContent) {
print('Answer: ${answer.answer}');
print('Source: ${answer.source}');
if (answer.abstract != null) {
print('Abstract: ${answer.abstract}');
}
}
// Get search suggestions
final suggestions = await ddgs.suggestions('flutter w');
for (final suggestion in suggestions) {
print('Suggestion: ${suggestion.suggestion}');
}
// Get spelling correction
final correction = await ddgs.spellingCorrection('fluter programing');
if (correction != null) {
print('Did you mean: $correction');
}
ddgs.close();
}
Result Caching #
import 'package:ddgs/ddgs.dart';
void main() async {
// Enable caching with 15-minute TTL
final ddgs = DDGS(
cacheConfig: CacheConfig(
enabled: true,
ttl: Duration(minutes: 15),
maxEntries: 100,
),
);
// First search - fetches from network
final results1 = await ddgs.textTyped('Dart programming');
// Second identical search - returns from cache
final results2 = await ddgs.textTyped('Dart programming');
// Check cache stats
print('Cache stats: ${ddgs.cacheStats}');
// Clear cache if needed
ddgs.clearCache();
ddgs.close();
}
Batch/Parallel Search #
import 'package:ddgs/ddgs.dart';
void main() async {
final ddgs = DDGS();
// Search multiple queries in parallel
final results = await ddgs.batchSearch(
['Dart programming', 'Flutter widgets', 'Pub packages'],
category: 'text',
options: SearchOptions(maxResults: 5),
maxConcurrency: 3,
);
for (final entry in results.entries) {
print('Query: ${entry.key}');
print('Results: ${entry.value.length}');
}
ddgs.close();
}
Rate Limiting & Retry #
import 'package:ddgs/ddgs.dart';
void main() async {
final ddgs = DDGS(
// Limit requests to prevent being blocked
maxRequestsPerSecond: 5,
// Configure retry behavior
retryConfig: RetryConfig(
maxRetries: 3,
baseDelay: Duration(milliseconds: 500),
exponentialBackoff: true,
),
);
// Your searches are now rate-limited and will retry on failure
final results = await ddgs.text('search query');
ddgs.close();
}
Available Engines Query #
import 'package:ddgs/ddgs.dart';
void main() {
// Get all available engines for a category
final textEngines = getAvailableEngines('text');
print('Text engines: $textEngines');
// Get all supported categories
print('Categories: $supportedCategories');
// Check if an engine is available
if (isEngineAvailable('text', 'google')) {
print('Google search is available!');
}
}
Testing #
This package includes comprehensive test coverage:
Unit Tests #
123 unit tests covering all public APIs and functionality:
dart test
Run specific test groups:
dart test -n "DDGS Tests"
dart test -n "Configuration"
dart test -n "Result Cache"
Integration Tests #
15 test groups executing real-world queries against actual search engines:
dart bin/integration_test.dart
Tests include:
- Text search across multiple engines
- Image, video, and news search
- Regional and language-specific searches
- Instant answers and suggestions
- Pagination and batch queries
- Caching performance (100-500x speedup verified)
- Error handling and resilience
Documentation #
- TESTING_SUMMARY.md - Complete test overview
- INTEGRATION_TEST_REPORT.md - Detailed integration test results
- QUICK_TEST_GUIDE.md - Quick reference guide
Example Scripts #
Educational examples showing common patterns:
dart bin/simple_example.dart # 5 basic examples
dart bin/integration_test.dart # Full integration tests
Note: Some search engines have anti-scraping measures. DuckDuckGo is recommended as the default backend for reliability.