| """ |
| Beautiful WhatsApp-Style Chatbot with Gradient Theme |
| """ |
|
|
| import streamlit as st |
| from groq import Groq |
|
|
| |
| st.set_page_config( |
| page_title="Chat Assistant", |
| page_icon="π¬", |
| layout="centered", |
| initial_sidebar_state="collapsed" |
| ) |
|
|
| |
| st.markdown(""" |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); |
| |
| * { |
| font-family: 'Inter', sans-serif; |
| } |
| |
| /* Gradient Background - Purple/Pink like your image */ |
| .stApp { |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%) !important; |
| background-attachment: fixed !important; |
| } |
| |
| /* Hide default Streamlit elements */ |
| #MainMenu {visibility: hidden;} |
| footer {visibility: hidden;} |
| header {visibility: hidden;} |
| |
| /* Main Container - White rounded card */ |
| .block-container { |
| background: rgba(255, 255, 255, 0.95) !important; |
| backdrop-filter: blur(20px) !important; |
| border-radius: 24px !important; |
| padding: 2rem !important; |
| margin-top: 2rem !important; |
| margin-bottom: 2rem !important; |
| box-shadow: 0 20px 40px rgba(0,0,0,0.2) !important; |
| max-width: 800px !important; |
| } |
| |
| /* Title Styling */ |
| h1 { |
| color: #1f2937 !important; |
| font-weight: 700 !important; |
| text-align: center !important; |
| margin-bottom: 1rem !important; |
| font-size: 2.5rem !important; |
| } |
| |
| /* API Key Section - Beautiful Container */ |
| .api-container { |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%) !important; |
| padding: 1.5rem !important; |
| border-radius: 16px !important; |
| margin-bottom: 1.5rem !important; |
| border: 2px solid #e0e7ff !important; |
| } |
| |
| /* Input Fields Styling */ |
| .stTextInput > div > div > input { |
| border-radius: 12px !important; |
| border: 2px solid #c7c7c7 !important; |
| padding: 0.75rem 1rem !important; |
| font-size: 1rem !important; |
| transition: all 0.3s ease !important; |
| background: white !important; |
| } |
| |
| .stTextInput > div > div > input:focus { |
| border-color: #667eea !important; |
| box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2) !important; |
| } |
| |
| /* Selectbox Styling */ |
| .stSelectbox > div > div { |
| border-radius: 12px !important; |
| border: 2px solid #c7c7c7 !important; |
| } |
| |
| /* Chat Messages Container */ |
| .stChatMessage { |
| padding: 0.5rem 0 !important; |
| } |
| |
| /* User Message - Purple bubble */ |
| .stChatMessage[data-testid="stChatMessageUser"] > div:first-child { |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; |
| color: white !important; |
| border-radius: 20px 20px 2px 20px !important; |
| padding: 12px 18px !important; |
| box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3) !important; |
| font-weight: 500 !important; |
| } |
| |
| /* Assistant Message - White bubble */ |
| .stChatMessage[data-testid="stChatMessageAssistant"] > div:first-child { |
| background: white !important; |
| color: #1f2937 !important; |
| border-radius: 20px 20px 20px 2px !important; |
| padding: 12px 18px !important; |
| box-shadow: 0 4px 12px rgba(0,0,0,0.08) !important; |
| border: 1px solid #e5e7eb !important; |
| font-weight: 500 !important; |
| } |
| |
| /* Chat Input - Fixed at bottom style */ |
| .stChatInputContainer { |
| background: white !important; |
| border-radius: 16px !important; |
| padding: 8px !important; |
| box-shadow: 0 4px 12px rgba(0,0,0,0.1) !important; |
| border: 1px solid #e5e7eb !important; |
| } |
| |
| /* Buttons - Purple gradient like your image */ |
| .stButton > button { |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; |
| color: white !important; |
| border: none !important; |
| border-radius: 12px !important; |
| padding: 0.75rem 1.5rem !important; |
| font-weight: 600 !important; |
| transition: all 0.3s ease !important; |
| box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3) !important; |
| } |
| |
| .stButton > button:hover { |
| transform: translateY(-2px) !important; |
| box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4) !important; |
| } |
| |
| /* Link Button */ |
| .stLinkButton > a { |
| background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%) !important; |
| color: white !important; |
| border-radius: 12px !important; |
| padding: 0.75rem 1.5rem !important; |
| font-weight: 600 !important; |
| text-decoration: none !important; |
| border: none !important; |
| } |
| |
| /* Warning/Info Boxes */ |
| .stAlert { |
| border-radius: 12px !important; |
| border: none !important; |
| } |
| |
| /* Divider */ |
| hr { |
| border-color: #e5e7eb !important; |
| margin: 1.5rem 0 !important; |
| } |
| |
| /* Caption */ |
| .stCaption { |
| color: #6b7280 !important; |
| text-align: center !important; |
| font-size: 0.8rem !important; |
| } |
| |
| /* Scrollbar Styling */ |
| ::-webkit-scrollbar { |
| width: 8px; |
| } |
| ::-webkit-scrollbar-track { |
| background: #f1f1f1; |
| border-radius: 10px; |
| } |
| ::-webkit-scrollbar-thumb { |
| background: #c1c1c1; |
| border-radius: 10px; |
| } |
| ::-webkit-scrollbar-thumb:hover { |
| background: #a1a1a1; |
| } |
| </style> |
| """, unsafe_allow_html=True) |
|
|
| |
| st.markdown("<h1>π¬ Chat Assistant</h1>", unsafe_allow_html=True) |
|
|
| st.markdown(""" |
| <p style='text-align: center; color: #6b7280; margin-bottom: 2rem; font-size: 1.1rem;'> |
| A modern, WhatsApp-style chat interface powered by Groq AI |
| </p> |
| """, unsafe_allow_html=True) |
|
|
| |
| with st.container(): |
| st.markdown(""" |
| <div class='api-container'> |
| <h3 style='color: #1f2937; margin-bottom: 1rem; text-align: center;'> |
| π Enter Your API Key |
| </h3> |
| </div> |
| """, unsafe_allow_html=True) |
| |
| col1, col2 = st.columns([3, 1]) |
| with col1: |
| api_key = st.text_input( |
| "API Key", |
| type="password", |
| placeholder="Paste your Groq API key here (gsk_...)", |
| label_visibility="collapsed" |
| ) |
| with col2: |
| st.link_button("β‘ Get Free Key", "https://console.groq.com/keys", use_container_width=True) |
|
|
| if not api_key: |
| st.warning("β οΈ Please enter your API key above to start chatting!") |
| st.info(""" |
| **How to get your FREE key in 30 seconds:** |
| 1. Click **"Get Free Key"** button above βοΈ |
| 2. Sign in with Google/GitHub (instant) |
| 3. Click **"Create API Key"** |
| 4. Copy and paste it in the box above |
| """) |
| st.stop() |
|
|
| |
| col1, col2 = st.columns([2, 1]) |
| with col1: |
| model = st.selectbox( |
| "π€ Choose AI Model:", |
| ["llama-3.1-8b-instant", "mixtral-8x7b-32768", "gemma2-9b-it"], |
| help="Free tier: 20 requests/min, 200/day" |
| ) |
|
|
| with col2: |
| if st.button("ποΈ Clear Chat", use_container_width=True): |
| st.session_state.messages = [] |
| st.rerun() |
|
|
| st.markdown("---") |
|
|
| |
| if "messages" not in st.session_state: |
| st.session_state.messages = [ |
| {"role": "assistant", "content": "Hey there! π I'm your AI assistant. How can I help you today?"} |
| ] |
|
|
| |
| for message in st.session_state.messages: |
| with st.chat_message(message["role"], avatar="π§" if message["role"] == "user" else "π€"): |
| st.markdown(message["content"]) |
|
|
| |
| if prompt := st.chat_input("π Type your message here...", key="chat_input"): |
| |
| st.session_state.messages.append({"role": "user", "content": prompt}) |
| |
| with st.chat_message("user", avatar="π§"): |
| st.markdown(prompt) |
| |
| |
| with st.chat_message("assistant", avatar="π€"): |
| with st.spinner("β¨ Thinking..."): |
| try: |
| client = Groq(api_key=api_key) |
| |
| response = client.chat.completions.create( |
| model=model, |
| messages=[{"role": m["role"], "content": m["content"]} for m in st.session_state.messages], |
| temperature=0.7, |
| max_tokens=1024 |
| ) |
| |
| assistant_response = response.choices[0].message.content |
| st.markdown(assistant_response) |
| |
| |
| st.session_state.messages.append( |
| {"role": "assistant", "content": assistant_response} |
| ) |
| |
| except Exception as e: |
| error_msg = str(e) |
| if "rate limit" in error_msg.lower(): |
| st.error("β±οΈ Whoa! Too fast! Free tier allows 20 requests per minute. Please wait a moment.") |
| elif "invalid" in error_msg.lower(): |
| st.error("π Invalid API key. Please check your key and try again.") |
| else: |
| st.error(f"β Error: {error_msg}") |
|
|
| st.markdown("---") |
| st.caption("π Your API key is session-only and never stored | Powered by Groq (Free Tier)") |