Spaces:
Sleeping
Sleeping
File size: 7,334 Bytes
70e7a93 517995a 14b368e b0e4528 517995a d2d5f1a 517995a ebfbcbb 14b368e 15d4a5b 3c702d3 517995a 3c702d3 517995a 6bf7ce5 517995a 708859f ebfbcbb 517995a f855ccd bef3485 517995a bef3485 517995a ebfbcbb 517995a ebfbcbb f855ccd ebfbcbb bef3485 ebfbcbb bef3485 517995a 3c702d3 517995a ef5c69d 517995a 3c702d3 517995a ebfbcbb 517995a bef3485 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
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('<', '<').replace('>', '>')
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) |