import streamlit as st import requests import os import json import boto3 from dotenv import load_dotenv # API Key (Ensure security; do not share publicly) # API_KEY = "67bd857847938bebf6b0ff82a26ba45f251986f3" # Define the API endpoint # API_URL = "https://google.serper.dev/search" # Load API keys from .env file load_dotenv() NEWS_API_KEY = "3d542da6aaa94a79ad7d2b852e944dac" SERPER_API_KEY = "67bd857847938bebf6b0ff82a26ba45f251986f3" # Claude 3 via AWS Bedrock bedrock = boto3.client("bedrock-runtime", region_name=os.getenv("AWS_REGION")) # Streamlit app UI st.title("📰 News Summarizer Agent") topic = st.text_input("Enter a topic, company name, or keyword:") # Fetch news from NewsAPI def fetch_newsapi_news(topic): url = f"https://newsapi.org/v2/everything?q={topic}&pageSize=5&sortBy=publishedAt&apiKey={NEWS_API_KEY}" response = requests.get(url) articles = response.json().get("articles", []) return [{"title": a["title"], "description": a["description"], "url": a["url"]} for a in articles] # Fetch news from Serper.dev def fetch_serper_news(topic): url = "https://google.serper.dev/news" headers = {"X-API-KEY": SERPER_API_KEY, "Content-Type": "application/json"} data = {"q": topic} response = requests.post(url, headers=headers, data=json.dumps(data)) results = response.json().get("news", [])[:5] return [{"title": r["title"], "description": r.get("snippet", ""), "url": r["link"]} for r in results] # Summarize with Claude 3 def summarize_with_claude(article): messages = [ { "role": "user", "content": f"""You are a helpful news summarizer agent. Given the article title and description, generate: 1. A more relevant headline based on the topic 2. A 3-5 line clear and concise summary. Title: {article['title']} Description: {article['description']} Respond as: Headline: ... Summary: ... """ } ] body = { "messages": messages, "max_tokens": 300, "temperature": 0.7, "anthropic_version": "bedrock-2023-05-31" # REQUIRED } response = bedrock.invoke_model( modelId="anthropic.claude-3-sonnet-20240229-v1:0", body=json.dumps(body), contentType="application/json", accept="application/json" ) result = json.loads(response["body"].read()) return result["content"][0]["text"].strip() # Button and main logic if st.button("Get News"): if not topic: st.warning("Please enter a topic.") else: st.subheader("Fetching top news...") news_items = fetch_newsapi_news(topic) + fetch_serper_news(topic) for idx, article in enumerate(news_items[:5]): st.markdown(f"### 🗞️ News #{idx+1}") st.markdown(f"[Original Article]({article['url']})") with st.spinner("Generating summary..."): summary = summarize_with_claude(article) st.markdown(summary)