Refactor news API integration to use NewsApiWrapper and GnewsWrapper; add tests for Gnews API functionality

This commit is contained in:
2025-09-30 00:34:07 +02:00
parent fc4753a245
commit c17a948ae0
10 changed files with 175 additions and 15 deletions

View File

@@ -1,3 +1,4 @@
from .news_api import NewsAPI
from .news_api import NewsApiWrapper
from .gnews_api import GnewsWrapper
__all__ = ["NewsAPI"]
__all__ = ["NewsApiWrapper", "GnewsWrapper"]

View File

@@ -6,3 +6,9 @@ class Article(BaseModel):
title: str = ""
description: str = ""
class NewsWrapper:
def get_top_headlines(self, query: str, total: int = 100) -> list[Article]:
raise NotImplementedError("This method should be overridden by subclasses")
def get_latest_news(self, query: str, total: int = 100) -> list[Article]:
raise NotImplementedError("This method should be overridden by subclasses")

31
src/app/news/gnews_api.py Normal file
View File

@@ -0,0 +1,31 @@
from gnews import GNews
from .base import Article, NewsWrapper
def result_to_article(result: dict) -> Article:
article = Article()
article.source = result.get("source", "")
article.time = result.get("publishedAt", "")
article.title = result.get("title", "")
article.description = result.get("description", "")
return article
class GnewsWrapper(NewsWrapper):
def get_top_headlines(self, query: str, total: int = 100) -> list[Article]:
gnews = GNews(language='en', max_results=total, period='7d')
results = gnews.get_top_news()
articles = []
for result in results:
article = result_to_article(result)
articles.append(article)
return articles
def get_latest_news(self, query: str, total: int = 100) -> list[Article]:
gnews = GNews(language='en', max_results=total, period='7d')
results = gnews.get_news(query)
articles = []
for result in results:
article = result_to_article(result)
articles.append(article)
return articles

View File

@@ -1,7 +1,6 @@
import os
import newsapi
from .base import Article
from .base import Article, NewsWrapper
def result_to_article(result: dict) -> Article:
article = Article()
@@ -11,7 +10,7 @@ def result_to_article(result: dict) -> Article:
article.description = result.get("description", "")
return article
class NewsAPI:
class NewsApiWrapper(NewsWrapper):
def __init__(self):
api_key = os.getenv("NEWS_API_KEY")
assert api_key is not None, "NEWS_API_KEY environment variable not set"
@@ -21,7 +20,7 @@ class NewsAPI:
self.language = "en" # TODO Only English articles for now?
self.max_page_size = 100
def get_top_headlines(self, query:str, total:int=100) -> list[Article]:
def get_top_headlines(self, query: str, total: int = 100) -> list[Article]:
page_size = min(self.max_page_size, total)
pages = (total // page_size) + (1 if total % page_size > 0 else 0)
@@ -32,4 +31,14 @@ class NewsAPI:
articles.extend(results)
return articles
def get_latest_news(self, query: str, total: int = 100) -> list[Article]:
page_size = min(self.max_page_size, total)
pages = (total // page_size) + (1 if total % page_size > 0 else 0)
articles = []
for page in range(1, pages + 1):
everything = self.client.get_everything(q=query, language=self.language, sort_by="publishedAt", page_size=page_size, page=page)
results = [result_to_article(article) for article in everything.get("articles", [])]
articles.extend(results)
return articles