import gradio as gr
import pandas as pd
import numpy as np
import folium
import sys
import os
# Add utils to path
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'utils'))
from clean_text import clean_text
from semantic_similarity import Encoder
from main import get_recommendations
print("Loading restaurant data...")
data = pd.read_csv("data/toy_data_aggregated_embeddings.csv")
print(f"Loaded {len(data)} restaurants")
# Initialize semantic encoder
print("Loading semantic encoder model...")
try:
encoder = Encoder()
print("Semantic encoder loaded")
except Exception as e:
print(f"Warning: Could not load semantic encoder: {e}")
print("Falling back to keyword-only search")
def create_paris_map(results_df):
"""Create interactive map of Paris restaurants"""
paris_center = [48.8566, 2.3522]
m = folium.Map(location=paris_center, zoom_start=12, tiles='OpenStreetMap')
for idx, row in results_df.iterrows():
lat_offset = np.random.uniform(-0.05, 0.05)
lng_offset = np.random.uniform(-0.07, 0.07)
coords = [48.8566 + lat_offset, 2.3522 + lng_offset]
rating = float(row.get('overall_rating', 0))
color = 'green' if rating >= 4.5 else 'blue' if rating >= 4.0 else 'orange' if rating >= 3.5 else 'red'
popup_html = f"""
{row['name']}
Rating: {row.get('overall_rating', 'N/A')}
Reviews: {row.get('review_count', 'N/A')}
Popularity Score: {row.get('pop_score', 'N/A'):.2f}
"""
folium.Marker(
location=coords,
popup=folium.Popup(popup_html, max_width=300),
icon=folium.Icon(color=color, icon='cutlery', prefix='fa')
).add_to(m)
return m._repr_html_()
def search_restaurants(query_input, data_source, num_results):
n_candidates = 2000
query_clean = clean_text(query_input)
restaurant_ids = get_recommendations(query_clean, n_candidates, num_results, data_source)
# Subset data for recommendedations
results = data[data["id"].isin(restaurant_ids)]
map_html = create_paris_map(results)
output = f"Found {len(results)} restaurants for '{query_input}'\n"
output += f"Data Source: {data_source}\n"
for idx, (_, row) in enumerate(results.iterrows(), 1):
name = row.get('name', 'Unknown')
rating = row.get('overall_rating', 'N/A')
reviews = row.get('review_count', 'N/A')
output += f"{idx}. **{name}**\n"
output += f" Rating: {rating} | Reviews: {reviews}\n"
output += "\n"
if 'address' in row and pd.notna(row['address']):
addr = str(row['address'])[:100]
output += f" Address: {addr}\n"
output += "\n"
return output, map_html
# Create Gradio interface
with gr.Blocks(
title="Restaurant Finder",
# theme=gr.themes.Soft()
) as app:
gr.Markdown("""
# Advanced Restaurant Recommendation System
### Search Through 5,000+ Restaurants with AI-Powered Semantic Search
Find restaurants using semantic understanding and popularity ranking!
""")
with gr.Row():
with gr.Column(scale=3):
query_input = gr.Textbox(
label="Search Query",
placeholder="e.g., Italian pasta, best sushi, romantic dinner, family-friendly pizza",
lines=2
)
with gr.Column(scale=2):
data_source = gr.Dropdown(
choices=["Michelin Guide", "Google", "Yelp"],
value="Yelp",
multiselect=True,
label="Data Source",
info="Select restaurant data source"
)
with gr.Row():
with gr.Column(scale=1):
num_results = gr.Slider(
minimum=5,
maximum=30,
value=10,
step=5,
label="Results"
)
search_btn = gr.Button("Search Restaurants", variant="primary", size="lg")
with gr.Row():
with gr.Column(scale=1):
results_output = gr.Textbox(
label="Restaurant Results",
lines=20,
max_lines=30
)
with gr.Column(scale=1):
map_output = gr.HTML(
label="Paris Map"
)
gr.Markdown("### Try These Examples:")
examples = [
["Italian pasta", "Yelp", 10],
["sushi", "Michelin Guide", 10],
["romantic dinner", "Google", 8],
["family-friendly pizza", "Yelp", 10],
["best seafood", "Michelin Guide", 10],
["cheap burger", "Google", 10]
]
gr.Examples(
examples=examples,
inputs=[query_input, data_source, num_results]
)
search_btn.click(
fn=search_restaurants,
inputs=[query_input, data_source, num_results],
outputs=[results_output, map_output]
)
query_input.submit(
fn=search_restaurants,
inputs=[query_input, data_source, num_results],
outputs=[results_output, map_output]
)
if __name__ == "__main__":
print("\nStarting Advanced Restaurant Finder...")
print(f"{len(data)} restaurants ready to search")
print("Opening at http://127.0.0.1:7860\n")
# # if run locally
# app.launch(share=False, server_name="127.0.0.1", server_port=7860, inbrowser=True)
# if run on HF Space
app.launch(ssr_mode=False)