AISearch / app.py
IAMTFRMZA's picture
Update app.py
0fcdf48 verified
Raw
History Blame Contribute Delete
6.02 kB
import requests
from bs4 import BeautifulSoup
import json
import os
import gradio as gr
from sentence_transformers import SentenceTransformer, util
# Load the car data
with open('car_dataformatted.json', 'r') as f:
car_data = json.load(f)
# Function to normalize key names
def normalize_key(key):
return key.strip().lower().replace(' ', '_')
# Prepare car listings with additional fields
car_listings = []
for car in car_data:
description = f"{car.get('title')} - {car.get('price')} - {car.get('status')} - {car.get('link')} - {car.get('year')} - {car.get('location')} - {car.get('image_url')} - {car.get('mileage')} - {car.get('BodyType')} - {car.get('colour')} - {car.get('DrivingWheels')} - {car.get('EngineSize')} - {car.get('FuelType')} - {car.get('GearboxType')} - {car.get('power')} - {car.get('seats')}"
car_listings.append(description.strip())
# Load a pre-trained Sentence Transformer model
model_name = 'paraphrase-MiniLM-L6-v2'
model = SentenceTransformer(model_name)
# Vectorize the car listings
car_embeddings = model.encode(car_listings, convert_to_tensor=True)
def search_cars(query):
# Vectorize the query
query_embedding = model.encode(query, convert_to_tensor=True)
# Calculate cosine similarity between the query and each car listing
cos_scores = util.pytorch_cos_sim(query_embedding, car_embeddings)[0]
# Normalize query to lower case and remove spaces for comparison
query_normalized = query.replace(" ", "").lower()
# Adjust boost logic and thresholds
boosted_scores = []
for score, car in zip(cos_scores, car_data):
boost = 0
# Normalize fields for comparison
normalized_fields = {normalize_key(field): car.get(field, '').replace(" ", "").lower() for field in ['title', 'price', 'status', 'year', 'location']}
# Check if query term is in any relevant field
if any(query_normalized in normalized_fields[field] for field in normalized_fields):
boost = 0.8 # Increase boost for better differentiation
boosted_scores.append(score.item() + boost)
# Combine the scores with their respective car descriptions and sort
results = list(zip(boosted_scores, car_listings, car_data))
results = sorted(results, key=lambda x: x[0], reverse=True)
# Separate results into two tables based on the score threshold
high_score_results = [r for r in results if r[0] >= 0.5] # Adjust threshold as needed
low_score_results = [r for r in results if 0.1 <= r[0] < 0.5] # Adjust lower score threshold
# Format results for display as cards
response_html = ""
# High score results cards
if high_score_results:
response_html += "<h2>Here are your results</h2>"
response_html += "<div style='display:flex; flex-wrap:wrap;'>"
for score, car_description, car_info in high_score_results:
response_html += "<div style='border: 1px solid #ddd; border-radius: 5px; padding: 10px; margin: 10px; width: 300px;'>"
response_html += f"<img src='{car_info.get('image_url')}' width='100' style='float:left; margin-right: 10px;'>"
response_html += f"<h3>{car_info.get('title')}</h3>"
response_html += f"<p><b>Price:</b> {car_info.get('price')}</p>"
response_html += f"<p><b>Status:</b> {car_info.get('status')}</p>"
response_html += f"<p><b>Body Type:</b> {car_info.get('BodyType')}</p>"
response_html += f"<p><b>Year:</b> {car_info.get('year')}</p>"
response_html += f"<p><b>Mileage:</b> {car_info.get('Mileage')}</p>"
response_html += f"<p><b>Location:</b> {car_info.get('location')}</p>"
response_html += f"<a href='{car_info.get('link')}' target='_blank'>View Listing</a>"
response_html += f"<p><b>Similarity Score:</b> {score:.4f}</p>"
response_html += "</div>"
response_html += "</div>"
# Low score results cards
if low_score_results:
response_html += "<h2>Some more results you might be interested in</h2>"
response_html += "<div style='display:flex; flex-wrap:wrap;'>"
for score, car_description, car_info in low_score_results:
response_html += "<div style='border: 1px solid #ddd; border-radius: 5px; padding: 10px; margin: 10px; width: 300px;'>"
response_html += f"<img src='{car_info.get('image_url')}' width='100' style='float:left; margin-right: 10px;'>"
response_html += f"<h3>{car_info.get('title')}</h3>"
response_html += f"<p><b>Price:</b> {car_info.get('price')}</p>"
response_html += f"<p><b>Status:</b> {car_info.get('status')}</p>"
response_html += f"<p><b>Body Type:</b> {car_info.get('BodyType')}</p>"
response_html += f"<p><b>Year:</b> {car_info.get('year')}</p>"
response_html += f"<p><b>Mileage:</b> {car_info.get('Mileage')}</p>"
response_html += f"<p><b>Location:</b> {car_info.get('location')}</p>"
response_html += f"<a href='{car_info.get('link')}' target='_blank' style='text-decoration:none; color:#333; background-color:#f0f0f0; padding:8px 12px; border-radius:4px; margin-right: 10px;'>View Listing</a>"
response_html += f"<p><b>Similarity Score:</b> {score:.4f}</p>"
response_html += "</div>"
response_html += "</div>"
return response_html
# Create a chat interface using Gradio's Blocks
def create_chat_interface():
with gr.Blocks(theme=gr.themes.Monochrome(), fill_height=True) as demo:
with gr.Row():
gr.Markdown("## Ai Search")
with gr.Row():
query_input = gr.Textbox(label="What are you looking for?", placeholder="Please type your query here")
with gr.Row():
output_html = gr.HTML(label="Search Results")
query_input.change(fn=search_cars, inputs=query_input, outputs=output_html)
return demo
# Launch the chat interface
demo = create_chat_interface()
demo.launch()