# 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(""" """, unsafe_allow_html=True) else: st.markdown(""" """, 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"
", unsafe_allow_html=True ) col.write(hex_color) st.subheader("🔤 Font Suggestions") fonts = fetch_google_fonts() for font in fonts: st.markdown( f"

{font}

", unsafe_allow_html=True ) st.success("✅ Moodboard ready! Right-click or screenshot to save.") st.session_state.generate = False # Reset