Ozgur Unlu
commited on
Commit
•
a8e55be
1
Parent(s):
7ae0911
moved to a simpler generator, changed UI by adding a prefill button
Browse files
app.py
CHANGED
@@ -6,154 +6,25 @@ from datetime import datetime, timedelta
|
|
6 |
import requests
|
7 |
from bs4 import BeautifulSoup
|
8 |
|
9 |
-
#
|
10 |
-
|
11 |
-
nltk.data.find('tokenizers/punkt')
|
12 |
-
except LookupError:
|
13 |
-
nltk.download('punkt')
|
14 |
|
15 |
-
# Initialize models and tokenizers
|
16 |
-
def load_models():
|
17 |
-
try:
|
18 |
-
# Text generation model
|
19 |
-
generator_model = "facebook/opt-350m"
|
20 |
-
generator_tokenizer = AutoTokenizer.from_pretrained(generator_model)
|
21 |
-
generator = AutoModelForCausalLM.from_pretrained(generator_model)
|
22 |
-
|
23 |
-
# Sentiment analysis
|
24 |
-
sentiment_analyzer = pipeline(
|
25 |
-
"sentiment-analysis",
|
26 |
-
model="finiteautomata/bertweet-base-sentiment-analysis"
|
27 |
-
)
|
28 |
-
|
29 |
-
# Content safety checker
|
30 |
-
content_checker = pipeline(
|
31 |
-
"text-classification",
|
32 |
-
model="facebook/roberta-hate-speech-dynabench-r4-target"
|
33 |
-
)
|
34 |
-
|
35 |
-
return generator_tokenizer, generator, sentiment_analyzer, content_checker
|
36 |
-
except Exception as e:
|
37 |
-
print(f"Error loading models: {str(e)}")
|
38 |
-
raise
|
39 |
-
|
40 |
-
# Simplified news fetching function
|
41 |
-
def fetch_recent_news(query, num_articles=3):
|
42 |
-
base_url = "https://news.google.com/rss/search"
|
43 |
-
params = {
|
44 |
-
'q': query,
|
45 |
-
'hl': 'en-US',
|
46 |
-
'gl': 'US',
|
47 |
-
'ceid': 'US:en'
|
48 |
-
}
|
49 |
-
|
50 |
-
try:
|
51 |
-
response = requests.get(base_url, params=params, timeout=5)
|
52 |
-
soup = BeautifulSoup(response.content, 'xml')
|
53 |
-
items = soup.find_all('item', limit=num_articles)
|
54 |
-
|
55 |
-
news_data = []
|
56 |
-
for item in items:
|
57 |
-
try:
|
58 |
-
news_data.append({
|
59 |
-
'title': item.title.text,
|
60 |
-
'description': item.description.text if item.description else ""
|
61 |
-
})
|
62 |
-
except:
|
63 |
-
continue
|
64 |
-
|
65 |
-
return news_data
|
66 |
-
except Exception as e:
|
67 |
-
return [{'title': f'Using default context due to error: {str(e)}', 'description': ''}]
|
68 |
-
|
69 |
-
# Generate content with ethical oversight
|
70 |
-
def generate_content(
|
71 |
-
product_name,
|
72 |
-
product_description,
|
73 |
-
target_audience,
|
74 |
-
key_features,
|
75 |
-
unique_benefits,
|
76 |
-
platform,
|
77 |
-
tone,
|
78 |
-
generator_tokenizer,
|
79 |
-
generator,
|
80 |
-
sentiment_analyzer,
|
81 |
-
content_checker
|
82 |
-
):
|
83 |
-
# Format prompt based on platform
|
84 |
-
char_limit = 280 if platform == "Twitter" else 500
|
85 |
-
|
86 |
-
# Get recent news for context
|
87 |
-
news_data = fetch_recent_news(f"{product_name} {target_audience}")
|
88 |
-
news_context = "\n".join([f"Recent context: {item['title']}" for item in news_data])
|
89 |
-
|
90 |
-
# Create prompt
|
91 |
-
prompt = f"""
|
92 |
-
Create a {platform} post with these requirements:
|
93 |
-
- Product Name: {product_name}
|
94 |
-
- Description: {product_description}
|
95 |
-
- Target Audience: {target_audience}
|
96 |
-
- Key Features: {key_features}
|
97 |
-
- Unique Benefits: {unique_benefits}
|
98 |
-
- Tone: {tone}
|
99 |
-
- Maximum Length: {char_limit} characters
|
100 |
-
|
101 |
-
Recent Market Context:
|
102 |
-
{news_context}
|
103 |
-
|
104 |
-
Generate a compelling {platform} post that highlights the product's benefits while maintaining a {tone} tone.
|
105 |
-
"""
|
106 |
-
|
107 |
-
try:
|
108 |
-
# Generate initial content
|
109 |
-
inputs = generator_tokenizer(prompt, return_tensors="pt", max_length=512, truncation=True)
|
110 |
-
outputs = generator.generate(
|
111 |
-
inputs["input_ids"],
|
112 |
-
max_length=char_limit + len(prompt),
|
113 |
-
num_return_sequences=3,
|
114 |
-
temperature=0.7,
|
115 |
-
top_p=0.9,
|
116 |
-
do_sample=True,
|
117 |
-
)
|
118 |
-
|
119 |
-
generated_texts = [generator_tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
|
120 |
-
|
121 |
-
# Filter and analyze content
|
122 |
-
filtered_content = []
|
123 |
-
for text in generated_texts:
|
124 |
-
# Clean up text by removing the prompt
|
125 |
-
text = text.replace(prompt, "").strip()
|
126 |
-
|
127 |
-
# Skip if text is too short or too long
|
128 |
-
if len(text) < 10 or len(text) > char_limit:
|
129 |
-
continue
|
130 |
-
|
131 |
-
# Check sentiment
|
132 |
-
sentiment = sentiment_analyzer(text)[0]
|
133 |
-
|
134 |
-
# Check content safety
|
135 |
-
safety_check = content_checker(text)[0]
|
136 |
-
|
137 |
-
# Filter based on ethical considerations
|
138 |
-
if (
|
139 |
-
sentiment['label'] != 'negative' and
|
140 |
-
safety_check['label'] == 'not_hate' and
|
141 |
-
len(text) <= char_limit
|
142 |
-
):
|
143 |
-
filtered_content.append({
|
144 |
-
'text': text,
|
145 |
-
'sentiment': sentiment['label'],
|
146 |
-
'safety_score': f"{float(safety_check['score']):.2f}"
|
147 |
-
})
|
148 |
-
|
149 |
-
return filtered_content
|
150 |
-
except Exception as e:
|
151 |
-
print(f"Error generating content: {str(e)}")
|
152 |
-
return []
|
153 |
-
|
154 |
-
# Gradio interface
|
155 |
def create_interface():
|
|
|
156 |
generator_tokenizer, generator, sentiment_analyzer, content_checker = load_models()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
|
158 |
def process_input(
|
159 |
product_name,
|
@@ -179,40 +50,51 @@ def create_interface():
|
|
179 |
content_checker
|
180 |
)
|
181 |
|
182 |
-
|
183 |
-
return "No suitable content generated. Please try again with different parameters."
|
184 |
-
|
185 |
-
output = ""
|
186 |
for i, content in enumerate(results, 1):
|
187 |
-
output += f"
|
188 |
-
output += f"Content: {content['text']}\n"
|
189 |
-
output += f"Sentiment: {content['sentiment']}\n"
|
190 |
-
output += f"Safety Score: {content['safety_score']}\n"
|
191 |
output += "-" * 50 + "\n"
|
192 |
|
193 |
return output
|
194 |
except Exception as e:
|
195 |
return f"An error occurred: {str(e)}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
|
197 |
-
#
|
|
|
|
|
|
|
198 |
iface = gr.Interface(
|
199 |
fn=process_input,
|
200 |
inputs=[
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
label="Platform",
|
209 |
-
value="Twitter"
|
210 |
-
),
|
211 |
-
gr.Textbox(label="Tone", placeholder="e.g., professional, casual, friendly"),
|
212 |
],
|
213 |
-
outputs=
|
214 |
title="Ethimar - AI Marketing Content Generator",
|
215 |
-
description="Generate ethical marketing content with AI-powered insights
|
|
|
|
|
216 |
theme="default",
|
217 |
examples=[
|
218 |
[
|
@@ -226,7 +108,29 @@ def create_interface():
|
|
226 |
]
|
227 |
]
|
228 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
return iface
|
231 |
|
232 |
# Launch the app
|
|
|
6 |
import requests
|
7 |
from bs4 import BeautifulSoup
|
8 |
|
9 |
+
# Previous imports and model loading code remains the same...
|
10 |
+
# (Keep all the previous code until the create_interface function)
|
|
|
|
|
|
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
def create_interface():
|
13 |
+
print("Loading models...")
|
14 |
generator_tokenizer, generator, sentiment_analyzer, content_checker = load_models()
|
15 |
+
print("Models loaded successfully!")
|
16 |
+
|
17 |
+
# Sample data function
|
18 |
+
def fill_sample_data():
|
19 |
+
return [
|
20 |
+
"EcoBottle", # Product Name
|
21 |
+
"Sustainable water bottle made from recycled ocean plastic", # Product Description
|
22 |
+
"Environmentally conscious young professionals", # Target Audience
|
23 |
+
"100% recycled materials, Insulated design, Leak-proof", # Key Features
|
24 |
+
"Helps clean oceans, Keeps drinks cold for 24 hours", # Unique Benefits
|
25 |
+
"Twitter", # Platform
|
26 |
+
"professional" # Tone
|
27 |
+
]
|
28 |
|
29 |
def process_input(
|
30 |
product_name,
|
|
|
50 |
content_checker
|
51 |
)
|
52 |
|
53 |
+
output = "🎯 Generated Marketing Content:\n\n"
|
|
|
|
|
|
|
54 |
for i, content in enumerate(results, 1):
|
55 |
+
output += f"Version {i}:\n"
|
56 |
+
output += f"📝 Content: {content['text']}\n"
|
57 |
+
output += f"😊 Sentiment: {content['sentiment']}\n"
|
58 |
+
output += f"✅ Safety Score: {content['safety_score']}\n"
|
59 |
output += "-" * 50 + "\n"
|
60 |
|
61 |
return output
|
62 |
except Exception as e:
|
63 |
return f"An error occurred: {str(e)}"
|
64 |
+
|
65 |
+
# Create input components
|
66 |
+
product_name = gr.Textbox(label="Product Name", placeholder="Enter product name")
|
67 |
+
product_description = gr.Textbox(label="Product Description", lines=3, placeholder="Brief description of your product")
|
68 |
+
target_audience = gr.Textbox(label="Target Audience", placeholder="Who is this product for?")
|
69 |
+
key_features = gr.Textbox(label="Key Features", lines=2, placeholder="Main features of your product")
|
70 |
+
unique_benefits = gr.Textbox(label="Unique Benefits", lines=2, placeholder="What makes your product special?")
|
71 |
+
platform = gr.Radio(
|
72 |
+
choices=["Twitter", "Instagram"],
|
73 |
+
label="Platform",
|
74 |
+
value="Twitter"
|
75 |
+
)
|
76 |
+
tone = gr.Textbox(label="Tone", placeholder="e.g., professional, casual, friendly")
|
77 |
|
78 |
+
# Output component
|
79 |
+
output = gr.Textbox(label="Generated Content", lines=10)
|
80 |
+
|
81 |
+
# Create the interface with custom layout
|
82 |
iface = gr.Interface(
|
83 |
fn=process_input,
|
84 |
inputs=[
|
85 |
+
product_name,
|
86 |
+
product_description,
|
87 |
+
target_audience,
|
88 |
+
key_features,
|
89 |
+
unique_benefits,
|
90 |
+
platform,
|
91 |
+
tone
|
|
|
|
|
|
|
|
|
92 |
],
|
93 |
+
outputs=output,
|
94 |
title="Ethimar - AI Marketing Content Generator",
|
95 |
+
description="""Generate ethical marketing content with AI-powered insights.
|
96 |
+
⏳ Note: First generation might take 3-5 minutes due to model loading.
|
97 |
+
Subsequent generations will be faster!""",
|
98 |
theme="default",
|
99 |
examples=[
|
100 |
[
|
|
|
108 |
]
|
109 |
]
|
110 |
)
|
111 |
+
|
112 |
+
# Add the sample data button with custom styling
|
113 |
+
fill_button = gr.Button(
|
114 |
+
"Fill the form with sample data",
|
115 |
+
variant="primary",
|
116 |
+
scale=1,
|
117 |
+
size="sm"
|
118 |
+
)
|
119 |
|
120 |
+
# Connect the button to the fill_sample_data function
|
121 |
+
fill_button.click(
|
122 |
+
fn=fill_sample_data,
|
123 |
+
outputs=[
|
124 |
+
product_name,
|
125 |
+
product_description,
|
126 |
+
target_audience,
|
127 |
+
key_features,
|
128 |
+
unique_benefits,
|
129 |
+
platform,
|
130 |
+
tone
|
131 |
+
]
|
132 |
+
)
|
133 |
+
|
134 |
return iface
|
135 |
|
136 |
# Launch the app
|