Coverage for mindsdb / integrations / handlers / hackernews_handler / hn_handler.py: 0%
69 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
1import requests
2import pandas as pd
3from mindsdb.utilities import log
4from mindsdb.integrations.libs.api_handler import APIHandler
5from mindsdb.integrations.libs.response import HandlerStatusResponse as StatusResponse, HandlerResponse as Response, RESPONSE_TYPE
6from .hn_table import StoriesTable, CommentsTable, HNStoriesTable, JobStoriesTable, ShowStoriesTable
8logger = log.getLogger(__name__)
11class HackerNewsHandler(APIHandler):
12 """
13 A class for handling connections and interactions with the Hacker News API.
14 """
16 def __init__(self, name=None, **kwargs):
17 super().__init__(name)
19 self.base_url = 'https://hacker-news.firebaseio.com/v0'
21 stories = StoriesTable(self)
22 self._register_table('stories', stories)
24 hnstories = HNStoriesTable(self)
25 self._register_table('hnstories', hnstories)
27 jobstories = JobStoriesTable(self)
28 self._register_table('jobstories', jobstories)
30 showstories = ShowStoriesTable(self)
31 self._register_table('showstories', showstories)
33 comments = CommentsTable(self)
34 self._register_table('comments', comments)
36 def connect(self):
37 return
39 def check_connection(self) -> StatusResponse:
40 try:
41 response = requests.get(f'{self.base_url}/maxitem.json')
42 response.raise_for_status()
43 return StatusResponse(True)
44 except Exception as e:
45 logger.error(f'Error checking connection: {e}')
46 return StatusResponse(False, str(e))
48 def native_query(self, query_string: str = None):
49 method_name, params = self.parse_native_query(query_string)
51 df = self.call_hackernews_api(method_name, params)
53 return Response(
54 RESPONSE_TYPE.TABLE,
55 data_frame=df
56 )
58 def get_df_from_class(self, table: StoriesTable = None, limit: int = None):
59 url = f'{self.base_url}/{table.json_endpoint}'
60 response = requests.get(url)
61 data = response.json()
62 stories_data = []
63 if limit is None:
64 limit = len(data)
65 for story_id in data[:limit]:
66 url = f'{self.base_url}/item/{story_id}.json'
67 response = requests.get(url)
68 story_data = response.json()
69 stories_data.append(story_data)
70 return pd.DataFrame(stories_data, columns=table.columns)
72 def call_hackernews_api(self, method_name: str = None, params: dict = None):
73 story_method_handlers = {
74 'get_top_stories': StoriesTable,
75 'ask_hn_stories': HNStoriesTable,
76 'get_job_stories': JobStoriesTable,
77 'show_hn_stories': ShowStoriesTable,
78 }
79 if method_name in story_method_handlers:
80 table = story_method_handlers[method_name]
81 df = self.get_df_from_class(table)
82 elif method_name == 'get_comments':
83 item_id = params.get('item_id')
84 url = f'{self.base_url}/item/{item_id}.json'
85 response = requests.get(url)
86 item_data = response.json()
87 if 'kids' in item_data:
88 comments_data = []
89 for comment_id in item_data['kids']:
90 url = f'{self.base_url}/item/{comment_id}.json'
91 response = requests.get(url)
92 comment_data = response.json()
93 comments_data.append(comment_data)
94 df = pd.DataFrame(comments_data)
95 else:
96 df = pd.DataFrame()
97 else:
98 raise ValueError(f'Unknown method_name: {method_name}')
100 return df