JaveriaZia's picture
Update app.py
6bf7ce5 verified
import streamlit as st
import random
import os
import re
from groq import Groq
import base64
# Set your GROQ API Key
GROQ_API_KEY = os.getenv("GROQ_API_KEY", "your_groq_api_key_here") # Replace with your actual key or set via environment
client = Groq(api_key=GROQ_API_KEY)
# Stickers for response - using more reliable CDN URLs
stickers = [
"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f60a.png", # Smiling face
"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f31f.png", # Glowing star
"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f338.png", # Cherry blossom
"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f31c.png", # Moon face
"https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/2728.png" # Sparkles
]
# Streamlit UI setup
st.set_page_config(page_title="SkinSense AI", layout="centered")
st.markdown("<h1 style='text-align:center; color:#4CAF50;'>🌿 SkinSense AI – Skincare Buddy</h1>", unsafe_allow_html=True)
# Input form
name = st.text_input("Your Name")
gender = st.radio("Gender", ["Female", "Male", "Other"])
age = st.slider("Age", 12, 100, 25)
skin_concern = st.selectbox("Main Skin Concern", ["Acne", "Dryness", "Oiliness", "Pores", "Dullness", "Pigmentation", "Other"])
description = st.text_area("Describe Your Skin Problem", placeholder="e.g. Small white pimples under skin for 2 weeks...")
image = st.file_uploader("Or upload a picture of your skin", type=["jpg", "jpeg", "png"])
duration = st.selectbox("How long has this been a concern?", ["Less than 1 week", "1-2 weeks", "More than 2 weeks"])
sensitivity = st.radio("Is your skin sensitive?", ["Yes", "No", "Not Sure"])
routine = st.text_input("Do you follow a routine?", placeholder="e.g. Facewash, moisturizer, sunscreen")
submit = st.button("✨ Generate Skincare Advice")
# Core function
def skincare_advice(name, gender, age, skin_concern, description, duration, sensitivity, routine, image):
if not name.strip():
return "<span style='color:red;'>⚠ Please enter your name.</span>"
sticker = random.choice(stickers)
# Determine concern text
if description.strip():
concern_text = description.strip()
elif image is not None:
concern_text = "The user uploaded an image showing their skin issue. Please base your suggestions on typical visible skin concerns."
else:
concern_text = skin_concern
# Prompt for the model
prompt = f"""
A user named {name} (Gender: {gender}, Age: {age}) is experiencing a skin issue: "{concern_text}".
Duration: {duration}, Sensitive skin: {sensitivity}, Routine followed: {routine}.
Write a response in sections using emojis and headings only for:
🌟 Greeting
🩺 Skin Issue Summary
πŸ“Š Global Insight
🧴 Daily Skincare Routine
🌿 Natural Remedy
πŸ’‘ Lifestyle Tips
πŸ’¬ Motivational Quote
Each section should start with a title (e.g., 🌿 Natural Remedy) on one line, then 2–4 lines of helpful content below it in plain text or bullet points.
Do not use bold, underline, or any extra styling.
"""
try:
response = client.chat.completions.create(
model="llama3-8b-8192",
messages=[{"role": "user", "content": prompt}]
)
raw = response.choices[0].message.content
except Exception as e:
return f"<span style='color:red;'>❌ Error: {str(e)}</span>"
# Clean the raw response first - remove any HTML tags that might be in the AI response
import html
raw = html.unescape(raw) # Decode HTML entities
raw = re.sub(r'<[^>]+>', '', raw) # Remove any HTML tags
# Format response using markdown and simple text formatting
lines = raw.strip().split("\n")
formatted_content = ""
section_colors = {
"🌟": "#E53935", "🩺": "#D81B60", "πŸ“Š": "#5E35B1",
"🧴": "#F57C00", "🌿": "#43A047", "πŸ’‘": "#039BE5", "πŸ’¬": "#6D4C41"
}
for line in lines:
stripped = line.strip()
if not stripped:
continue
# Skip lines that look like HTML code or contain style attributes
if '<' in stripped and ('style=' in stripped or '/>' in stripped or '</p>' in stripped):
continue
# Check if this line is a section header (starts with emoji and contains expected keywords)
is_section_header = False
for emoji in section_colors:
if stripped.startswith(emoji):
# Additional check to ensure it's actually a header and not content
header_keywords = ["Greeting", "Skin Issue Summary", "Global Insight", "Daily Skincare Routine",
"Natural Remedy", "Lifestyle Tips", "Motivational Quote"]
if any(keyword.lower() in stripped.lower() for keyword in header_keywords):
is_section_header = True
color = section_colors[emoji]
# Use HTML span for colored headers
formatted_content += f"<br><span style='color:{color}; font-weight:bold; font-size:18px;'>{stripped}</span><br>\n"
break
# If not a section header, treat as regular content
if not is_section_header:
# Clean content and add as regular text
clean_content = stripped.replace('<', '&lt;').replace('>', '&gt;')
formatted_content += f"{clean_content}<br>\n"
# Build the final response with proper HTML structure
html_output = f"""
<div style='margin: 10px 0;'>
{formatted_content}
</div>
"""
# Embed uploaded image
image_html = ""
if image is not None:
mime = image.type
img_bytes = image.read()
img_b64 = base64.b64encode(img_bytes).decode()
image_html = f"<img src='data:{mime};base64,{img_b64}' style='max-width:100%; border-radius:12px; margin:15px 0;'>"
# Final HTML layout with fallback for sticker
final_html = f"""
<div style='font-family:Arial, sans-serif; color:#111; background:#fff; padding:20px;
border-radius:12px; border:1px solid #ccc; box-shadow:0 2px 6px rgba(0,0,0,0.1);'>
<div style='display:flex; align-items:center; justify-content:space-between; margin-bottom:20px;'>
<h2 style='color:#000; margin:0;'>πŸ‘€ <b>{name}</b> | {gender}, {age} yrs</h2>
<div style='width:70px; height:70px; border-radius:10px; background:linear-gradient(45deg, #ff6b6b, #4ecdc4); display:flex; align-items:center; justify-content:center; font-size:30px;'>
<img src="{sticker}" style="width:60px; height:60px; border-radius:8px;" alt="✨" onerror="this.style.display='none'; this.nextSibling.style.display='block';">
<span style="display:none; color:white;">✨</span>
</div>
</div>
{image_html}
{html_output}
</div>
"""
return final_html
# Handle button press
if submit:
with st.spinner("Generating advice..."):
result = skincare_advice(name, gender, age, skin_concern, description, duration, sensitivity, routine, image)
if result.startswith("<span style='color:red;'>"):
st.markdown(result, unsafe_allow_html=True)
else:
st.markdown(result, unsafe_allow_html=True)