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("
๐ฟ SkinSense AI โ Skincare Buddy
", 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 "โ Please enter your name."
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"โ Error: {str(e)}"
# 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 '' 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"
{stripped}
\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('<', '<').replace('>', '>')
formatted_content += f"{clean_content}
\n"
# Build the final response with proper HTML structure
html_output = f"""
{formatted_content}
"""
# 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"
"
# Final HTML layout with fallback for sticker
final_html = f"""
๐ค {name} | {gender}, {age} yrs
โจ
{image_html}
{html_output}
"""
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(""):
st.markdown(result, unsafe_allow_html=True)
else:
st.markdown(result, unsafe_allow_html=True)