feat: Reworked chunking and retrieval logic to operate on entire stories instead of chunks.

This commit is contained in:
Adrian Rumpold
2025-07-01 13:08:45 +02:00
parent f093a488f3
commit b55fd6a021
8 changed files with 442 additions and 920 deletions

30
hn.py
View File

@@ -1,3 +1,4 @@
import asyncio
from datetime import datetime
import dateutil.parser
@@ -16,16 +17,16 @@ class Story(BaseModel):
class HackerNewsClient:
def __init__(self, client: httpx.Client | None = None):
def __init__(self, client: httpx.AsyncClient | None = None):
base_url = "https://hn.algolia.com/api/v1"
if client:
client.base_url = base_url
self._client = client
else:
self._client = httpx.Client(base_url=base_url)
self._client = httpx.AsyncClient(base_url=base_url)
def get_top_stories(self, limit: int = 10) -> list[Story]:
resp = self._client.get(
async def get_top_stories(self, limit: int = 10) -> list[Story]:
resp = await self._client.get(
"search",
params={"tags": "front_page", "hitsPerPage": limit, "page": 0},
)
@@ -40,7 +41,24 @@ class HackerNewsClient:
for hit in resp.json().get("hits", [])
]
def get_item(self, item_id):
resp = self._client.get(f"items/{item_id}")
async def get_item(self, item_id):
resp = await self._client.get(f"items/{item_id}")
resp.raise_for_status()
return resp.json()
async def close(self):
"""Close the underlying HTTP client."""
if self._client and not self._client.is_closed:
await self._client.aclose()
def __del__(self):
"""Ensure the HTTP client is closed when the object is deleted."""
try:
loop = asyncio.get_event_loop()
if loop.is_running():
loop.create_task(self.close())
else:
loop.run_until_complete(self.close())
except Exception:
pass