|
import gradio as gr |
|
from openai import OpenAI |
|
import json |
|
import os |
|
|
|
from pydantic import BaseModel, Field |
|
from typing import Optional, List |
|
from openai import OpenAI |
|
import pandas as pd |
|
|
|
|
|
class SummaryTweet(BaseModel): |
|
content: str = Field(..., description="A concise version of the abstract in tweet format. No Hastags") |
|
|
|
class AnnounceTweet(BaseModel): |
|
content: str = Field(..., description="A tweet announcing a new article. Text must include the author and title. No Hastags") |
|
|
|
class InsightTweet(BaseModel): |
|
content: str = Field(..., description="Simple, understandable statement distilling a complex social science concept. No Hastags") |
|
|
|
class ThreadTweet(BaseModel): |
|
content: List[str] = Field(default=[], description="A list of tweets that together form a thread about the article, summarizing its key points and implications, engaging the audience, and encouraging further discussion or reading. No hashtags.") |
|
|
|
class GenerateTweets(BaseModel): |
|
summary_tweets: List[SummaryTweet] = Field(default=[], description="A list of SummaryTweet instances.") |
|
insight_tweets: List[InsightTweet] = Field(default=[], description="A list of InsightTweet instances.") |
|
announce_tweets: List[AnnounceTweet] = Field(default=[], description="A list of AnnounceTweet instances.") |
|
|
|
def get_api_key(input_password): |
|
|
|
correct_password = os.environ.get("password") |
|
api_key = os.environ.get("openai_key") |
|
|
|
if input_password == correct_password: |
|
return api_key |
|
else: |
|
return "Incorrect password." |
|
|
|
|
|
|
|
def write_tweets(input_password, abstract_input): |
|
|
|
api_key_input = get_api_key(input_password) |
|
if api_key_input == "Incorrect password.": |
|
return 'Incorrect password.' |
|
|
|
client = OpenAI( |
|
max_retries=3, |
|
api_key=api_key_input, |
|
timeout=90.0, |
|
) |
|
|
|
|
|
messages = [ |
|
{ |
|
"role": "system", |
|
"content": ''' You write a variety of different types of social media posts about sociology articles. |
|
If you perform well, everyone gets a raise, while there are negative consequences if the posts don't get views. |
|
NEVER USE HASHTAGS. |
|
''', |
|
}, |
|
{ |
|
"role": "user", |
|
"content": f"""Generate five different tweets of each style about this sociology article: |
|
|
|
|
|
{abstract_input} |
|
|
|
""", |
|
}, |
|
] |
|
|
|
completion = client.chat.completions.create( |
|
model = 'gpt-4o', |
|
functions=[ |
|
{ |
|
"name": "generate_tweets", |
|
"description": "Create multiple social media posts, including a tweet thread, based on an article abstract.", |
|
"parameters": GenerateTweets.model_json_schema(), |
|
}, |
|
], |
|
n=1, |
|
messages=messages, |
|
) |
|
r = json.loads(completion.choices[0].message.function_call.arguments) |
|
tweets = [{'type': tweet_type.split('_')[0], 'text': t['content']} for tweet_type in r for t in r[tweet_type]] |
|
df = pd.DataFrame(tweets) |
|
grouped = df.groupby('type')['text'].apply(list).reset_index() |
|
markdown = "" |
|
for _, row in grouped.iterrows(): |
|
markdown += f"- **{row['type']}**\n" |
|
for text in row['text']: |
|
markdown += f" - {text}\n" |
|
return markdown |
|
|
|
|
|
|
|
with gr.Blocks() as app: |
|
gr.Markdown("### Social Media Post Generator") |
|
api_key_input = gr.Textbox(label="Password", placeholder="Enter the super secret password") |
|
abstract_input = gr.Textbox(label="Article Abstract", placeholder="Enter the article abstract here") |
|
generate_button = gr.Button("Generate Tweets") |
|
output_markdown = gr.Markdown() |
|
|
|
generate_button.click(fn=write_tweets, inputs=[api_key_input, abstract_input], outputs=output_markdown) |
|
|
|
app.launch() |