Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import requests | |
| from bs4 import BeautifulSoup | |
| from geopy.geocoders import Nominatim | |
| from urllib.parse import urljoin, urlparse | |
| import re | |
| import os | |
| import pandas as pd | |
| import folium | |
| from streamlit_folium import folium_static | |
| # Configure environment | |
| DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_KEY") | |
| API_ENDPOINT = "https://api.deepseek.com/v1/chat/completions" | |
| # Cache expensive operations | |
| def scrape_location_data(query): | |
| """Scrape location data from public sources""" | |
| sources = { | |
| "Niche": f"https://www.niche.com/places-to-live/search/{query}", | |
| "AreaVibes": f"https://www.areavibes.com/search/?query={query}", | |
| } | |
| results = [] | |
| for source, url in sources.items(): | |
| try: | |
| response = requests.get(url, timeout=15) | |
| soup = BeautifulSoup(response.text, 'html.parser') | |
| if source == "Niche": | |
| listings = soup.find_all('div', class_='search-results__list__item') | |
| for item in listings[:3]: | |
| results.append({ | |
| 'name': item.find('h2').text.strip(), | |
| 'details': item.find('div', class_='search-result-tagline').text.strip(), | |
| 'score': item.find('div', class_='search-result-grade').text.strip() | |
| }) | |
| except Exception as e: | |
| continue | |
| return results | |
| def generate_recommendations(preferences): | |
| """Generate neighborhood recommendations using Deepseek API""" | |
| headers = { | |
| "Authorization": f"Bearer {DEEPSEEK_API_KEY}", | |
| "Content-Type": "application/json" | |
| } | |
| prompt = f""" | |
| Create a neighborhood recommendation report based on these preferences: | |
| {preferences} | |
| Include these sections: | |
| 1. Top 5 Neighborhood Matches | |
| 2. Hidden Gem Recommendation | |
| 3. Key Amenities Analysis | |
| 4. Commute Times Overview | |
| 5. Safety & Community Insights | |
| Format with markdown headers and bullet points. Keep sections concise. | |
| """ | |
| try: | |
| response = requests.post( | |
| API_ENDPOINT, | |
| json={ | |
| "model": "deepseek-chat", | |
| "messages": [{"role": "user", "content": prompt}], | |
| "temperature": 0.7, | |
| "max_tokens": 1500 | |
| }, | |
| headers=headers, | |
| timeout=30 | |
| ) | |
| return response.json()["choices"][0]["message"]["content"] | |
| except Exception as e: | |
| st.error(f"API Error: {str(e)}") | |
| return None | |
| # Streamlit UI | |
| st.set_page_config(layout="wide", page_icon="🏡") | |
| st.title("Neighborhood Matchmaker") | |
| with st.sidebar: | |
| st.header("Search Preferences") | |
| city = st.text_input("City/Region", "New York, NY") | |
| budget = st.slider("Monthly Housing Budget ($)", 1000, 10000, 3000) | |
| commute = st.selectbox("Max Commute Time", ["15 mins", "30 mins", "45 mins", "1 hour"]) | |
| amenities = st.multiselect("Must-Have Amenities", [ | |
| "Good Schools", "Parks", "Public Transport", | |
| "Nightlife", "Shopping", "Healthcare" | |
| ]) | |
| lifestyle = st.selectbox("Lifestyle Preference", [ | |
| "Family-Friendly", "Urban Professional", "Retirement", | |
| "Student", "Remote Worker", "Outdoor Enthusiast" | |
| ]) | |
| if st.button("Find My Neighborhood"): | |
| with st.spinner("Analyzing locations..."): | |
| # Collect preferences | |
| preferences = { | |
| "city": city, | |
| "budget": f"${budget}/mo", | |
| "max_commute": commute, | |
| "amenities": amenities, | |
| "lifestyle": lifestyle | |
| } | |
| # Get location data | |
| location_data = scrape_location_data(city) | |
| # Generate recommendations | |
| report = generate_recommendations(preferences) | |
| # Display results | |
| if report: | |
| st.subheader("Your Personalized Neighborhood Report") | |
| st.markdown(report) | |
| # Show map | |
| try: | |
| geolocator = Nominatim(user_agent="neighborhood_finder") | |
| location = geolocator.geocode(city) | |
| m = folium.Map(location=[location.latitude, location.longitude], zoom_start=12) | |
| folium_static(m, width=1200, height=500) | |
| except Exception as e: | |
| st.warning("Couldn't generate map visualization") | |
| st.markdown("---") | |
| st.caption("Note: Recommendations generated by AI. Verify with local experts.") |