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 += "

Here are your results

" response_html += "
" for score, car_description, car_info in high_score_results: response_html += "
" response_html += f"" response_html += f"

{car_info.get('title')}

" response_html += f"

Price: {car_info.get('price')}

" response_html += f"

Status: {car_info.get('status')}

" response_html += f"

Body Type: {car_info.get('BodyType')}

" response_html += f"

Year: {car_info.get('year')}

" response_html += f"

Mileage: {car_info.get('Mileage')}

" response_html += f"

Location: {car_info.get('location')}

" response_html += f"View Listing" response_html += f"

Similarity Score: {score:.4f}

" response_html += "
" response_html += "
" # Low score results cards if low_score_results: response_html += "

Some more results you might be interested in

" response_html += "
" for score, car_description, car_info in low_score_results: response_html += "
" response_html += f"" response_html += f"

{car_info.get('title')}

" response_html += f"

Price: {car_info.get('price')}

" response_html += f"

Status: {car_info.get('status')}

" response_html += f"

Body Type: {car_info.get('BodyType')}

" response_html += f"

Year: {car_info.get('year')}

" response_html += f"

Mileage: {car_info.get('Mileage')}

" response_html += f"

Location: {car_info.get('location')}

" response_html += f"View Listing" response_html += f"

Similarity Score: {score:.4f}

" response_html += "
" response_html += "
" 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()