Spaces:
Sleeping
Sleeping
import streamlit as st | |
from PIL import Image | |
from phi.agent import Agent | |
from phi.model.google import Gemini | |
from phi.tools.firecrawl import FirecrawlTools | |
import google.generativeai as genai | |
import io | |
import base64 | |
import time | |
from pathlib import Path | |
import tempfile | |
from dotenv import load_dotenv | |
import os | |
# Load environment variables | |
load_dotenv() | |
# Configure Google API | |
API_KEY = os.getenv("GOOGLE_API_KEY") | |
if API_KEY: | |
genai.configure(api_key=API_KEY) | |
# Page Configuration | |
st.set_page_config( | |
page_title="AI Shopping Partner", | |
page_icon="π€ποΈ", | |
layout="centered" | |
) | |
# Custom CSS for styling | |
st.markdown(""" | |
<style> | |
/* Main container styling */ | |
.main { | |
background-color: #f9fafb; | |
padding: 2rem; | |
} | |
/* Title styling */ | |
.title-text { | |
color: #FFFFFF; | |
font-size: 2.5rem !important; | |
font-weight: 700; | |
text-align: center; | |
margin-bottom: 1rem; | |
} | |
/* Header styling */ | |
.header-text { | |
color: #4a5568 !important; | |
font-size: 1.2rem !important; | |
text-align: center; | |
margin-bottom: 2rem; | |
} | |
/* Upload section styling */ | |
.upload-section { | |
background: white; | |
border-radius: 12px; | |
padding: 2rem; | |
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); | |
margin-bottom: 2rem; | |
} | |
/* Input field styling */ | |
.stTextInput input, .stTextArea textarea { | |
border: 2px solid #e2e8f0 !important; | |
border-radius: 8px !important; | |
padding: 0.75rem !important; | |
} | |
/* Button styling */ | |
.stButton button { | |
background: #4299e1 !important; | |
color: white !important; | |
border: none; | |
padding: 12px 24px; | |
border-radius: 8px; | |
font-weight: 600; | |
transition: all 0.3s; | |
width: 100%; | |
} | |
.stButton button:hover { | |
background: #3182ce !important; | |
transform: translateY(-1px); | |
box-shadow: 0 4px 6px -1px rgba(66, 153, 225, 0.3); | |
} | |
/* Result section styling */ | |
.result-section { | |
background: white; | |
border-radius: 12px; | |
padding: 2rem; | |
margin-top: 2rem; | |
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); | |
} | |
/* Product card styling */ | |
.product-card { | |
border-left: 4px solid #4299e1; | |
padding: 1rem; | |
margin: 1rem 0; | |
background: #f8fafc; | |
border-radius: 8px; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
# Page Content | |
st.markdown('<p class="title-text">π€ AI Shopping Partner ποΈ</p>', unsafe_allow_html=True) | |
st.markdown('<p class="header-text">Discover perfect products with AI-powered recommendations</p>', unsafe_allow_html=True) | |
# Initialize the Agent | |
def initialize_agent(): | |
return Agent( | |
name="Shopping Partner", | |
model=Gemini(id="gemini-2.0-flash-exp"), | |
instructions=[ | |
"You are a product recommender agent specializing in finding products that match user preferences.", | |
"Prioritize finding products that satisfy as many user requirements as possible, but ensure a minimum match of 50%.", | |
"Search for products only from authentic and trusted e-commerce websites such as Google Shopping, Amazon, Flipkart, Myntra, Meesho, Nike, and other reputable platforms.", | |
"Verify that each product recommendation is in stock and available for purchase.", | |
"Avoid suggesting counterfeit or unverified products.", | |
"Clearly mention the key attributes of each product (e.g., price, brand, features) in the response.", | |
"Format the recommendations neatly and ensure clarity for ease of user understanding.", | |
], | |
tools=[FirecrawlTools()], | |
markdown=True | |
) | |
# Initialize the Agent | |
multimodal_agent = initialize_agent() | |
# Function to get Gemini response | |
def get_gemini_response(api_key, prompt, image): | |
model = genai.GenerativeModel(model_name="gemini-2.0-flash-exp") | |
response = model.generate_content([prompt, image]) | |
return response.text | |
# Image Upload Section | |
with st.container(): | |
st.markdown(""" | |
<div class="upload-section"> | |
<h3 style="color: #2d3748; margin-bottom: 1rem;">πΈ Upload Product Image</h3> | |
""", unsafe_allow_html=True) | |
image_file = st.file_uploader( | |
"Drag and drop or click to upload (JPEG, PNG)", | |
type=["jpg", "jpeg", "png"], | |
help="Max file size: 20MB", | |
label_visibility="collapsed" | |
) | |
st.markdown("</div>", unsafe_allow_html=True) | |
# Display Image | |
if image_file is not None: | |
image = Image.open(image_file) | |
st.image(image, caption="Uploaded Image", use_column_width=True) | |
# Preferences Section | |
with st.container(): | |
st.markdown("### π¨ Product Preferences") | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
prompt_color = st.text_input("Preferred Color", placeholder="e.g., Navy Blue") | |
with col2: | |
prompt_purpose = st.text_input("Intended Use", placeholder="e.g., Running") | |
with col3: | |
prompt_budget = st.text_input("Budget Range", placeholder="e.g., βΉ5,000-10,000") | |
# Search Query Section | |
user_query = st.text_area( | |
"π Tell us more about what you're looking for:", | |
placeholder="Example: 'Looking for durable running shoes with good arch support'", | |
height=100 | |
) | |
# Search Button | |
if st.button("π Find Perfect Products"): | |
if not user_query: | |
st.warning("Please describe what you're looking for") | |
else: | |
with st.spinner("π§ AI is analyzing your preferences..."): | |
try: | |
# Step 1: Identify the product in the image | |
prompt = "What is in this photo?" | |
product_description = get_gemini_response(API_KEY, prompt, image) | |
# Step 2: Generate analysis prompt | |
analysis_prompt = f""" | |
I am looking for {product_description} | |
with the below preferences: | |
- Color: {prompt_color} | |
- Purpose: {prompt_purpose} | |
- Budget: {prompt_budget} | |
Can you provide recommendations? Always make sure that you provide hyperlinks to the product. | |
Additional details: {user_query} | |
""" | |
# Step 3: Get recommendations from the agent | |
response = multimodal_agent.run(analysis_prompt, image=image) | |
# Display Results | |
st.markdown(""" | |
<div class="result-section"> | |
<h3 style="color: #2d3748; margin-bottom: 1rem;">π Recommended Products</h3> | |
""", unsafe_allow_html=True) | |
# Display the response content | |
st.markdown(response.content, unsafe_allow_html=True) | |
st.markdown("</div>", unsafe_allow_html=True) | |
except Exception as error: | |
st.error(f"β οΈ An error occurred: {str(error)}") | |
# Footer | |
st.markdown(""" | |
<div style="text-align: center; color: #718096; margin-top: 3rem;"> | |
<hr style="margin-bottom: 1rem;"> | |
<p>Powered by Gemini AI β’ Secure Processing β’ Always Learning</p> | |
</div> | |
""", unsafe_allow_html=True) |