import os import feedparser from flask import Flask, render_template from huggingface_hub import HfApi, Repository from langchain_huggingface import HuggingFaceInferenceClient from langchain.vectorstores import Chroma from langchain.embeddings import HuggingFaceEmbeddings from langchain.docstore.document import Document import requests import shutil # Flask app setup app = Flask(__name__) # Hugging Face setup HF_API_TOKEN = os.getenv("HF_API_TOKEN", "YOUR_HF_API_TOKEN") HF_MODEL = "Qwen/Qwen-72B-Instruct" # Qwen-72B model REPO_ID = "your-username/news-rag-db" # Replace with your HF repo ID LOCAL_DB_DIR = "chroma_db" client = HuggingFaceInferenceClient(model=HF_MODEL, api_key=HF_API_TOKEN) # RSS feeds to fetch (example list) RSS_FEEDS = [ "http://rss.cnn.com/rss/cnn_topstories.rss", "https://feeds.bbci.co.uk/news/rss.xml", "https://www.npr.org/rss/rss.php?id=1001", ] # Embedding model for vectorization embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2") # Initialize Chroma DB vector_db = Chroma(persist_directory=LOCAL_DB_DIR, embedding_function=embedding_model) # HfApi for Hugging Face Hub hf_api = HfApi() def fetch_rss_feeds(): """Fetch news articles from RSS feeds.""" articles = [] for feed_url in RSS_FEEDS: feed = feedparser.parse(feed_url) for entry in feed.entries[:5]: # Limit to 5 articles per feed for demo articles.append({ "title": entry.get("title", "No Title"), "link": entry.get("link", ""), "description": entry.get("summary", entry.get("description", "No Description")), "published": entry.get("published", "Unknown Date"), }) return articles def summarize_article(text): """Summarize text using Qwen-72B via InferenceClient.""" prompt = f"Summarize the following text in a concise manner:\n\n{text}" response = client.generate(prompt, max_new_tokens=100, temperature=0.7) return response.generated_text.strip() def categorize_article(text): """Categorize text into positive, negative, or neutral using Qwen-72B.""" prompt = f"Classify the sentiment of the following text as positive, negative, or neutral:\n\n{text}" response = client.generate(prompt, max_new_tokens=10, temperature=0.7) return response.generated_text.strip() def process_and_store_articles(articles): """Process articles: summarize, categorize, vectorize, and store in RAG DB.""" documents = [] for article in articles: # Summarize and categorize summary = summarize_article(article["description"]) category = categorize_article(article["description"]) # Create document with metadata doc = Document( page_content=summary, metadata={ "title": article["title"], "link": article["link"], "original_description": article["description"], "published": article["published"], "category": category, } ) documents.append(doc) # Vectorize and store in Chroma DB vector_db.add_documents(documents) vector_db.persist() # Upload to Hugging Face Hub upload_to_hf_hub() def upload_to_hf_hub(): """Upload the Chroma DB to Hugging Face Hub.""" if os.path.exists(LOCAL_DB_DIR): # Check if repo exists, create if not try: hf_api.create_repo(repo_id=REPO_ID, repo_type="dataset", exist_ok=True) except Exception as e: print(f"Error creating repo: {e}") # Upload all files in the DB directory for root, _, files in os.walk(LOCAL_DB_DIR): for file in files: local_path = os.path.join(root, file) remote_path = os.path.relpath(local_path, LOCAL_DB_DIR) hf_api.upload_file( path_or_fileobj=local_path, path_in_repo=remote_path, repo_id=REPO_ID, repo_type="dataset", token=HF_API_TOKEN ) print(f"Database uploaded to Hugging Face Hub: {REPO_ID}") @app.route('/') def index(): """Render the Flask frontend with news articles.""" articles = fetch_rss_feeds() process_and_store_articles(articles) # Retrieve summaries from the vector DB for display stored_docs = vector_db.similarity_search("news", k=len(articles)) enriched_articles = [] for doc in stored_docs: enriched_articles.append({ "title": doc.metadata["title"], "link": doc.metadata["link"], "summary": doc.page_content, "category": doc.metadata["category"], "published": doc.metadata["published"], }) return render_template("index.html", articles=enriched_articles) # HTML template as a string (for simplicity) HTML_TEMPLATE = """