RetailGenie / app.py
Parishri07's picture
Update app.py
c872642 verified
raw
history blame
7.68 kB
import gradio as gr
import os
import pandas as pd
from PIL import Image, ImageDraw
BASE_DIR = "data"
ASSETS_DIR = "assets"
STORE_MAP_FILE = os.path.join(ASSETS_DIR, "store_map_clinicplus.png")
# Approximate mapping from Aisle number to bounding box on the store map
AISLE_TO_BOX = {
# Example: '14': (x, y, width, height) - you can later load this from config
"14": (220, 150, 40, 120),
"15": (270, 150, 40, 120),
"16": (320, 150, 40, 120),
# Add more as needed...
}
def get_subfolders(path):
try:
return sorted([f for f in os.listdir(path) if os.path.isdir(os.path.join(path, f))])
except Exception as e:
print(f"❌ Error reading subfolders from {path}: {e}")
return []
def get_csv_files(path):
try:
return sorted([f[:-4] for f in os.listdir(path) if f.endswith(".csv")])
except Exception as e:
print(f"❌ Error reading CSVs from {path}: {e}")
return []
def get_quantities_from_csv(path):
try:
df = pd.read_csv(path)
if df.empty or "Quantity" not in df.columns:
return gr.update(choices=[], visible=False), {}
return gr.update(choices=df["Quantity"].dropna().tolist(), visible=True), df.to_dict()
except Exception as e:
print(f"❌ Error loading CSV: {e}")
return gr.update(choices=[], visible=False), {}
def display_quantity_info(quantity, data_dict):
try:
df = pd.DataFrame(data_dict)
row = df[df["Quantity"] == quantity].iloc[0]
if str(row["In Stock"]).strip().lower() == "yes":
msg = (
f"βœ… {quantity} is available!\n"
f"β€’ Floor: {row['Floor']}\n"
f"β€’ Aisle: {row['Aisle']}\n"
f"β€’ Price: β‚Ή{row['Price']}"
)
if "Offer" in row and pd.notna(row["Offer"]) and row["Offer"].strip():
msg += f"\nβ€’ πŸŽ‰ Offer: {row['Offer']}"
return msg
else:
return f"❌ Sorry, {quantity} is currently not in stock."
except Exception as e:
return f"⚠️ Error: {e}"
def generate_map_with_highlight(quantity, data_dict):
try:
df = pd.DataFrame(data_dict)
row = df[df["Quantity"] == quantity].iloc[0]
aisle = str(row.get("Aisle", "")).strip()
image = Image.open(STORE_MAP_FILE).convert("RGBA")
draw = ImageDraw.Draw(image)
if aisle in AISLE_TO_BOX:
x, y, w, h = AISLE_TO_BOX[aisle]
draw.rectangle([x, y, x + w, y + h], outline="red", width=5)
return image
except Exception as e:
print(f"⚠️ Map render error: {e}")
return Image.open(STORE_MAP_FILE)
def suggest_items(query):
query = query.lower()
if "gift" in query and "500" in query:
return (
"🎁 Gift Suggestions under β‚Ή500:\n"
"1. Bath & Body Gift Set - β‚Ή499\n"
"2. Mini Perfume Pack - β‚Ή349\n"
"3. Skin Care Hamper - β‚Ή399\n"
"4. Chocolates Gift Box - β‚Ή299"
)
if "shampoo" in query and "dry" in query:
return (
"🧴 Shampoos for Dry Hair:\n"
"1. Dove 500 ml - β‚Ή325\n"
"2. Clinic Plus 500 ml - β‚Ή680"
)
return "🀷 Sorry, no smart suggestions found. Try asking: 'Gift items under 500' or 'Shampoo for dry hair'"
def reset_all():
return (
None, # country - Dropdown
None, # state - Dropdown
None, # city - Dropdown
None, # store - Dropdown
None, # category - Dropdown
None, # product - Dropdown
None, # brand - Dropdown
gr.update(choices=[], visible=False), # quantity - Dropdown
"", # result - Textbox
{}, # data_state - State (MUST be a raw dict or string, not gr.update)
Image.open(STORE_MAP_FILE) # store_map - Image (if using type="pil")
)
with gr.Blocks(title="RetailGenie") as demo:
gr.Markdown("# πŸ§žβ€β™‚οΈ RetailGenie – In-Store Smart Assistant")
with gr.Tabs():
with gr.TabItem("🧭 Navigator"):
with gr.Row():
country = gr.Dropdown(label="🌍 Country", choices=get_subfolders(BASE_DIR), value=None)
state = gr.Dropdown(label="πŸ™οΈ State", choices=[], interactive=False)
city = gr.Dropdown(label="🏘️ City", choices=[], interactive=False)
store = gr.Dropdown(label="πŸͺ Store", choices=[], interactive=False)
category = gr.Dropdown(label="πŸ›οΈ Category", choices=[], interactive=False)
product = gr.Dropdown(label="πŸ“¦ Product", choices=[], interactive=False)
brand = gr.Dropdown(label="🏷️ Brand", choices=[], interactive=False)
quantity = gr.Dropdown(label="πŸ”’ Quantity", visible=False)
result = gr.Textbox(label="πŸ” Product Info", lines=5)
store_map = gr.Image(label="πŸ—ΊοΈ Store Map", value=Image.open(STORE_MAP_FILE), type="pil")
data_state = gr.State(value={})
reset_btn = gr.Button("πŸ”„ Reset All")
country.change(lambda c: gr.update(choices=get_subfolders(os.path.join(BASE_DIR, c)) if c else [], value=None, interactive=True), inputs=country, outputs=state)
state.change(lambda c, s: gr.update(choices=get_subfolders(os.path.join(BASE_DIR, c, s)) if c and s else [], value=None, interactive=True), inputs=[country, state], outputs=city)
city.change(lambda c, s, ci: gr.update(choices=get_subfolders(os.path.join(BASE_DIR, c, s, ci)) if c and s and ci else [], value=None, interactive=True), inputs=[country, state, city], outputs=store)
store.change(lambda c, s, ci, st: gr.update(choices=get_subfolders(os.path.join(BASE_DIR, c, s, ci, st)) if all([c, s, ci, st]) else [], value=None, interactive=True), inputs=[country, state, city, store], outputs=category)
category.change(lambda c, s, ci, st, cat: gr.update(choices=get_subfolders(os.path.join(BASE_DIR, c, s, ci, st, cat)) if all([c, s, ci, st, cat]) else [], value=None, interactive=True), inputs=[country, state, city, store, category], outputs=product)
product.change(lambda c, s, ci, st, cat, prod: gr.update(choices=get_csv_files(os.path.join(BASE_DIR, c, s, ci, st, cat, prod)) if all([c, s, ci, st, cat, prod]) else [], value=None, interactive=True), inputs=[country, state, city, store, category, product], outputs=brand)
brand.change(lambda c, s, ci, st, cat, prod, b: get_quantities_from_csv(os.path.join(BASE_DIR, c, s, ci, st, cat, prod, f"{b}.csv")) if all([c, s, ci, st, cat, prod, b]) else (gr.update(choices=[], visible=False), {}), inputs=[country, state, city, store, category, product, brand], outputs=[quantity, data_state])
quantity.change(display_quantity_info, inputs=[quantity, data_state], outputs=result)
quantity.change(generate_map_with_highlight, inputs=[quantity, data_state], outputs=store_map)
reset_btn.click(reset_all, inputs=[], outputs=[country, state, city, store, category, product, brand, quantity, result, data_state, store_map])
with gr.TabItem("🎁 Smart Suggestions"):
gr.Markdown("### πŸ€– Ask RetailGenie for Recommendations")
suggestion_input = gr.Textbox(label="Ask something like:", placeholder="Gift items under 500", lines=1)
suggest_btn = gr.Button("πŸ’‘ Get Suggestions")
suggestions_output = gr.Textbox(label="πŸ“ Suggestions", lines=10)
suggest_btn.click(suggest_items, inputs=suggestion_input, outputs=suggestions_output)
demo.launch()