from PIL import Image, ImageDraw, ImageFont from textwrap import wrap import requests import numpy as np import gradio as gr import matplotlib.pyplot as plt import seaborn as sns from matplotlib.backends.backend_agg import FigureCanvasAgg from io import BytesIO import os import configparser import tweepy config = configparser.ConfigParser() config.read('./config.ini') api_key = os.environ.get('api_key') api_key_secret = os.environ.get('api_key_secret') access_token = os.environ.get('access_token') access_token_secret = os.environ.get('access_token_secret') huggingFaceAuth = os.environ.get('Huggingface_Authorization') # Authenticate with Twitter auth = tweepy.OAuthHandler(api_key, api_key_secret) auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth) tweets = [] def drawTweet(tweet,i): width, height = 1000, 200 image = Image.new('RGBA', (width, height), 'white') draw = ImageDraw.Draw(image) font = ImageFont.truetype('SofiaSansCondensed-VariableFont_wght.ttf', size=36, encoding='utf-16') user = tweet.user user_tag = user.screen_name tweet_text = tweet.full_text words = tweet_text.split() formatted_string = '' for i, word in enumerate(words): formatted_string += word+' ' if (i + 1) % 10 == 0: formatted_string += '\n' draw.multiline_text( (135,50), formatted_string , fill='black' , font=font, embedded_color=True) draw.text((135,10), f"@{user_tag}", fill='black',font=font) response = requests.get(user.profile_image_url_https) content = response.content f = BytesIO(content) avatar_size = (100, 100) avatar_image = Image.open(f) avatar_image = avatar_image.resize(avatar_size) image.paste(avatar_image, (10, 10)) return image def collect_tweets(topic): limit=200 tweets = tweepy.Cursor(api.search_tweets,q=f"{topic} -filter:retweets", lang="en", tweet_mode='extended', result_type = 'recent').items(limit) tweets = [tweet for tweet in tweets] images = [] i = 1 for tweet in tweets: img = drawTweet(tweet,i) images.append(img) sentiment_plot = sentiment_analysis(tweets,topic) return images,sentiment_plot def sentiment_analysis(tweets,topic): tweet_procs = [] for tweet in tweets: tweet_words = [] for word in tweet.full_text.split(' '): if word.startswith('@') and len(word) > 1: word = '@user' elif word.startswith('https'): word = "http" tweet_words.append(word) tweet_proc = " ".join(tweet_words) tweet_procs.append(tweet_proc) API_URL = "https://api-inference.huggingface.co/models/cardiffnlp/twitter-roberta-base-sentiment" headers = {"Authorization": huggingFaceAuth} def query(payload): response = requests.post(API_URL, headers=headers, json=payload) return response.json() model_input = { "inputs": [tweet_procs[0]] } for i in range(1,len(tweets)): model_input["inputs"].append(tweet_procs[i]) output = query({ "inputs": model_input["inputs"]}) negative = 0 neutral = 0 positive = 0 for score in output: neg = 0 neu = 0 pos = 0 for labels in score: if labels['label'] == 'LABEL_0': neg += labels['score'] elif labels['label'] == 'LABEL_1': neu += labels['score'] elif labels['label'] == 'LABEL_2': pos += labels['score'] sentiment = max(neg,neu,pos) if neg == sentiment: negative += 1 elif neu == sentiment: neutral += 1 elif pos == sentiment: positive += 1 sns.barplot(x=["Negative Sentiment", "Neutral Sentiment", "Positive Sentiment"], y = [negative,neutral,positive]) plt.title(f"Sentiment Analysis on Twitter regarding {topic}") canvas = FigureCanvasAgg(plt.gcf()) canvas.draw() plot = np.array(canvas.buffer_rgba()) return plot with gr.Blocks() as app: with gr.Column(): gr.Markdown(""" # Due to Twitter's restriction on free tier API access, the app will not work properly. ## If you are a recuriter who would like to view a functioning version of this app, please send me a direct message. """) topic = gr.Textbox(label="Enter a topic for tweets") output2 = gr.Image(label="Sentiment Analysis Result") output1 = gr.Gallery(label="Screenshot of Tweets", show_label=True, elem_id="gallery").style(grid=[3], height="50", width="80") greet_btn = gr.Button("Initiate Sentiment Analysis") greet_btn.click(collect_tweets, inputs=topic, outputs=[output1, output2]) app.launch()