Skip to content

Commit 93bc40e

Browse files
committed
fix: fix ruff lint and format issues in hackernews
1 parent fb86821 commit 93bc40e

3 files changed

Lines changed: 138 additions & 121 deletions

File tree

hackernews/hackernews.py

Lines changed: 87 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
from autohive_integrations_sdk import (
2-
Integration, ExecutionContext, ActionHandler, ActionResult
2+
Integration,
3+
ExecutionContext,
4+
ActionHandler,
5+
ActionResult,
36
)
47
from typing import Dict, Any, List, Optional
58
from datetime import datetime, timezone
@@ -20,12 +23,16 @@ async def fetch_json(context: ExecutionContext, url: str) -> Optional[Any]:
2023
return None
2124

2225

23-
async def fetch_item(context: ExecutionContext, item_id: int) -> Optional[Dict[str, Any]]:
26+
async def fetch_item(
27+
context: ExecutionContext, item_id: int
28+
) -> Optional[Dict[str, Any]]:
2429
"""Fetch a single item by ID."""
2530
return await fetch_json(context, f"{BASE_URL}/item/{item_id}.json")
2631

2732

28-
async def fetch_items_batch(context: ExecutionContext, item_ids: List[int]) -> List[Dict[str, Any]]:
33+
async def fetch_items_batch(
34+
context: ExecutionContext, item_ids: List[int]
35+
) -> List[Dict[str, Any]]:
2936
"""Fetch multiple items concurrently."""
3037
tasks = [fetch_item(context, item_id) for item_id in item_ids]
3138
results = await asyncio.gather(*tasks)
@@ -43,40 +50,42 @@ def format_item(item: Dict[str, Any]) -> Dict[str, Any]:
4350
"descendants": item.get("descendants", 0),
4451
"hn_url": f"{HN_ITEM_URL}{item.get('id')}",
4552
}
46-
53+
4754
if item.get("time"):
4855
formatted["time"] = datetime.fromtimestamp(
4956
item["time"], tz=timezone.utc
5057
).isoformat()
51-
58+
5259
if item.get("url"):
5360
formatted["url"] = item["url"]
54-
61+
5562
if item.get("text"):
5663
formatted["text"] = item["text"]
57-
64+
5865
return formatted
5966

6067

61-
def format_comment(item: Dict[str, Any], replies: List[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
68+
def format_comment(
69+
item: Dict[str, Any], replies: List[Dict[str, Any]] = None
70+
) -> Optional[Dict[str, Any]]:
6271
"""Format a comment for LLM-friendly output."""
6372
if item.get("deleted") or item.get("dead"):
6473
return None
65-
74+
6675
formatted = {
6776
"id": item.get("id"),
6877
"by": item.get("by", "[deleted]"),
6978
"text": item.get("text", ""),
7079
}
71-
80+
7281
if item.get("time"):
7382
formatted["time"] = datetime.fromtimestamp(
7483
item["time"], tz=timezone.utc
7584
).isoformat()
76-
85+
7786
if replies:
7887
formatted["replies"] = replies
79-
88+
8089
return formatted
8190

8291

@@ -85,240 +94,237 @@ async def fetch_comments_recursive(
8594
comment_ids: List[int],
8695
limit: int,
8796
current_depth: int,
88-
max_depth: int
97+
max_depth: int,
8998
) -> List[Dict[str, Any]]:
9099
"""Recursively fetch comments up to a certain depth."""
91100
if not comment_ids or current_depth > max_depth:
92101
return []
93-
102+
94103
limited_ids = comment_ids[:limit] if current_depth == 1 else comment_ids[:10]
95104
comments = await fetch_items_batch(context, limited_ids)
96-
105+
97106
result = []
98107
for comment in comments:
99108
if comment.get("deleted") or comment.get("dead"):
100109
continue
101-
110+
102111
replies = []
103112
if current_depth < max_depth and comment.get("kids"):
104113
replies = await fetch_comments_recursive(
105-
context,
106-
comment["kids"],
107-
limit,
108-
current_depth + 1,
109-
max_depth
114+
context, comment["kids"], limit, current_depth + 1, max_depth
110115
)
111-
116+
112117
formatted = format_comment(comment, replies if replies else None)
113118
if formatted:
114119
result.append(formatted)
115-
120+
116121
return result
117122

118123

119124
async def fetch_stories_list(
120-
context: ExecutionContext,
121-
endpoint: str,
122-
limit: int,
123-
output_key: str = "stories"
125+
context: ExecutionContext, endpoint: str, limit: int, output_key: str = "stories"
124126
) -> Dict[str, Any]:
125127
"""Generic function to fetch a list of stories from an endpoint."""
126128
story_ids = await fetch_json(context, f"{BASE_URL}/{endpoint}.json")
127-
129+
128130
if not story_ids:
129131
return {
130132
output_key: [],
131133
"fetched_at": datetime.now(timezone.utc).isoformat(),
132-
"count": 0
134+
"count": 0,
133135
}
134-
135-
limited_ids = story_ids[:min(limit, 100)]
136+
137+
limited_ids = story_ids[: min(limit, 100)]
136138
items = await fetch_items_batch(context, limited_ids)
137-
139+
138140
formatted_items = []
139141
for item in items:
140142
if item:
141143
formatted_items.append(format_item(item))
142-
144+
143145
return {
144146
output_key: formatted_items,
145147
"fetched_at": datetime.now(timezone.utc).isoformat(),
146-
"count": len(formatted_items)
148+
"count": len(formatted_items),
147149
}
148150

149151

150152
@hackernews.action("get_top_stories")
151153
class GetTopStoriesAction(ActionHandler):
152154
"""Fetch top stories from Hacker News."""
153155

154-
async def execute(self, inputs: Dict[str, Any], context: ExecutionContext) -> ActionResult:
156+
async def execute(
157+
self, inputs: Dict[str, Any], context: ExecutionContext
158+
) -> ActionResult:
155159
try:
156160
limit = inputs.get("limit", 30)
157161
result = await fetch_stories_list(context, "topstories", limit)
158162
return ActionResult(data=result, cost_usd=0.0)
159163
except Exception as e:
160164
return ActionResult(
161-
data={"stories": [], "count": 0, "error": str(e)},
162-
cost_usd=0.0
165+
data={"stories": [], "count": 0, "error": str(e)}, cost_usd=0.0
163166
)
164167

165168

166169
@hackernews.action("get_best_stories")
167170
class GetBestStoriesAction(ActionHandler):
168171
"""Fetch best stories from Hacker News."""
169172

170-
async def execute(self, inputs: Dict[str, Any], context: ExecutionContext) -> ActionResult:
173+
async def execute(
174+
self, inputs: Dict[str, Any], context: ExecutionContext
175+
) -> ActionResult:
171176
try:
172177
limit = inputs.get("limit", 30)
173178
result = await fetch_stories_list(context, "beststories", limit)
174179
return ActionResult(data=result, cost_usd=0.0)
175180
except Exception as e:
176181
return ActionResult(
177-
data={"stories": [], "count": 0, "error": str(e)},
178-
cost_usd=0.0
182+
data={"stories": [], "count": 0, "error": str(e)}, cost_usd=0.0
179183
)
180184

181185

182186
@hackernews.action("get_new_stories")
183187
class GetNewStoriesAction(ActionHandler):
184188
"""Fetch newest stories from Hacker News."""
185189

186-
async def execute(self, inputs: Dict[str, Any], context: ExecutionContext) -> ActionResult:
190+
async def execute(
191+
self, inputs: Dict[str, Any], context: ExecutionContext
192+
) -> ActionResult:
187193
try:
188194
limit = inputs.get("limit", 30)
189195
result = await fetch_stories_list(context, "newstories", limit)
190196
return ActionResult(data=result, cost_usd=0.0)
191197
except Exception as e:
192198
return ActionResult(
193-
data={"stories": [], "count": 0, "error": str(e)},
194-
cost_usd=0.0
199+
data={"stories": [], "count": 0, "error": str(e)}, cost_usd=0.0
195200
)
196201

197202

198203
@hackernews.action("get_ask_hn_stories")
199204
class GetAskHNStoriesAction(ActionHandler):
200205
"""Fetch Ask HN stories."""
201206

202-
async def execute(self, inputs: Dict[str, Any], context: ExecutionContext) -> ActionResult:
207+
async def execute(
208+
self, inputs: Dict[str, Any], context: ExecutionContext
209+
) -> ActionResult:
203210
try:
204211
limit = inputs.get("limit", 30)
205212
result = await fetch_stories_list(context, "askstories", limit)
206213
return ActionResult(data=result, cost_usd=0.0)
207214
except Exception as e:
208215
return ActionResult(
209-
data={"stories": [], "count": 0, "error": str(e)},
210-
cost_usd=0.0
216+
data={"stories": [], "count": 0, "error": str(e)}, cost_usd=0.0
211217
)
212218

213219

214220
@hackernews.action("get_show_hn_stories")
215221
class GetShowHNStoriesAction(ActionHandler):
216222
"""Fetch Show HN stories."""
217223

218-
async def execute(self, inputs: Dict[str, Any], context: ExecutionContext) -> ActionResult:
224+
async def execute(
225+
self, inputs: Dict[str, Any], context: ExecutionContext
226+
) -> ActionResult:
219227
try:
220228
limit = inputs.get("limit", 30)
221229
result = await fetch_stories_list(context, "showstories", limit)
222230
return ActionResult(data=result, cost_usd=0.0)
223231
except Exception as e:
224232
return ActionResult(
225-
data={"stories": [], "count": 0, "error": str(e)},
226-
cost_usd=0.0
233+
data={"stories": [], "count": 0, "error": str(e)}, cost_usd=0.0
227234
)
228235

229236

230237
@hackernews.action("get_job_stories")
231238
class GetJobStoriesAction(ActionHandler):
232239
"""Fetch job postings from Hacker News."""
233240

234-
async def execute(self, inputs: Dict[str, Any], context: ExecutionContext) -> ActionResult:
241+
async def execute(
242+
self, inputs: Dict[str, Any], context: ExecutionContext
243+
) -> ActionResult:
235244
try:
236245
limit = inputs.get("limit", 30)
237-
result = await fetch_stories_list(context, "jobstories", limit, output_key="jobs")
246+
result = await fetch_stories_list(
247+
context, "jobstories", limit, output_key="jobs"
248+
)
238249
return ActionResult(data=result, cost_usd=0.0)
239250
except Exception as e:
240251
return ActionResult(
241-
data={"jobs": [], "count": 0, "error": str(e)},
242-
cost_usd=0.0
252+
data={"jobs": [], "count": 0, "error": str(e)}, cost_usd=0.0
243253
)
244254

245255

246256
@hackernews.action("get_story_with_comments")
247257
class GetStoryWithCommentsAction(ActionHandler):
248258
"""Fetch a story with its comments."""
249259

250-
async def execute(self, inputs: Dict[str, Any], context: ExecutionContext) -> ActionResult:
260+
async def execute(
261+
self, inputs: Dict[str, Any], context: ExecutionContext
262+
) -> ActionResult:
251263
try:
252264
story_id = inputs["story_id"]
253265
comment_limit = inputs.get("comment_limit", 20)
254266
comment_depth = inputs.get("comment_depth", 2)
255-
267+
256268
story = await fetch_item(context, story_id)
257-
269+
258270
if not story:
259271
return ActionResult(
260-
data={"error": f"Story with ID {story_id} not found"},
261-
cost_usd=0.0
272+
data={"error": f"Story with ID {story_id} not found"}, cost_usd=0.0
262273
)
263-
274+
264275
comments = []
265276
if story.get("kids"):
266277
comments = await fetch_comments_recursive(
267278
context,
268279
story["kids"],
269280
comment_limit,
270281
current_depth=1,
271-
max_depth=comment_depth
282+
max_depth=comment_depth,
272283
)
273-
284+
274285
return ActionResult(
275286
data={
276287
"story": format_item(story),
277288
"comments": comments,
278-
"fetched_at": datetime.now(timezone.utc).isoformat()
289+
"fetched_at": datetime.now(timezone.utc).isoformat(),
279290
},
280-
cost_usd=0.0
291+
cost_usd=0.0,
281292
)
282293
except Exception as e:
283-
return ActionResult(
284-
data={"error": str(e)},
285-
cost_usd=0.0
286-
)
294+
return ActionResult(data={"error": str(e)}, cost_usd=0.0)
287295

288296

289297
@hackernews.action("get_user_profile")
290298
class GetUserProfileAction(ActionHandler):
291299
"""Fetch a user's public profile."""
292300

293-
async def execute(self, inputs: Dict[str, Any], context: ExecutionContext) -> ActionResult:
301+
async def execute(
302+
self, inputs: Dict[str, Any], context: ExecutionContext
303+
) -> ActionResult:
294304
try:
295305
username = inputs["username"]
296-
306+
297307
user = await fetch_json(context, f"{BASE_URL}/user/{username}.json")
298-
308+
299309
if not user:
300310
return ActionResult(
301-
data={"error": f"User '{username}' not found"},
302-
cost_usd=0.0
311+
data={"error": f"User '{username}' not found"}, cost_usd=0.0
303312
)
304-
313+
305314
result = {
306315
"id": user.get("id"),
307316
"karma": user.get("karma", 0),
308-
"profile_url": f"{HN_USER_URL}{username}"
317+
"profile_url": f"{HN_USER_URL}{username}",
309318
}
310-
319+
311320
if user.get("created"):
312321
result["created"] = datetime.fromtimestamp(
313322
user["created"], tz=timezone.utc
314323
).isoformat()
315-
324+
316325
if user.get("about"):
317326
result["about"] = user["about"]
318-
327+
319328
return ActionResult(data=result, cost_usd=0.0)
320329
except Exception as e:
321-
return ActionResult(
322-
data={"error": str(e)},
323-
cost_usd=0.0
324-
)
330+
return ActionResult(data={"error": str(e)}, cost_usd=0.0)

0 commit comments

Comments
 (0)