Skip to content

Commit fa66479

Browse files
committed
Create news_oversimplifier.py
Python command-line tool that fetches recent news articles based on a search query using NewsAPI and summarizes the article content using extractive summarization. You can also save the summaries to a text file.
1 parent e40588d commit fa66479

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed

news_oversimplifier.py

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# news_oversimplifier.py
2+
# Python command-line tool that fetches recent news articles based on a search query using NewsAPI and summarizes the article content using extractive summarization. You can also save the summaries to a text file.
3+
4+
# (requires API key in .env file)
5+
6+
import requests
7+
import os
8+
import sys
9+
from dotenv import load_dotenv
10+
from summa.summarizer import summarize
11+
12+
13+
def main():
14+
15+
# loads .env variables
16+
load_dotenv()
17+
API_KEY = os.getenv("NEWS_API_KEY")
18+
19+
# check validity of command-line arguments
20+
try:
21+
if len(sys.argv) == 2:
22+
news_query = sys.argv[1]
23+
else:
24+
raise IndexError()
25+
except IndexError:
26+
sys.exit('Please provide correct number of command-line arguments')
27+
28+
try:
29+
# get number of articles from user
30+
while True:
31+
try:
32+
num_articles = int(input('Enter number of articles: '))
33+
break
34+
except ValueError:
35+
continue
36+
37+
# fetch news articles based on user's query
38+
articles = fetch_news(API_KEY, query=news_query, max_articles=num_articles)
39+
40+
# output printing title, summary and no. of words in the summary
41+
for i, article in enumerate(articles):
42+
capitalized_title = capitalize_title(article["title"])
43+
print(f"\n{i+1}. {capitalized_title}")
44+
45+
content = article.get("content") or article.get("description") or ""
46+
if not content.strip():
47+
print("No content to oversimplify.")
48+
continue
49+
50+
summary = summarize_text(content) # returns summary
51+
count = word_count(summary) # returns word count
52+
print(f"\nOVERSIMPLIFIED:\n{summary}\n{count} words\n")
53+
54+
# ask user whether they want to save the output in a txt file
55+
while True:
56+
saving_status = input(
57+
"Would you like to save this in a text file? (y/n): ").strip().lower()
58+
if saving_status == "y":
59+
save_summary(article["title"], summary)
60+
break
61+
elif saving_status == "n":
62+
break
63+
else:
64+
print('Try again\n')
65+
continue
66+
67+
except Exception as e:
68+
print("ERROR:", e)
69+
70+
71+
def word_count(text): # pytest in test file
72+
"""
73+
Returns the number of words in the given text.
74+
75+
args:
76+
text (str): Input string to count words from.
77+
78+
returns:
79+
int: Number of words in the string.
80+
"""
81+
return len(text.split())
82+
83+
84+
def summarize_text(text, ratio=0.6): # pytest in test file
85+
"""
86+
Summarizes the given text using the summa library.
87+
88+
args:
89+
text (str): The input text to summarize.
90+
ratio (float): Ratio of the original text to retain in the summary.
91+
92+
returns:
93+
str: The summarized text, or a fallback message if intro is present or summary is empty.
94+
"""
95+
summary = summarize(text, ratio=ratio)
96+
if summary.lower().startswith("hello, and welcome to decoder!"):
97+
return "No description available for this headline"
98+
else:
99+
return summary.strip() if summary else text
100+
101+
102+
def capitalize_title(title): # pytest in test file
103+
"""
104+
Capitalizes all letters in a given article title.
105+
106+
args:
107+
title (str): The title to format.
108+
109+
returns:
110+
str: Title in uppercase with surrounding spaces removed.
111+
"""
112+
return title.upper().strip()
113+
114+
115+
def fetch_news(api_key, query, max_articles=5): # no pytest
116+
"""
117+
Fetches a list of news articles from NewsAPI based on a query string.
118+
119+
args:
120+
api_key (str): NewsAPI key loaded from environment.
121+
query (str): The keyword to search for in news articles.
122+
max_articles (int): Maximum number of articles to fetch.
123+
124+
returns:
125+
list: List of dictionaries, each representing a news article.
126+
127+
raises:
128+
Exception: If the API response status is not 'ok'.
129+
"""
130+
url = (
131+
f"https://newsapi.org/v2/everything?q={query}&language=en&apiKey={api_key}&pageSize={max_articles}"
132+
)
133+
response = requests.get(url)
134+
data = response.json()
135+
if data.get("status") != "ok":
136+
raise Exception("Failed to fetch news:", data.get("message"))
137+
return data["articles"]
138+
139+
140+
def save_summary(title, summary, path="summaries.txt"): # no pytest
141+
"""
142+
Appends a formatted summary to a file along with its title.
143+
144+
args:
145+
title (str): Title of the article.
146+
summary (str): Summarized text to save.
147+
path (str): File path to save the summary, i.e. 'summaries.txt'
148+
"""
149+
with open(path, "a", encoding="utf-8") as f:
150+
f.write(f"{title}\n{summary}\n{'='*60}\n")
151+
152+
153+
if __name__ == "__main__":
154+
main()

0 commit comments

Comments
 (0)