fortuala's picture
Update app.py
0a731d7 verified
# app.py
import gradio as gr
import pandas as pd
import torch
from sentence_transformers import SentenceTransformer, util
# 1) Load your committed Excel database
df = pd.read_excel("BuyWellDataBase.xlsx")
# 2) Prepare the "combined" field and compute embeddings for each row
df["combined"] = df["Company Name"] + " — " + df["Product or Services"]
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
row_embeddings = model.encode(df["combined"].tolist(), convert_to_tensor=True)
# 3) Build a centroid embedding for each sector
sectors = df["Sector"].unique().tolist()
sector_embeddings = {}
for sector in sectors:
# indices of rows in this sector
idxs = df.index[df["Sector"] == sector].tolist()
# mean of their embeddings
sector_embeddings[sector] = row_embeddings[idxs].mean(dim=0, keepdim=True)
def recommend_store(query: str) -> str:
q = query.strip()
if not q:
return "<p style='color:red;'>❗ Please enter what you’d like to buy.</p>"
# 1) Embed the query
q_emb = model.encode(q, convert_to_tensor=True, normalize_embeddings=True)
# 2) Find the best-matching sector via cosine similarity
sector_sims = {
sector: util.cos_sim(q_emb, emb).item()
for sector, emb in sector_embeddings.items()
}
best_sector = max(sector_sims, key=sector_sims.get)
# 3) Within that sector, score all rows and pick top 5
mask = df["Sector"] == best_sector
sector_idxs = df.index[mask].tolist()
sims = util.cos_sim(q_emb, row_embeddings[sector_idxs])[0]
top5 = torch.topk(sims, k=min(5, len(sector_idxs))).indices.tolist()
# 4) Build an HTML table of the top 5
rows = []
for rank_idx in top5:
df_idx = sector_idxs[rank_idx]
row = df.loc[df_idx]
rows.append(f"""
<tr>
<td><strong>{row['Company Name']}</strong></td>
<td>{row['Product or Services']}</td>
<td style="text-align:center;">{row['Rating']}</td>
<td>{row['Google Map Location']}</td>
<td><a href="{row['Website']}" target="_blank">Visit site</a></td>
</tr>
""")
table_html = f"""
<h3>Top 5 alternatives in <em>{best_sector}</em></h3>
<table border="1" cellpadding="4" cellspacing="0">
<thead style="background:#f0f0f0;">
<tr>
<th>Company</th>
<th>Product / Services</th>
<th>Rating</th>
<th>Location</th>
<th>Website</th>
</tr>
</thead>
<tbody>
{''.join(rows)}
</tbody>
</table>
"""
return table_html
# 5) Build Gradio UI
with gr.Blocks(title="GoodBuy Guide") as demo:
gr.HTML("""
<h1 style="text-align:center; color: #2a7f4f;">🌿 GoodBuy Guide</h1>
<p style="text-align:center;">Discover ethical, democratic & sustainable alternatives—one “good buy” at a time!</p>
<p style="text-align:center; font-size:0.9em;">*Feedback or issues?* 📧 <a href="mailto:msalanfortuny@gmail.com">msalanfortuny@gmail.com</a></p>
""")
with gr.Row():
inp = gr.Textbox(
placeholder="e.g. coffee beans, Amazon Prime, Siemens fridge…",
label="What do you want to buy?",
interactive=True
)
btn = gr.Button("Find a Good Buy", variant="primary")
out = gr.HTML()
btn.click(fn=recommend_store, inputs=inp, outputs=out)
inp.submit(fn=recommend_store, inputs=inp, outputs=out)
if __name__ == "__main__":
demo.launch()