Spaces:
Running
Running
COMPLETE REWRITE: Remove session state dependency for HF Spaces compatibility
Browse files
app.py
CHANGED
@@ -14,12 +14,6 @@ st.set_page_config(
|
|
14 |
layout="wide"
|
15 |
)
|
16 |
|
17 |
-
# Initialize session state FIRST - before any other code
|
18 |
-
if 'processed_data' not in st.session_state:
|
19 |
-
st.session_state.processed_data = None
|
20 |
-
if 'email_generator' not in st.session_state:
|
21 |
-
st.session_state.email_generator = None
|
22 |
-
|
23 |
def init_database():
|
24 |
"""Initialize SQLite database for caching"""
|
25 |
conn = sqlite3.connect('leads.db')
|
@@ -57,18 +51,15 @@ def init_database():
|
|
57 |
conn.commit()
|
58 |
conn.close()
|
59 |
|
|
|
60 |
def load_email_generator():
|
61 |
"""Load the email generator with caching"""
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
st.error(f"β Failed to load AI model: {str(e)}")
|
69 |
-
st.info("π‘ The model will be downloaded automatically on first run. Please ensure you have a stable internet connection.")
|
70 |
-
return None
|
71 |
-
return st.session_state.email_generator
|
72 |
|
73 |
def process_csv_data(df, tone, creativity, num_variations):
|
74 |
"""Process CSV data and generate emails"""
|
@@ -186,25 +177,17 @@ def display_results(results, tone, creativity):
|
|
186 |
|
187 |
# Subject line
|
188 |
st.write("**Subject:**")
|
189 |
-
|
190 |
-
with subject_container:
|
191 |
-
st.code(best['subject_line'], language=None)
|
192 |
-
if st.button(f"π Copy Subject", key=f"copy_subject_{idx}"):
|
193 |
-
st.success("Subject copied to clipboard!")
|
194 |
|
195 |
# Email body
|
196 |
st.write("**Email Body:**")
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
label_visibility="collapsed"
|
205 |
-
)
|
206 |
-
if st.button(f"π Copy Email", key=f"copy_email_{idx}"):
|
207 |
-
st.success("Email copied to clipboard!")
|
208 |
|
209 |
with col3:
|
210 |
st.write("**π― Generation Settings:**")
|
@@ -221,10 +204,7 @@ def display_results(results, tone, creativity):
|
|
221 |
st.write(f"**π Variations ({len(result['variations'])}):**")
|
222 |
for i, var in enumerate(result['variations']):
|
223 |
quality_color = "π" if var['quality_score'] >= 8 else "β‘" if var['quality_score'] >= 6 else "β οΈ"
|
224 |
-
|
225 |
-
# Show this variation
|
226 |
-
st.info(f"**Subject:** {var['subject_line']}")
|
227 |
-
st.text_area("Body", var['email_body'], height=200, key=f"var_body_{idx}_{i}")
|
228 |
|
229 |
def export_to_csv(results):
|
230 |
"""Export results to CSV format"""
|
@@ -292,10 +272,6 @@ def main():
|
|
292 |
# Model info
|
293 |
st.subheader("π€ AI Model")
|
294 |
st.info("**Vicuna-7B GGUF**\n\nOptimized for quality cold email generation")
|
295 |
-
|
296 |
-
if st.button("π Reload Model"):
|
297 |
-
st.session_state.email_generator = None
|
298 |
-
st.experimental_rerun()
|
299 |
|
300 |
# File upload
|
301 |
st.subheader("π Upload Your Lead List")
|
@@ -328,6 +304,9 @@ def main():
|
|
328 |
"text/csv"
|
329 |
)
|
330 |
|
|
|
|
|
|
|
331 |
if uploaded_file is not None:
|
332 |
try:
|
333 |
# Load and validate CSV
|
@@ -375,8 +354,28 @@ def main():
|
|
375 |
results = process_csv_data(df, tone, creativity, num_variations)
|
376 |
|
377 |
if results:
|
378 |
-
st.session_state.processed_data = results
|
379 |
st.success("β
Email generation complete!")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
380 |
else:
|
381 |
st.error("β Failed to process leads. Please try again.")
|
382 |
|
@@ -384,28 +383,6 @@ def main():
|
|
384 |
st.error(f"β Error reading CSV file: {str(e)}")
|
385 |
st.info("Please ensure your CSV file has the correct format and encoding.")
|
386 |
|
387 |
-
# Display results if available - This is where the error was happening
|
388 |
-
if st.session_state.processed_data is not None:
|
389 |
-
st.markdown("---")
|
390 |
-
display_results(st.session_state.processed_data, tone, creativity)
|
391 |
-
|
392 |
-
# Export functionality
|
393 |
-
st.markdown("---")
|
394 |
-
st.subheader("π€ Export Results")
|
395 |
-
|
396 |
-
export_df = export_to_csv(st.session_state.processed_data)
|
397 |
-
if export_df is not None:
|
398 |
-
csv = export_df.to_csv(index=False)
|
399 |
-
st.download_button(
|
400 |
-
"π₯ Download Results as CSV",
|
401 |
-
csv,
|
402 |
-
f"cold_emails_export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
|
403 |
-
"text/csv",
|
404 |
-
help="Download all generated emails in CSV format"
|
405 |
-
)
|
406 |
-
|
407 |
-
st.info(f"π Ready to export {len(export_df)} successful email generations")
|
408 |
-
|
409 |
# Footer
|
410 |
st.markdown("---")
|
411 |
st.markdown(
|
|
|
14 |
layout="wide"
|
15 |
)
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
def init_database():
|
18 |
"""Initialize SQLite database for caching"""
|
19 |
conn = sqlite3.connect('leads.db')
|
|
|
51 |
conn.commit()
|
52 |
conn.close()
|
53 |
|
54 |
+
@st.cache_resource
|
55 |
def load_email_generator():
|
56 |
"""Load the email generator with caching"""
|
57 |
+
try:
|
58 |
+
return EmailGenerator()
|
59 |
+
except Exception as e:
|
60 |
+
st.error(f"β Failed to load AI model: {str(e)}")
|
61 |
+
st.info("π‘ The model will be downloaded automatically on first run. Please ensure you have a stable internet connection.")
|
62 |
+
return None
|
|
|
|
|
|
|
|
|
63 |
|
64 |
def process_csv_data(df, tone, creativity, num_variations):
|
65 |
"""Process CSV data and generate emails"""
|
|
|
177 |
|
178 |
# Subject line
|
179 |
st.write("**Subject:**")
|
180 |
+
st.code(best['subject_line'], language=None)
|
|
|
|
|
|
|
|
|
181 |
|
182 |
# Email body
|
183 |
st.write("**Email Body:**")
|
184 |
+
st.text_area(
|
185 |
+
"Email Content",
|
186 |
+
best['email_body'],
|
187 |
+
height=300,
|
188 |
+
key=f"email_body_{idx}",
|
189 |
+
label_visibility="collapsed"
|
190 |
+
)
|
|
|
|
|
|
|
|
|
191 |
|
192 |
with col3:
|
193 |
st.write("**π― Generation Settings:**")
|
|
|
204 |
st.write(f"**π Variations ({len(result['variations'])}):**")
|
205 |
for i, var in enumerate(result['variations']):
|
206 |
quality_color = "π" if var['quality_score'] >= 8 else "β‘" if var['quality_score'] >= 6 else "β οΈ"
|
207 |
+
st.write(f"{quality_color} Variation {i+1}: {var['quality_score']:.1f}/10")
|
|
|
|
|
|
|
208 |
|
209 |
def export_to_csv(results):
|
210 |
"""Export results to CSV format"""
|
|
|
272 |
# Model info
|
273 |
st.subheader("π€ AI Model")
|
274 |
st.info("**Vicuna-7B GGUF**\n\nOptimized for quality cold email generation")
|
|
|
|
|
|
|
|
|
275 |
|
276 |
# File upload
|
277 |
st.subheader("π Upload Your Lead List")
|
|
|
304 |
"text/csv"
|
305 |
)
|
306 |
|
307 |
+
# Initialize results variable
|
308 |
+
results = None
|
309 |
+
|
310 |
if uploaded_file is not None:
|
311 |
try:
|
312 |
# Load and validate CSV
|
|
|
354 |
results = process_csv_data(df, tone, creativity, num_variations)
|
355 |
|
356 |
if results:
|
|
|
357 |
st.success("β
Email generation complete!")
|
358 |
+
|
359 |
+
# Display results immediately
|
360 |
+
st.markdown("---")
|
361 |
+
display_results(results, tone, creativity)
|
362 |
+
|
363 |
+
# Export functionality
|
364 |
+
st.markdown("---")
|
365 |
+
st.subheader("π€ Export Results")
|
366 |
+
|
367 |
+
export_df = export_to_csv(results)
|
368 |
+
if export_df is not None:
|
369 |
+
csv = export_df.to_csv(index=False)
|
370 |
+
st.download_button(
|
371 |
+
"π₯ Download Results as CSV",
|
372 |
+
csv,
|
373 |
+
f"cold_emails_export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
|
374 |
+
"text/csv",
|
375 |
+
help="Download all generated emails in CSV format"
|
376 |
+
)
|
377 |
+
|
378 |
+
st.info(f"π Ready to export {len(export_df)} successful email generations")
|
379 |
else:
|
380 |
st.error("β Failed to process leads. Please try again.")
|
381 |
|
|
|
383 |
st.error(f"β Error reading CSV file: {str(e)}")
|
384 |
st.info("Please ensure your CSV file has the correct format and encoding.")
|
385 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
386 |
# Footer
|
387 |
st.markdown("---")
|
388 |
st.markdown(
|