Update app.py
Browse files
app.py
CHANGED
@@ -1,47 +1,114 @@
|
|
1 |
import streamlit as st
|
2 |
-
import
|
3 |
from tenacity import retry, stop_after_attempt, wait_fixed
|
|
|
4 |
|
5 |
-
#
|
6 |
-
|
7 |
|
8 |
-
# Retry decorator to handle potential API call failures
|
9 |
@retry(stop=stop_after_attempt(3), wait=wait_fixed(1))
|
10 |
def call_openai_api(messages):
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
13 |
messages=messages,
|
14 |
-
max_tokens=
|
15 |
-
|
16 |
-
stop=None
|
17 |
)
|
18 |
|
19 |
def generate_video_hooks(script):
|
|
|
|
|
|
|
20 |
messages = [{
|
21 |
-
"role": "system",
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
}, {
|
29 |
-
"role": "user",
|
|
|
30 |
}]
|
|
|
31 |
response = call_openai_api(messages)
|
32 |
-
return response.choices[0].message
|
33 |
|
34 |
-
# Streamlit
|
35 |
-
st.
|
36 |
|
37 |
-
#
|
38 |
-
|
|
|
|
|
|
|
39 |
|
40 |
-
#
|
41 |
-
|
42 |
-
|
43 |
-
hooks = generate_video_hooks(user_input)
|
44 |
-
st.markdown("### Generated Hooks")
|
45 |
-
st.write(hooks)
|
46 |
|
47 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
+
from openai import OpenAI
|
3 |
from tenacity import retry, stop_after_attempt, wait_fixed
|
4 |
+
import os
|
5 |
|
6 |
+
# Initialize OpenAI client
|
7 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
8 |
|
|
|
9 |
@retry(stop=stop_after_attempt(3), wait=wait_fixed(1))
|
10 |
def call_openai_api(messages):
|
11 |
+
"""
|
12 |
+
Make API call to OpenAI with retry logic for reliability.
|
13 |
+
"""
|
14 |
+
return client.chat.completions.create(
|
15 |
+
model="gpt-4",
|
16 |
messages=messages,
|
17 |
+
max_tokens=400,
|
18 |
+
temperature=0.9 # Higher creativity for hook generation
|
|
|
19 |
)
|
20 |
|
21 |
def generate_video_hooks(script):
|
22 |
+
"""
|
23 |
+
Generate compelling video hooks based on the provided script.
|
24 |
+
"""
|
25 |
messages = [{
|
26 |
+
"role": "system",
|
27 |
+
"content": """You are an expert at creating viral video hooks for real estate content.
|
28 |
+
Your specialty is writing opening lines that stop scrollers and make viewers watch the entire video.
|
29 |
+
|
30 |
+
Your hooks should:
|
31 |
+
- Be 15 words or less (can be 2 short sentences if needed)
|
32 |
+
- Create immediate curiosity or urgency
|
33 |
+
- Use power words that grab attention
|
34 |
+
- Avoid generic openings like "Hey guys" or "In today's video"
|
35 |
+
- Be specific and intriguing
|
36 |
+
- Make viewers think "I need to know this"
|
37 |
+
|
38 |
+
Generate exactly 10 different hook options that are each unique in style:
|
39 |
+
- Question hooks that create curiosity
|
40 |
+
- Shocking statement hooks
|
41 |
+
- "What if" scenario hooks
|
42 |
+
- Contrarian/surprising hooks
|
43 |
+
- Fear-based urgency hooks
|
44 |
+
- Benefit-focused hooks
|
45 |
+
- Story teaser hooks
|
46 |
+
- Number/list hooks
|
47 |
+
- Problem-focused hooks
|
48 |
+
- Secret/insider knowledge hooks
|
49 |
+
|
50 |
+
Format your response as a numbered list with each hook on its own line."""
|
51 |
}, {
|
52 |
+
"role": "user",
|
53 |
+
"content": f"Script: {script}"
|
54 |
}]
|
55 |
+
|
56 |
response = call_openai_api(messages)
|
57 |
+
return response.choices[0].message.content
|
58 |
|
59 |
+
# Streamlit setup
|
60 |
+
st.set_page_config(layout="wide", page_title="Video Hook Generator")
|
61 |
|
62 |
+
# Initialize session state
|
63 |
+
if "generated_hooks" not in st.session_state:
|
64 |
+
st.session_state["generated_hooks"] = None
|
65 |
+
if "show_notice" not in st.session_state:
|
66 |
+
st.session_state["show_notice"] = False
|
67 |
|
68 |
+
# Header
|
69 |
+
st.markdown("<h1 style='text-align: center; color: black;'>🎣 Video Hook Generator</h1>", unsafe_allow_html=True)
|
70 |
+
st.markdown("<p style='text-align: center; color: gray; font-size: 18px;'>Turn any script into scroll-stopping content</p>", unsafe_allow_html=True)
|
|
|
|
|
|
|
71 |
|
72 |
+
# Simple input section
|
73 |
+
st.markdown("<h2 style='text-align: center; color: black;'>Paste Your Script</h2>", unsafe_allow_html=True)
|
74 |
+
|
75 |
+
# Create a clean, centered input area
|
76 |
+
col1, col2, col3 = st.columns([1, 3, 1])
|
77 |
+
|
78 |
+
with col2:
|
79 |
+
user_script = st.text_area(
|
80 |
+
"",
|
81 |
+
placeholder="Paste your complete video script here...\n\nThe more detailed your script, the better hooks I can create for you.",
|
82 |
+
height=200
|
83 |
+
)
|
84 |
+
|
85 |
+
generate_button = st.button('🎯 Generate 10 Hooks', use_container_width=True)
|
86 |
+
|
87 |
+
# Process results
|
88 |
+
if generate_button and user_script.strip():
|
89 |
+
st.session_state["show_notice"] = True
|
90 |
+
|
91 |
+
with st.spinner("🎣 Creating irresistible hooks..."):
|
92 |
+
st.session_state["generated_hooks"] = generate_video_hooks(user_script)
|
93 |
+
st.session_state["show_notice"] = False
|
94 |
+
|
95 |
+
elif generate_button and not user_script.strip():
|
96 |
+
st.error("Please paste your script first!")
|
97 |
+
|
98 |
+
# Display waiting notice
|
99 |
+
if st.session_state["show_notice"]:
|
100 |
+
st.info("🎬 Analyzing your script and generating hooks... This will just take a moment!")
|
101 |
+
|
102 |
+
# Display results
|
103 |
+
if st.session_state["generated_hooks"]:
|
104 |
+
st.markdown("---")
|
105 |
+
st.markdown("<h2 style='text-align: center; color: black;'>🔥 Your Hook Options</h2>", unsafe_allow_html=True)
|
106 |
+
|
107 |
+
# Display hooks in a clean format
|
108 |
+
st.markdown("""
|
109 |
+
<div style='background-color: #f8f9fa; padding: 25px; border-radius: 10px; border-left: 4px solid #FF6B35; margin: 20px 0;'>
|
110 |
+
""", unsafe_allow_html=True)
|
111 |
+
|
112 |
+
st.markdown(st.session_state["generated_hooks"])
|
113 |
+
|
114 |
+
st.markdown("</div>", unsafe_allow_html=True)
|