73 lines
2.3 KiB
Python
73 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Unified search via local search-hub API (port 8650).
|
|
Supports baidu, tavily, searxng, duckduckgo sources.
|
|
|
|
Usage:
|
|
python3 search.py "<query>" [--source auto] [--limit 5]
|
|
"""
|
|
import json
|
|
import sys
|
|
import urllib.request
|
|
import urllib.error
|
|
|
|
SEARCH_API = "http://192.168.5.14:8650"
|
|
|
|
def search(query: str, source: str = "auto", max_results: int = 5) -> dict:
|
|
payload = json.dumps({
|
|
"query": query,
|
|
"source": source,
|
|
"max_results": max_results,
|
|
}).encode("utf-8")
|
|
|
|
req = urllib.request.Request(
|
|
f"{SEARCH_API}/api/search",
|
|
data=payload,
|
|
headers={"Content-Type": "application/json"},
|
|
method="POST",
|
|
)
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
return json.loads(resp.read().decode("utf-8"))
|
|
except urllib.error.HTTPError as e:
|
|
return {"error": f"HTTP {e.code}: {e.reason}", "results": []}
|
|
except urllib.error.URLError as e:
|
|
return {"error": f"Connection failed: {e.reason}", "results": []}
|
|
except Exception as e:
|
|
return {"error": str(e), "results": []}
|
|
|
|
if __name__ == "__main__":
|
|
args = sys.argv[1:]
|
|
if not args:
|
|
print(json.dumps({"error": "No query provided"}, ensure_ascii=False))
|
|
sys.exit(1)
|
|
|
|
query = args[0]
|
|
source = "auto"
|
|
limit = 5
|
|
for i, a in enumerate(args[1:]):
|
|
if a == "--source" and i + 1 < len(args[1:]):
|
|
source = args[1:][i + 1]
|
|
elif a == "--limit" and i + 1 < len(args[1:]):
|
|
limit = int(args[1:][i + 1])
|
|
|
|
result = search(query, source, limit)
|
|
# Clean up for agent consumption
|
|
output = {
|
|
"query": result.get("query", query),
|
|
"source": result.get("source", source),
|
|
"elapsed": result.get("elapsed", 0),
|
|
"total": result.get("total", len(result.get("results", []))),
|
|
"results": [
|
|
{
|
|
"title": r.get("title", ""),
|
|
"url": r.get("url", ""),
|
|
"content": r.get("content", ""),
|
|
"source": r.get("source", ""),
|
|
}
|
|
for r in result.get("results", [])[:limit]
|
|
],
|
|
}
|
|
if "error" in result:
|
|
output["error"] = result["error"]
|
|
print(json.dumps(output, ensure_ascii=False, indent=2))
|