radames's picture
radames HF staff
bump version and use Docker
1b06101
from flask import Flask, request, jsonify
from flask_cors import CORS
import os
from dotenv import load_dotenv
from transformers import pipeline
import feedparser
import json
from dateutil import parser
import re
load_dotenv()
# Load Setiment Classifier
sentiment_analysis = pipeline(
"sentiment-analysis", model="siebert/sentiment-roberta-large-english"
)
app = Flask(__name__, static_url_path="", static_folder="dist")
CORS(app)
@app.route("/")
def index():
return app.send_static_file("index.html")
@app.route("/api/news")
def get_news():
feed_url = request.args.get("feed_url")
# check if string is a valid
# file name for cache
file_name = "".join(re.split(r"https://|\.|/", feed_url))
feed_entries = get_feed(feed_url)
# filter only titles for sentiment analysis
try:
with open(f"{file_name}_cache.json") as file:
cache = json.load(file)
except:
cache = {}
# if new homepage is newer than cache, update cache and return
print("new date", feed_entries["last_update"])
print("old date", cache["last_update"] if "last_update" in cache else "None")
if not cache or parser.parse(feed_entries["last_update"]) > parser.parse(
cache["last_update"]
):
print("Updating cache with new preditions")
titles = [entry["title"] for entry in feed_entries["entries"]]
# run sentiment analysis on titles
predictions = [sentiment_analysis(sentence) for sentence in titles]
# parse Negative and Positive, normalize to -1 to 1
predictions = [
-prediction[0]["score"]
if prediction[0]["label"] == "NEGATIVE"
else prediction[0]["score"]
for prediction in predictions
]
# merge rss data with predictions
entries_predicitons = [
{**entry, "sentiment": prediction}
for entry, prediction in zip(feed_entries["entries"], predictions)
]
output = {
"entries": entries_predicitons,
"last_update": feed_entries["last_update"],
}
# update last precitions cache
with open(f"{file_name}_cache.json", "w") as file:
json.dump(output, file)
# send back json
return jsonify(output)
else:
print("Returning cached predictions")
return jsonify(cache)
@app.route("/api/predict", methods=["POST"])
def predict():
# get data from POST
if request.method == "POST":
# get current news
# get post body data
data = request.get_json()
if data.get("sentences") is None:
return jsonify({"error": "No text provided"})
# get post expeceted to be under {'sentences': ['text': '...']}
sentences = data.get("sentences")
# prencit sentiments
predictions = [sentiment_analysis(sentence) for sentence in sentences]
# parse Negative and Positive, normalize to -1 to 1
predictions = [
-prediction[0]["score"]
if prediction[0]["label"] == "NEGATIVE"
else prediction[0]["score"]
for prediction in predictions
]
output = [
dict(sentence=sentence, sentiment=prediction)
for sentence, prediction in zip(sentences, predictions)
]
# send back json
return jsonify(output)
def get_feed(feed_url):
feed = feedparser.parse(feed_url)
return {"entries": feed["entries"], "last_update": feed["feed"]["updated"]}
if __name__ == "__main__":
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 7860)))