79 lines
2.5 KiB
Python
79 lines
2.5 KiB
Python
"""Hacker News client using the Algolia HN Search API.
|
|
|
|
No authentication required. Docs: https://hn.algolia.com/api
|
|
"""
|
|
|
|
import httpx
|
|
|
|
HN_API_BASE = "https://hn.algolia.com/api/v1"
|
|
|
|
|
|
async def search_stories(query: str, limit: int = 25) -> list[dict]:
|
|
"""Search HN for stories matching a query.
|
|
|
|
Returns a list of story dicts with: title, url, author, points,
|
|
num_comments, created_at, objectID, story_text.
|
|
"""
|
|
async with httpx.AsyncClient(timeout=15) as client:
|
|
resp = await client.get(
|
|
f"{HN_API_BASE}/search",
|
|
params={
|
|
"query": query,
|
|
"tags": "story",
|
|
"hitsPerPage": min(limit, 50),
|
|
},
|
|
)
|
|
resp.raise_for_status()
|
|
data = resp.json()
|
|
|
|
results = []
|
|
for hit in data.get("hits", []):
|
|
results.append(
|
|
{
|
|
"title": hit.get("title", ""),
|
|
"url": hit.get("url", ""),
|
|
"author": hit.get("author", ""),
|
|
"points": hit.get("points", 0),
|
|
"num_comments": hit.get("num_comments", 0),
|
|
"created_at": hit.get("created_at", ""),
|
|
"object_id": hit.get("objectID", ""),
|
|
"story_text": hit.get("story_text") or "",
|
|
"hn_url": f"https://news.ycombinator.com/item?id={hit.get('objectID', '')}",
|
|
}
|
|
)
|
|
return results
|
|
|
|
|
|
async def search_comments(query: str, limit: int = 25) -> list[dict]:
|
|
"""Search HN for comments matching a query.
|
|
|
|
Returns a list of comment dicts with: comment_text, author, points,
|
|
created_at, story_title, story_url.
|
|
"""
|
|
async with httpx.AsyncClient(timeout=15) as client:
|
|
resp = await client.get(
|
|
f"{HN_API_BASE}/search",
|
|
params={
|
|
"query": query,
|
|
"tags": "comment",
|
|
"hitsPerPage": min(limit, 50),
|
|
},
|
|
)
|
|
resp.raise_for_status()
|
|
data = resp.json()
|
|
|
|
results = []
|
|
for hit in data.get("hits", []):
|
|
results.append(
|
|
{
|
|
"comment_text": hit.get("comment_text", ""),
|
|
"author": hit.get("author", ""),
|
|
"points": hit.get("points", 0),
|
|
"created_at": hit.get("created_at", ""),
|
|
"story_title": hit.get("story_title", ""),
|
|
"story_url": hit.get("story_url", ""),
|
|
"hn_url": f"https://news.ycombinator.com/item?id={hit.get('objectID', '')}",
|
|
}
|
|
)
|
|
return results
|