Update app.py
Browse files
app.py
CHANGED
@@ -1,89 +1,97 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
import html2text
|
3 |
-
import google.generativeai as genai
|
4 |
-
import os
|
5 |
-
|
6 |
-
# Prompt template builder
|
7 |
-
def build_prompt(content, platform, styles, emotions):
|
8 |
-
style_text = ", ".join(styles) if styles else "humanized"
|
9 |
-
emotion_text = ", ".join(emotions) if emotions else "genuine"
|
10 |
-
|
11 |
-
return f"""
|
12 |
-
You are a fermentation enthusiast who has real-world experience.
|
13 |
-
Take the following HTML content, summarize it, and turn it into a highly engaging {platform} post.
|
14 |
-
The tone must feel like it’s written by a human—not AI. Be expressive, imperfect, casual, and honest.
|
15 |
-
Use styles like {style_text}, and include emotional tones like {emotion_text}.
|
16 |
-
Sound like you're sharing a personal story or tip—not giving a lecture.
|
17 |
-
|
18 |
-
Output structure:
|
19 |
-
1. Title (1 sentence, catchy, personal)
|
20 |
-
2. Post body: 2–4 paragraphs, casual tone, share what worked/didn’t, and end with a relatable or curious question.
|
21 |
-
|
22 |
-
CONTENT TO CONVERT:
|
23 |
-
\"\"\"{content}\"\"\"
|
24 |
-
"""
|
25 |
-
|
26 |
-
# Function to handle post generation
|
27 |
-
def generate_post(api_key, file, platform, styles, emotions):
|
28 |
-
if not api_key:
|
29 |
-
return "Please enter your Gemini API key first."
|
30 |
-
if not file:
|
31 |
-
return "Please upload a file."
|
32 |
-
|
33 |
-
try:
|
34 |
-
genai.configure(api_key=api_key)
|
35 |
-
model = genai.GenerativeModel("gemini-pro")
|
36 |
-
|
37 |
-
raw_html = file.read().decode("utf-8")
|
38 |
-
plain_text = html2text.html2text(raw_html)
|
39 |
-
prompt = build_prompt(plain_text, platform, styles, emotions)
|
40 |
-
|
41 |
-
response = model.generate_content(prompt)
|
42 |
-
return response.text
|
43 |
-
|
44 |
-
except Exception as e:
|
45 |
-
return f"Error: {e}"
|
46 |
-
|
47 |
-
# Download handlers
|
48 |
-
def download_outputs(content):
|
49 |
-
html_path = "/tmp/post_output.html"
|
50 |
-
txt_path = "/tmp/post_output.txt"
|
51 |
-
with open(html_path, "w") as f:
|
52 |
-
f.write(content)
|
53 |
-
with open(txt_path, "w") as f:
|
54 |
-
f.write(content)
|
55 |
-
return html_path, txt_path
|
56 |
-
|
57 |
-
# Gradio App
|
58 |
-
with gr.Blocks(title="Reddit/Quora Post Generator") as demo:
|
59 |
-
gr.Markdown("## 🔥 Turn your SEO-rich HTML content into humanized Reddit or Quora posts")
|
60 |
-
|
61 |
-
api_key = gr.Textbox(label="🔐 Gemini API Key", type="password", placeholder="Paste your Gemini API key")
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
with gr.Row():
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
["Curious", "Enthusiastic", "Skeptical", "Inspiring"],
|
75 |
-
label="Emotional Tone",
|
76 |
-
value=["Curious"]
|
77 |
-
)
|
78 |
-
|
79 |
-
generate_btn = gr.Button("✨ Generate Post")
|
80 |
-
output = gr.Textbox(label="Generated Post", lines=15)
|
81 |
|
82 |
with gr.Row():
|
83 |
-
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
85 |
|
86 |
-
generate_btn.click(
|
87 |
-
|
|
|
88 |
|
89 |
demo.launch()
|
|
|
|
|
|
1 |
+
import gradio as gr import html2text import google.generativeai as genai
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
+
Insert your Gemini API key manually
|
4 |
+
|
5 |
+
GEMINI_API_KEY = "your-gemini-api-key-here" genai.configure(api_key=GEMINI_API_KEY)
|
6 |
+
|
7 |
+
model = genai.GenerativeModel("gemini-1.5-pro-latest")
|
8 |
+
|
9 |
+
Example HTML input (for demo/testing)
|
10 |
+
|
11 |
+
EXAMPLE_HTML = """
|
12 |
+
|
13 |
+
<html>
|
14 |
+
<head><title>How I Brew Kombucha at Home</title></head>
|
15 |
+
<body>
|
16 |
+
<h1>How I Brew Kombucha at Home</h1>
|
17 |
+
<p>Brewing kombucha at home has changed my wellness journey. I start with black tea and sugar, let it cool, and then introduce the SCOBY. After 7 days, I bottle it with fresh ginger or berries for a second ferment. It's fizzy, healthy, and deeply satisfying.</p>
|
18 |
+
<h2>Ingredients</h2>
|
19 |
+
<ul>
|
20 |
+
<li>1 SCOBY</li>
|
21 |
+
<li>1 cup sugar</li>
|
22 |
+
<li>8 cups filtered water</li>
|
23 |
+
<li>4 bags black tea</li>
|
24 |
+
</ul>
|
25 |
+
</body>
|
26 |
+
</html>
|
27 |
+
"""Humanized prompt builder
|
28 |
+
|
29 |
+
def build_prompt(html_content, platform, styles, emotions): markdown = html2text.html2text(html_content) prompt = f""" You are an expert copywriter and SEO specialist writing for a Reddit or Quora audience. Rewrite the following content into a post that feels genuinely human and experience-based.
|
30 |
+
|
31 |
+
Platform: {platform}
|
32 |
+
|
33 |
+
Writing style: {', '.join(styles)}
|
34 |
+
|
35 |
+
Emotional tone: {', '.join(emotions)}
|
36 |
+
|
37 |
+
Format as a personal story or real experience, not as polished marketing copy.
|
38 |
+
|
39 |
+
Include imperfections, uncertainty, and real-life observations when possible.
|
40 |
+
|
41 |
+
Use natural language and conversational tone. Avoid generic AI-sounding phrases.
|
42 |
+
|
43 |
+
Add light humor, personal opinions, and authentic transitions.
|
44 |
+
|
45 |
+
End with a relatable thought or casual call to action (like "What do you think?" or "Curious if anyone else has tried this?").
|
46 |
+
|
47 |
+
Summarize where needed but preserve the heart of the experience.
|
48 |
+
|
49 |
+
Output: A suggested title + post body. No tags, no metadata.
|
50 |
+
|
51 |
+
|
52 |
+
Content: """ prompt += markdown return prompt
|
53 |
+
|
54 |
+
Generator function
|
55 |
+
|
56 |
+
def generate_post(file, platform, styles, emotions): if file is None: return "Please upload an HTML file."
|
57 |
+
|
58 |
+
content = file.read().decode("utf-8")
|
59 |
+
prompt = build_prompt(content, platform, styles, emotions)
|
60 |
+
response = model.generate_content(prompt)
|
61 |
+
return response.text
|
62 |
+
|
63 |
+
Download helper
|
64 |
+
|
65 |
+
def save_file(text, file_type): ext = ".html" if file_type == "HTML" else ".txt" return (text, f"generated_post{ext}")
|
66 |
+
|
67 |
+
Gradio UI
|
68 |
+
|
69 |
+
def launch_app(): with gr.Blocks(title="Reddit/Quora Post Generator") as demo: gr.Markdown("# Reddit/Quora Post Generator\nGenerate engaging posts based on SEO HTML content.")
|
70 |
+
|
71 |
+
with gr.Row():
|
72 |
+
file_input = gr.File(label="Upload your HTML file")
|
73 |
|
74 |
with gr.Row():
|
75 |
+
platform = gr.CheckboxGroup(["Reddit", "Quora"], label="Choose platform (one only)", value=["Reddit"])
|
76 |
+
style = gr.CheckboxGroup(["Friendly", "Humanized", "Personal/Storytelling"], label="Choose writing style")
|
77 |
+
emotions = gr.CheckboxGroup(["Curious", "Enthusiastic", "Skeptical", "Inspiring"], label="Emotional Tone")
|
78 |
+
|
79 |
+
generate_btn = gr.Button("Generate Post")
|
80 |
+
output_text = gr.Textbox(label="Generated Post", lines=15)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
|
82 |
with gr.Row():
|
83 |
+
download_format = gr.Radio(["Text", "HTML"], value="Text", label="Download Format")
|
84 |
+
download_btn = gr.DownloadButton("Download", label="Download Post")
|
85 |
+
|
86 |
+
def generate_and_return(file, platform, style, emotions, file_type):
|
87 |
+
platform_selected = platform[0] if platform else "Reddit"
|
88 |
+
result = generate_post(file, platform_selected, style, emotions)
|
89 |
+
return result, save_file(result, file_type)
|
90 |
|
91 |
+
generate_btn.click(generate_and_return,
|
92 |
+
inputs=[file_input, platform, style, emotions, download_format],
|
93 |
+
outputs=[output_text, download_btn])
|
94 |
|
95 |
demo.launch()
|
96 |
+
|
97 |
+
launch_app()
|