MoodboardAI / app.py
IqraFatima's picture
Update app.py
a5f16fc verified
# app.py
import streamlit as st
import requests
from PIL import Image
from io import BytesIO
from colorthief import ColorThief
import random
import os
# -- API Keys from Hugging Face Secrets --
UNSPLASH_ACCESS_KEY = os.environ.get("UNSPLASH_ACCESS_KEY")
GOOGLE_FONTS_API_KEY = os.environ.get("GOOGLE_FONTS_API_KEY")
st.set_page_config(page_title="Moodboard AI", layout="wide")
# -- Init Session State --
if 'dark_mode' not in st.session_state:
st.session_state.dark_mode = False
if 'generate' not in st.session_state:
st.session_state.generate = False
if 'remix' not in st.session_state:
st.session_state.remix = random.randint(1, 10000)
# -- Dark Mode Toggle (no forced rerun) --
dark_mode_toggle = st.toggle("πŸŒ™ Toggle Dark Mode", value=st.session_state.dark_mode, key="dark_toggle")
if dark_mode_toggle != st.session_state.dark_mode:
st.session_state.dark_mode = dark_mode_toggle
st.experimental_rerun()
# -- Apply Dark Mode Styling --
if st.session_state.dark_mode:
st.markdown("""
<style>
body, .stApp {
background-color: #121212;
color: #f0f0f0;
}
h1, h2, h3, h4, h5, h6 {
color: #ffffff !important;
}
.stTextInput > div > div > input,
.stTextArea > div > textarea {
background-color: #222222;
color: #ffffff;
}
.stButton>button {
background-color: #333333;
color: #ffffff;
}
</style>
""", unsafe_allow_html=True)
else:
st.markdown("""
<style>
h1, h2, h3, h4, h5, h6 {
color: #000000 !important;
}
</style>
""", unsafe_allow_html=True)
# -- Title --
st.title("🎨 Moodboard AI – Smart Visual Inspiration Generator")
# -- API Status Display --
if UNSPLASH_ACCESS_KEY:
st.success("βœ… Unsplash API key loaded successfully.")
else:
st.warning("⚠️ Unsplash API key missing or not set in Hugging Face Secrets.")
if GOOGLE_FONTS_API_KEY:
st.success("βœ… Google Fonts API key loaded successfully.")
else:
st.warning("⚠️ Google Fonts API key missing or not set in Hugging Face Secrets.")
# -- Theme Input --
theme = st.text_input("Enter a theme or keyword (e.g. 'vintage tech', 'coastal minimalism'):", "futuristic tech").lower()
# -- Control Buttons --
col1, col2 = st.columns(2)
with col1:
if st.button("πŸ” Remix Moodboard"):
st.session_state.remix = random.randint(1, 10000)
st.session_state.generate = True
with col2:
if st.button("✨ Generate Moodboard"):
st.session_state.generate = True
# -- Fetch Images from Unsplash --
def fetch_images_from_unsplash(query, count=5):
if not UNSPLASH_ACCESS_KEY:
st.error("🚫 Missing Unsplash API Key. Please add it to Hugging Face Secrets.")
return []
try:
url = f"https://api.unsplash.com/search/photos?query={query}&per_page={count}&client_id={UNSPLASH_ACCESS_KEY}"
response = requests.get(url)
if response.status_code != 200:
st.error(f"❌ Unsplash API Error: {response.status_code}")
return []
data = response.json()
results = data.get('results', [])
if not results:
st.warning("⚠️ Unsplash API returned 0 results. Try a different keyword.")
return [item['urls']['regular'] for item in results]
except Exception as e:
st.error(f"❌ Error fetching images: {e}")
return []
# -- Extract Dominant Colors --
def extract_colors(image_urls):
colors = []
for url in image_urls[:3]:
try:
response = requests.get(url)
img = BytesIO(response.content)
ct = ColorThief(img)
palette = ct.get_palette(color_count=3)
colors.extend(palette)
except:
continue
return colors[:5]
# -- Fetch Fonts from Google Fonts --
def fetch_google_fonts():
if not GOOGLE_FONTS_API_KEY:
st.error("🚫 Missing Google Fonts API Key. Please add it to Hugging Face Secrets.")
return []
try:
url = f"https://www.googleapis.com/webfonts/v1/webfonts?sort=popularity&key={GOOGLE_FONTS_API_KEY}"
res = requests.get(url)
data = res.json()
fonts = [item['family'] for item in data.get('items', [])]
return random.sample(fonts, 3)
except Exception as e:
st.error(f"❌ Error fetching fonts: {e}")
return []
# -- Show Moodboard --
if st.session_state.get("generate"):
with st.spinner("Generating your moodboard..."):
query = f"{theme} {st.session_state.remix}"
image_urls = fetch_images_from_unsplash(query)
if not image_urls:
st.warning("No images found. Try another keyword or check your API key.")
else:
st.subheader("πŸ–ΌοΈ Image Suggestions")
cols = st.columns(len(image_urls))
for col, url in zip(cols, image_urls):
col.image(url, use_container_width=True)
st.subheader("🎨 Color Palette")
palette = extract_colors(image_urls)
color_cols = st.columns(len(palette))
for col, rgb in zip(color_cols, palette):
hex_color = '#%02x%02x%02x' % rgb
col.markdown(
f"<div style='background-color:{hex_color};height:50px;width:100%;border-radius:5px'></div>",
unsafe_allow_html=True
)
col.write(hex_color)
st.subheader("πŸ”€ Font Suggestions")
fonts = fetch_google_fonts()
for font in fonts:
st.markdown(
f"<p style='font-family:{font};font-size:24px;color:{'#ffffff' if st.session_state.dark_mode else '#000000'}'>{font}</p>",
unsafe_allow_html=True
)
st.success("βœ… Moodboard ready! Right-click or screenshot to save.")
st.session_state.generate = False # Reset