Spaces:
Running
Running
Upload 2 files
Browse files- app.py +134 -0
- requirements.txt +4 -0
app.py
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from newsdataapi import NewsDataApiClient
|
| 3 |
+
from huggingface_hub import InferenceClient
|
| 4 |
+
import os
|
| 5 |
+
|
| 6 |
+
# Initialize APIs
|
| 7 |
+
NEWS_API_KEY = os.getenv("NEWS_API_KEY")
|
| 8 |
+
HF_TOKEN = os.getenv("HF_TOKEN")
|
| 9 |
+
news_client = NewsDataApiClient(apikey=NEWS_API_KEY)
|
| 10 |
+
hf_client = InferenceClient(api_key=HF_TOKEN)
|
| 11 |
+
|
| 12 |
+
def fetch_news(query, country, language, category, max_pages):
|
| 13 |
+
"""
|
| 14 |
+
Fetch news articles using Newsdata.io API with pagination.
|
| 15 |
+
"""
|
| 16 |
+
try:
|
| 17 |
+
page = None
|
| 18 |
+
all_articles = []
|
| 19 |
+
for _ in range(max_pages):
|
| 20 |
+
response = news_client.latest_api(q=query, country=country, language=language, category=category, page=page)
|
| 21 |
+
articles = response.get('results', [])
|
| 22 |
+
if not articles:
|
| 23 |
+
break
|
| 24 |
+
all_articles.extend(articles)
|
| 25 |
+
page = response.get('nextPage', None)
|
| 26 |
+
if not page:
|
| 27 |
+
break
|
| 28 |
+
return all_articles
|
| 29 |
+
except Exception as e:
|
| 30 |
+
return f"Error: {e}"
|
| 31 |
+
|
| 32 |
+
def summarize_articles(articles, summary_length="brief"):
|
| 33 |
+
"""
|
| 34 |
+
Summarize articles using Hugging Face models.
|
| 35 |
+
"""
|
| 36 |
+
try:
|
| 37 |
+
article_texts = "\n".join([article['title'] for article in articles])
|
| 38 |
+
prompt = "Summarize briefly" if summary_length == "brief" else "Provide a detailed summary"
|
| 39 |
+
messages = [{"role": "user", "content": f"{prompt} the following news: {article_texts}"}]
|
| 40 |
+
|
| 41 |
+
completion = hf_client.chat.completions.create(
|
| 42 |
+
model="mistralai/Mistral-7B-Instruct-v0.3",
|
| 43 |
+
messages=messages,
|
| 44 |
+
max_tokens=500
|
| 45 |
+
)
|
| 46 |
+
return completion.choices[0].message['content']
|
| 47 |
+
except Exception as e:
|
| 48 |
+
return f"Error: {e}"
|
| 49 |
+
|
| 50 |
+
def gradio_interface(query, country, language, category, max_pages, summary_length):
|
| 51 |
+
"""
|
| 52 |
+
Unified interface for fetching and summarizing news articles.
|
| 53 |
+
"""
|
| 54 |
+
country = country.split(" (")[-1][:-1] # Extract the code part from the dropdown choice
|
| 55 |
+
articles = fetch_news(query, country, language, category, max_pages)
|
| 56 |
+
if isinstance(articles, str): # Error handling
|
| 57 |
+
return articles, []
|
| 58 |
+
|
| 59 |
+
summaries = summarize_articles(articles, summary_length)
|
| 60 |
+
article_titles = [article['title'] for article in articles]
|
| 61 |
+
|
| 62 |
+
# Update the dropdown with new article titles
|
| 63 |
+
return summaries, gr.update(choices = article_titles, value = article_titles[0])
|
| 64 |
+
|
| 65 |
+
countries = [
|
| 66 |
+
"Afghanistan (af)", "Albania (al)", "Algeria (dz)", "Andorra (ad)", "Angola (ao)", "Argentina (ar)", "Armenia (am)",
|
| 67 |
+
"Australia (au)", "Austria (at)", "Azerbaijan (az)", "Bahamas (bs)", "Bahrain (bh)", "Bangladesh (bd)", "Barbados (bb)",
|
| 68 |
+
"Belarus (by)", "Belgium (be)", "Belize (bz)", "Benin (bj)", "Bermuda (bm)", "Bhutan (bt)", "Bolivia (bo)",
|
| 69 |
+
"Bosnia And Herzegovina (ba)", "Botswana (bw)", "Brazil (br)", "Brunei (bn)", "Bulgaria (bg)", "Burkina Faso (bf)",
|
| 70 |
+
"Burundi (bi)", "Cambodia (kh)", "Cameroon (cm)", "Canada (ca)", "Cape Verde (cv)", "Cayman Islands (ky)",
|
| 71 |
+
"Central African Republic (cf)", "Chad (td)", "Chile (cl)", "China (cn)", "Colombia (co)", "Comoros (km)", "Congo (cg)",
|
| 72 |
+
"Cook Islands (ck)", "Costa Rica (cr)", "Croatia (hr)", "Cuba (cu)", "Curaçao (cw)", "Cyprus (cy)", "Czech Republic (cz)",
|
| 73 |
+
"Denmark (dk)", "Djibouti (dj)", "Dominica (dm)", "Dominican Republic (do)", "DR Congo (cd)", "Ecuador (ec)",
|
| 74 |
+
"Egypt (eg)", "El Salvador (sv)", "Equatorial Guinea (gq)", "Eritrea (er)", "Estonia (ee)", "Eswatini (sz)",
|
| 75 |
+
"Ethiopia (et)", "Fiji (fj)", "Finland (fi)", "France (fr)", "French Polynesia (pf)", "Gabon (ga)", "Gambia (gm)",
|
| 76 |
+
"Georgia (ge)", "Germany (de)", "Ghana (gh)", "Gibraltar (gi)", "Greece (gr)", "Grenada (gd)", "Guatemala (gt)",
|
| 77 |
+
"Guinea (gn)", "Guyana (gy)", "Haiti (ht)", "Honduras (hn)", "Hong Kong (hk)", "Hungary (hu)", "Iceland (is)",
|
| 78 |
+
"India (in)", "Indonesia (id)", "Iran (ir)", "Iraq (iq)", "Ireland (ie)", "Israel (il)", "Italy (it)", "Ivory Coast (ci)",
|
| 79 |
+
"Jamaica (jm)", "Japan (jp)", "Jersey (je)", "Jordan (jo)", "Kazakhstan (kz)", "Kenya (ke)", "Kiribati (ki)",
|
| 80 |
+
"Kosovo (xk)", "Kuwait (kw)", "Kyrgyzstan (kg)", "Laos (la)", "Latvia (lv)", "Lebanon (lb)", "Lesotho (ls)", "Liberia (lr)",
|
| 81 |
+
"Libya (ly)", "Liechtenstein (li)", "Lithuania (lt)", "Luxembourg (lu)", "Macau (mo)", "Macedonia (mk)", "Madagascar (mg)",
|
| 82 |
+
"Malawi (mw)", "Malaysia (my)", "Maldives (mv)", "Mali (ml)", "Malta (mt)", "Marshall Islands (mh)", "Mauritania (mr)",
|
| 83 |
+
"Mauritius (mu)", "Mexico (mx)", "Micronesia (fm)", "Moldova (md)", "Monaco (mc)", "Mongolia (mn)", "Montenegro (me)",
|
| 84 |
+
"Morocco (ma)", "Mozambique (mz)", "Myanmar (mm)", "Namibia (na)", "Nauru (nr)", "Nepal (np)", "Netherlands (nl)",
|
| 85 |
+
"New Caledonia (nc)", "New Zealand (nz)", "Nicaragua (ni)", "Niger (ne)", "Nigeria (ng)", "North Korea (kp)", "Norway (no)",
|
| 86 |
+
"Oman (om)", "Pakistan (pk)", "Palau (pw)", "Palestine (ps)", "Panama (pa)", "Papua New Guinea (pg)", "Paraguay (py)",
|
| 87 |
+
"Peru (pe)", "Philippines (ph)", "Poland (pl)", "Portugal (pt)", "Puerto Rico (pr)", "Qatar (qa)", "Romania (ro)",
|
| 88 |
+
"Russia (ru)", "Rwanda (rw)", "Saint Lucia (lc)", "Saint Martin (sx)", "Samoa (ws)", "San Marino (sm)", "São Tomé and Príncipe (st)",
|
| 89 |
+
"Saudi Arabia (sa)", "Senegal (sn)", "Serbia (rs)", "Seychelles (sc)", "Sierra Leone (sl)", "Singapore (sg)", "Slovakia (sk)",
|
| 90 |
+
"Slovenia (si)", "Solomon Islands (sb)", "Somalia (so)", "South Africa (za)", "South Korea (kr)", "Spain (es)", "Sri Lanka (lk)",
|
| 91 |
+
"Sudan (sd)", "Suriname (sr)", "Sweden (se)", "Switzerland (ch)", "Syria (sy)", "Taiwan (tw)", "Tajikistan (tj)", "Tanzania (tz)",
|
| 92 |
+
"Thailand (th)", "Timor-Leste (tl)", "Togo (tg)", "Tonga (to)", "Trinidad and Tobago (tt)", "Tunisia (tn)", "Turkey (tr)",
|
| 93 |
+
"Turkmenistan (tm)", "Tuvalu (tv)", "Uganda (ug)", "Ukraine (ua)", "United Arab Emirates (ae)", "United Kingdom (gb)",
|
| 94 |
+
"United States of America (us)", "Uruguay (uy)", "Uzbekistan (uz)", "Vanuatu (vu)", "Vatican (va)", "Venezuela (ve)",
|
| 95 |
+
"Vietnam (vi)", "Virgin Islands (British) (vg)", "World (wo)", "Yemen (ye)", "Zambia (zm)", "Zimbabwe (zw)"
|
| 96 |
+
]
|
| 97 |
+
|
| 98 |
+
categories = [
|
| 99 |
+
"business", "crime", "domestic", "education", "entertainment",
|
| 100 |
+
"environment", "food", "health", "lifestyle", "other",
|
| 101 |
+
"politics", "science", "sports", "technology", "top",
|
| 102 |
+
"tourism", "world"
|
| 103 |
+
]
|
| 104 |
+
|
| 105 |
+
# Gradio UI
|
| 106 |
+
with gr.Blocks() as demo:
|
| 107 |
+
# Add Horizontal Bar for App Name and Description using gr.HTML
|
| 108 |
+
gr.HTML(
|
| 109 |
+
"""
|
| 110 |
+
<div style="background-color: #2C3E50; padding: 15px; text-align: center;">
|
| 111 |
+
<h1 style="color: white;">Newsify-AI</h1>
|
| 112 |
+
<p style="color: #BDC3C7;">Summarize news articles using AI-powered insights</p>
|
| 113 |
+
</div>
|
| 114 |
+
"""
|
| 115 |
+
)
|
| 116 |
+
with gr.Row():
|
| 117 |
+
query = gr.Textbox(label="Query/Keyword", placeholder="E.g., Ronaldo", value="")
|
| 118 |
+
with gr.Row():
|
| 119 |
+
country = gr.Dropdown(label="Country",choices=countries, value="United States of America (us)" )
|
| 120 |
+
language = gr.Textbox(label="Language", placeholder="E.g., en", value="en", interactive= False)
|
| 121 |
+
category = gr.Dropdown(label="Category", choices=categories, value="sports")
|
| 122 |
+
max_pages = gr.Number(label="Max Pages to Fetch", value=1, precision=0, interactive=False)
|
| 123 |
+
summary_length = gr.Radio(["brief", "detailed"], label="Summary Length", value="brief")
|
| 124 |
+
|
| 125 |
+
fetch_button = gr.Button("Fetch & Summarize")
|
| 126 |
+
summary_output = gr.Textbox(label="Summarized News", lines=10)
|
| 127 |
+
links_dropdown = gr.Dropdown(label="Article Links", choices=[], interactive=True, allow_custom_value = True)
|
| 128 |
+
|
| 129 |
+
fetch_button.click(gradio_interface,
|
| 130 |
+
inputs=[query, country, language, category, max_pages, summary_length],
|
| 131 |
+
outputs=[summary_output, links_dropdown])
|
| 132 |
+
|
| 133 |
+
if __name__ == "__main__":
|
| 134 |
+
demo.launch(debug=True)
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
streamlit
|
| 2 |
+
requests
|
| 3 |
+
newsdataapi
|
| 4 |
+
huggingface-hub
|