-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathweb_search.py
More file actions
107 lines (88 loc) · 3 KB
/
web_search.py
File metadata and controls
107 lines (88 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""
Web Search Module
-----------------
Performs web search requests using the requests library.
Uses DuckDuckGo Instant Answer API (free, no API key required).
"""
import requests
from urllib.parse import quote
def search(query: str) -> dict:
"""
Perform a web search for the given query.
Uses DuckDuckGo Instant Answer API - a free API that returns
structured information about search queries. No API key required.
Args:
query: The search query string (e.g., "John Smith Acme Corp")
Returns:
Dictionary containing search results:
- abstract: Brief description/summary
- abstract_url: URL for more info
- related_topics: List of related search topics
- success: Whether the request succeeded
"""
if not query or not str(query).strip():
return {
"success": False,
"error": "Empty search query",
"abstract": None,
"abstract_url": None,
"related_topics": [],
}
base_url = "https://api.duckduckgo.com/"
params = {
"q": query,
"format": "json",
"no_html": 1,
}
try:
response = requests.get(base_url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
# Extract relevant fields from DuckDuckGo response
abstract = data.get("Abstract", "") or data.get("AbstractText", "")
abstract_url = data.get("AbstractURL", "")
related = data.get("RelatedTopics", [])
# Get first few related topics (simplified for display)
related_topics = []
for topic in related[:5]:
if isinstance(topic, dict) and "Text" in topic:
related_topics.append(topic.get("Text", ""))
elif isinstance(topic, str):
related_topics.append(topic)
return {
"success": True,
"query": query,
"abstract": abstract or "(No summary available)",
"abstract_url": abstract_url or None,
"related_topics": related_topics,
}
except requests.RequestException as e:
return {
"success": False,
"error": str(e),
"query": query,
"abstract": None,
"abstract_url": None,
"related_topics": [],
}
def format_search_result(result: dict) -> str:
"""
Format a search result for console display.
Args:
result: The result dictionary from search()
Returns:
Formatted string for printing
"""
if not result.get("success"):
return f" [ERROR] {result.get('error', 'Unknown error')}"
lines = [
f" Summary: {result.get('abstract', 'N/A')}",
f" URL: {result.get('abstract_url', 'N/A')}",
]
related = result.get("related_topics", [])
if related:
lines.append(" Related topics:")
for topic in related[:3]:
if topic:
lines.append(f" - {topic}")
return "\n".join(lines)