HypePack / hype_pack /streamlit_app.py
LeoWalker's picture
Updated Arnold and Tony's speaker profiles along with updating to add Groq.
f6cf9cc
import streamlit as st
from hype_pack.utils.state import InterviewState, InitialInput
from hype_pack.utils.nodes import (
build_reference_material_node,
generate_questions_node,
generate_transcript_node,
run_text_to_speech_node,
speaker_voice_map
)
from hype_pack.utils.speaker_profiles import (
tony_robbins,
arnold_schwarzenegger,
simon_sinek,
speaker_voice_map
)
from pypdf import PdfReader
import tempfile
import os
import uuid
from dotenv import load_dotenv
load_dotenv()
# Configure Streamlit page
st.set_page_config(
page_title="HypeCast Generator",
page_icon="πŸŽ™οΈ",
layout="wide"
)
# Add speaker profiles dictionary after imports
speaker_profiles = {
"Tony Robbins": tony_robbins,
"Arnold Schwarzenegger": arnold_schwarzenegger,
"Simon Sinek": simon_sinek
}
def read_pdf(pdf_file):
"""Extract text from uploaded PDF file"""
reader = PdfReader(pdf_file)
text = ""
for page in reader.pages:
text += page.extract_text()
return text
def main():
# Initialize all session state variables
if 'stage' not in st.session_state:
st.session_state.stage = 'upload'
if 'selected_speaker' not in st.session_state:
st.session_state.selected_speaker = None
if 'interview_state' not in st.session_state:
st.session_state.interview_state = None
if 'generated_audio' not in st.session_state:
st.session_state.generated_audio = None
# Single header with description
st.markdown("""
<div style='text-align: center; padding: 1rem 0;'>
<h1 style='margin: 0; font-size: 2.5rem; color: #2F4F4F;'>
Let's Get You Hyped For Your Next Big Move! πŸš€
</h1>
<p style='color: #666; font-size: 1.1em; margin-top: 0.5rem;'>
Upload your profile and job description, then let our AI-powered motivational speakers create
a personalized hype speech just for you!
</p>
</div>
<hr style='margin: 1rem 0;'>
""", unsafe_allow_html=True)
if st.session_state.stage == 'upload':
# Centered speaker selection
st.markdown("<h3 style='text-align: center;'>Choose Your Hype Person</h3>", unsafe_allow_html=True)
# Create a wider central column for the radio buttons
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
# Add custom CSS to center the radio buttons
st.markdown(
"""
<style>
div.row-widget.stRadio > div {
flex-direction: row;
justify-content: center;
}
div.row-widget.stRadio > div[role="radiogroup"] > label {
margin: 0 10px; /* Add some spacing between buttons */
text-align: center;
}
</style>
""",
unsafe_allow_html=True
)
selected_speaker = st.radio(
"Select your motivational speaker",
options=["Tony Robbins πŸ”₯", "Arnold Schwarzenegger ⚑", "Simon Sinek 🌟"],
label_visibility="collapsed",
horizontal=True,
key="speaker_selection"
)
st.session_state.selected_speaker = selected_speaker.split()[0] + " " + selected_speaker.split()[1]
st.markdown("---")
# Input sections in two columns
col1, col2 = st.columns(2)
with col1:
st.subheader("Your Profile")
resume_file = st.file_uploader("Upload Resume (PDF)", type=['pdf'])
st.markdown("<small>OR</small>", unsafe_allow_html=True)
personal_text = st.text_area(
"Tell us about yourself",
height=150,
placeholder="Share your experience, skills, and achievements..."
)
with col2:
st.subheader("Target Opportunity")
job_text = st.text_area(
"What do you want to get hyped about?",
height=150,
placeholder="Paste the job description or describe your goal..."
)
# Centered button
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
if st.button("Next β†’", use_container_width=True):
if st.session_state.selected_speaker and (resume_file or personal_text) and job_text:
with st.spinner("Analyzing your profile..."):
# Process inputs
resume_text = read_pdf(resume_file) if resume_file else ""
profile_text = resume_text or personal_text
initial_input = InitialInput(
resume_text=profile_text,
personal_text=personal_text,
job_text=job_text
)
interview_state = InterviewState(user_initial_input=initial_input)
interview_state = build_reference_material_node(interview_state)
interview_state = generate_questions_node(interview_state)
st.session_state.interview_state = interview_state
st.session_state.stage = 'questions'
st.rerun()
else:
st.error("Please fill in all required information")
# Questions Stage
elif st.session_state.stage == 'questions':
with st.container():
st.markdown("### Quick Questions πŸ€”")
st.markdown("Help us personalize your hype speech by answering these questions:")
if st.session_state.interview_state and st.session_state.interview_state.qa_history:
# Create a form for all questions
with st.form("questions_form"):
for i, question in enumerate(st.session_state.interview_state.qa_history.questions):
st.markdown(f"#### {i+1}. {question.question_text}")
choice = st.radio(
"Select your answer:",
options=[choice.text for choice in question.choices],
key=f"q_{i}",
label_visibility="collapsed"
)
question.user_answer = choice
st.divider()
if st.form_submit_button("Generate My Hype Speech! 🎀", use_container_width=True):
with st.spinner("Creating your personalized hype speech..."):
interview_state = st.session_state.interview_state
interview_state = generate_transcript_node(
interview_state,
speaker_profiles[st.session_state.selected_speaker]
)
interview_state = run_text_to_speech_node(
interview_state,
st.session_state.selected_speaker
)
st.session_state.interview_state = interview_state
st.session_state.stage = 'results'
st.rerun()
# Results Stage
elif st.session_state.stage == 'results':
if (st.session_state.interview_state and
st.session_state.interview_state.transcript):
with st.container():
st.markdown("### Your Personalized Hype Speech πŸŽ‰")
# Audio player section
st.markdown("#### Listen to Your Hype Speech 🎧")
if st.session_state.interview_state.audio_bytes:
# Create columns for audio player and download button
col1, col2 = st.columns([3, 1])
with col1:
# Display audio player
st.audio(
st.session_state.interview_state.audio_bytes,
format='audio/mp3'
)
with col2:
# Add download button with unique filename
unique_filename = f"hype_speech_{uuid.uuid4().hex[:8]}.mp3"
st.download_button(
label="πŸ’Ύ Download",
data=st.session_state.interview_state.audio_bytes,
file_name=unique_filename,
mime="audio/mpeg",
help="Download your hype speech as an MP3 file"
)
# Collapsible transcript
with st.expander("View Speech Transcript πŸ“", expanded=False):
st.write(st.session_state.interview_state.transcript.content)
# Add spacing
st.markdown("---")
# Create Another button
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
if st.button("Create Another Hype Speech! πŸ”„", use_container_width=True):
# Reset session state
st.session_state.stage = 'upload'
st.session_state.interview_state = None
st.session_state.selected_speaker = None
st.rerun()
if __name__ == "__main__":
main()