import streamlit as st
import wikipedia
import re
from functools import lru_cache
import time
# Configure page
st.set_page_config(
page_title="Car Categories Explorer",
layout="centered",
page_icon="🚗"
)
# Custom CSS for better styling
st.markdown("""
""", unsafe_allow_html=True)
st.markdown('
🚗 Car Categories Explorer
', unsafe_allow_html=True)
# --- Initialize session state ---
if 'search_history' not in st.session_state:
st.session_state.search_history = []
if 'favorites' not in st.session_state:
st.session_state.favorites = []
# --- Sidebar Configuration ---
st.sidebar.header("🚘 Car Categories")
# Category selection with descriptions
categories = {
"Vintage Cars": {
"description": "Classic automobiles from bygone eras",
"examples": ["Ford Model T", "Jaguar E-Type", "Rolls-Royce Silver Ghost", "Chevrolet Bel Air"]
},
"Trending Cars": {
"description": "Popular modern vehicles",
"examples": ["Tesla Model S", "Hyundai Exter", "Mahindra Thar", "Toyota Camry"]
},
"SUVs": {
"description": "Sport Utility Vehicles",
"examples": ["Tata Harrier", "Jeep Compass", "Hyundai Creta", "Ford EcoSport"]
},
"Electric Cars": {
"description": "Eco-friendly electric vehicles",
"examples": ["Tesla Model 3", "Nissan Leaf", "Tata Nexon EV", "BMW i3"]
}
}
category = st.sidebar.selectbox("Choose a Category", list(categories.keys()))
# Display category info
st.sidebar.markdown(f"**{categories[category]['description']}**")
st.sidebar.markdown("#### 💡 Example Cars:")
for example in categories[category]['examples']:
st.sidebar.markdown(f"- {example}")
# Search history in sidebar
if st.session_state.search_history:
st.sidebar.markdown("#### 🕐 Recent Searches:")
for item in st.session_state.search_history[-5:]: # Show last 5 searches
if st.sidebar.button(f"🔍 {item}", key=f"history_{item}"):
st.session_state.current_search = item
# --- Caching Functions ---
@lru_cache(maxsize=100)
def cached_wikipedia_search(query):
"""Cache Wikipedia search results to avoid repeated API calls"""
try:
if len(query.strip()) < 3:
return []
return wikipedia.search(query, results=10)
except Exception as e:
st.error(f"Search error: {str(e)}")
return []
@lru_cache(maxsize=50)
def cached_wikipedia_page(car_name):
"""Cache Wikipedia page content"""
try:
# Set language to English for better car results
wikipedia.set_lang("en")
page = wikipedia.page(car_name)
summary = wikipedia.summary(car_name, sentences=8)
# Clean summary
clean_summary = re.sub(r'\[\d+\]', '', summary)
clean_summary = re.sub(r'\s+', ' ', clean_summary).strip()
# Get first valid image
image_url = None
if page.images:
for img in page.images[:3]: # Try first 3 images
if any(ext in img.lower() for ext in ['.jpg', '.jpeg', '.png', '.gif']):
image_url = img
break
return clean_summary, image_url, page.url, page.title
except wikipedia.exceptions.DisambiguationError as e:
# Handle disambiguation by trying the first option
try:
return cached_wikipedia_page(e.options[0])
except:
return None, None, None, None
except wikipedia.exceptions.PageError:
return None, None, None, None
except Exception as e:
st.error(f"Error fetching page: {str(e)}")
return None, None, None, None
def smart_search_cars(query, category):
"""Enhanced search with category-specific terms"""
if not query.strip():
return []
# Add category context to search
category_terms = {
"Vintage Cars": ["vintage", "classic", "antique"],
"Trending Cars": ["2023", "2024", "new", "latest"],
"SUVs": ["SUV", "crossover"],
"Electric Cars": ["electric", "EV", "hybrid"]
}
# Try exact search first
results = cached_wikipedia_search(query)
# If few results, try with category context
if len(results) < 3:
enhanced_query = f"{query} {category_terms.get(category, [''])[0]}"
enhanced_results = cached_wikipedia_search(enhanced_query)
results.extend([r for r in enhanced_results if r not in results])
return results[:10] # Limit to 10 results
# --- Main Search Interface ---
st.markdown(f"### 🔍 Search Cars in {category}")
# Search input with debouncing
search_container = st.container()
with search_container:
col1, col2 = st.columns([3, 1])
with col1:
query = st.text_input(
"Type a Car Name",
placeholder="e.g., Tesla Model S, Ford Mustang",
key="search_input"
)
with col2:
st.markdown("
", unsafe_allow_html=True) # Add spacing
clear_btn = st.button("🗑️ Clear", help="Clear search")
if clear_btn:
st.rerun()
# Live suggestions with improved logic
suggestions = []
if query and len(query.strip()) >= 3:
with st.spinner("Searching..."):
suggestions = smart_search_cars(query, category)
# Display suggestions
if suggestions:
selected_car = st.selectbox("🔎 Select from suggestions:", [""] + suggestions)
else:
selected_car = None
# Search button
submit_btn = st.button("🚘 Get Car Information", type="primary")
# --- Display Results ---
if submit_btn and selected_car:
# Add to search history
if selected_car not in st.session_state.search_history:
st.session_state.search_history.append(selected_car)
st.markdown("---")
# Progress bar for better UX
progress_bar = st.progress(0)
status_text = st.empty()
status_text.text("Fetching car information...")
progress_bar.progress(25)
# Fetch car information
summary, image_url, page_url, page_title = cached_wikipedia_page(selected_car)
progress_bar.progress(75)
if summary:
# Display main car info
st.markdown(f'', unsafe_allow_html=True)
# Title with favorite button
col1, col2 = st.columns([4, 1])
with col1:
st.subheader(f"📄 {page_title or selected_car}")
with col2:
if st.button("⭐ Favorite", key=f"fav_{selected_car}"):
if selected_car not in st.session_state.favorites:
st.session_state.favorites.append(selected_car)
st.success("Added to favorites!")
# Display image and summary
if image_url:
try:
st.image(image_url, caption=page_title or selected_car, use_column_width=True)
except:
st.info("📷 Image could not be loaded")
st.write(summary)
# Links and actions
col1, col2, col3 = st.columns(3)
with col1:
if page_url:
st.markdown(f"[🔗 Wikipedia Page]({page_url})")
with col2:
if st.button("🔄 Search Similar", key=f"similar_{selected_car}"):
# Extract brand name for similar search
brand = selected_car.split()[0]
similar_results = cached_wikipedia_search(f"{brand} cars")
if similar_results:
st.info(f"Similar cars: {', '.join(similar_results[:3])}")
with col3:
if st.button("📤 Share", key=f"share_{selected_car}"):
st.code(f"Check out this car: {selected_car}\n{page_url}")
st.markdown('
', unsafe_allow_html=True)
progress_bar.progress(100)
status_text.text("✅ Information loaded successfully!")
# Clear progress indicators after 2 seconds
time.sleep(1)
progress_bar.empty()
status_text.empty()
else:
progress_bar.progress(100)
status_text.empty()
progress_bar.empty()
st.markdown('❌ No information found for this car.
', unsafe_allow_html=True)
st.info("💡 Try searching with a different spelling or check the suggestions above.")
# --- Favorites Section ---
if st.session_state.favorites:
st.markdown("---")
st.subheader("⭐ Your Favorite Cars")
for i, fav in enumerate(st.session_state.favorites):
col1, col2 = st.columns([4, 1])
with col1:
st.write(f"🚗 {fav}")
with col2:
if st.button("🗑️", key=f"remove_{i}", help="Remove from favorites"):
st.session_state.favorites.remove(fav)
st.rerun()
# --- Footer ---
st.markdown("---")
st.markdown("""
🚗 Car Categories Explorer | Powered by Wikipedia API
Data provided by Wikipedia. Images and content are subject to their respective licenses.
""", unsafe_allow_html=True)