News / app.py
Badumetsibb's picture
Update app.py
4bb8669 verified
# app_news_sentiment_firebase.py
import feedparser
import pandas as pd
import gradio as gr
from transformers import pipeline
from datetime import datetime
import firebase_admin
from firebase_admin import credentials, db
import os
import json
# --- Firebase Configuration ---
# IMPORTANT: Set these environment variables in your deployment environment (e.g., Hugging Face Spaces Secrets)
# 1. FIRESTORE_SA_KEY: The full JSON content of your Firebase service account key.
# 2. FIREBASE_DB_URL: The URL to your Firebase Realtime Database.
SA_KEY_JSON = os.environ.get('FIRESTORE_SA_KEY')
DB_URL = os.environ.get('FIREBASE_DB_URL')
class NewsRTDBLogger:
def __init__(self, db_ref_name='news_sentiment'):
self.ref = None
if not all([SA_KEY_JSON, DB_URL]):
print("NEWS LOGGER: Firebase secrets not set. Logger is disabled.")
return
try:
# The service account key is loaded from a JSON string in the environment variable
cred_dict = json.loads(SA_KEY_JSON)
cred = credentials.Certificate(cred_dict)
if not firebase_admin._apps:
firebase_admin.initialize_app(cred, {'databaseURL': DB_URL})
self.ref = db.reference(db_ref_name)
print(f"NEWS LOGGER: Successfully connected to Firebase RTDB at '{db_ref_name}'.")
except Exception as e:
print(f"NEWS LOGGER: CRITICAL ERROR - Failed to initialize: {e}")
def log_sentiment(self, pub_date, headline, sentiment, confidence):
if not self.ref:
return
try:
# Create a unique key based on the timestamp to keep logs ordered
log_entry = {
"timestamp_published": pub_date,
"headline": headline,
"sentiment": sentiment,
"confidence_score": float(confidence)
}
self.ref.push(log_entry)
# print(f"NEWS LOGGER: Logged '{headline}'")
except Exception as e:
print(f"NEWS LOGGER: CRITICAL ERROR - Could not write sentiment log: {e}")
# --- Initialize Global Objects ---
sentiment_pipeline = pipeline("text-classification", model="cardiffnlp/twitter-roberta-base-sentiment-latest")
news_logger = NewsRTDBLogger() # Initialize the logger
# --- Core Functions ---
def fetch_news():
"""Fetches the latest news headlines from the FXStreet RSS feed."""
url = "https://www.fxstreet.com/rss/news"
feed = feedparser.parse(url)
# Fetch a few more headlines to ensure we get recent, unique ones
headlines = feed.entries[:15]
return headlines
def analyze_news():
"""
Analyzes news sentiment, logs it to Firebase, and returns a DataFrame for display.
"""
headlines = fetch_news()
results = []
for h in headlines:
text = h.title
# Get the publication date, fallback to now if not present
pub_date = h.get("published", datetime.utcnow().isoformat())
# Perform sentiment analysis
pred = sentiment_pipeline(text)[0]
label = pred["label"].lower()
score = round(pred["score"], 3)
if label == "positive":
market_sentiment = "Bullish"
elif label == "negative":
market_sentiment = "Bearish"
else:
market_sentiment = "Neutral"
# Log the result to Firebase
news_logger.log_sentiment(pub_date, text, market_sentiment, score)
results.append([pub_date, text, market_sentiment, score])
# Create DataFrame for Gradio output, showing the 7 most recent
df = pd.DataFrame(results, columns=["Date", "Headline", "Market Sentiment", "Confidence"])
return df.head(7)
# --- Gradio Interface ---
demo = gr.Interface(
fn=analyze_news,
inputs=None,
outputs=gr.Dataframe(headers=["Date", "Headline", "Market Sentiment", "Confidence"]),
title="๐Ÿ“Š Forex Sentiment Agent (Firebase Edition)",
description="Live Forex headlines sentiment (Bullish / Bearish / Neutral). Now logging results directly to Firebase.",
allow_flagging='never'
)
if __name__ == "__main__":
demo.launch()