nniehaus commited on
Commit
2199ab8
·
verified ·
1 Parent(s): 2913e9e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -113
app.py CHANGED
@@ -1,154 +1,133 @@
1
  import streamlit as st
2
  import requests
3
  from bs4 import BeautifulSoup
4
- import os
 
5
  import re
6
- from deepseek_api import DeepSeek # Replace with actual Deepseek SDK
 
 
 
7
 
8
- # Configure Deepseek API
9
- DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")
10
- ds = DeepSeek(api_key=DEEPSEEK_API_KEY)
11
 
12
- def search_neighborhood_data(query):
13
- """Search for neighborhood information across various sources"""
 
 
14
  sources = {
15
  "Niche": f"https://www.niche.com/places-to-live/search/{query}",
16
  "AreaVibes": f"https://www.areavibes.com/search/?query={query}",
17
- "Walkscore": f"https://www.walkscore.com/score/{query}"
18
  }
19
 
20
- results = {}
21
  for source, url in sources.items():
22
  try:
23
- response = requests.get(url, timeout=10)
24
  soup = BeautifulSoup(response.text, 'html.parser')
25
 
26
  if source == "Niche":
27
  listings = soup.find_all('div', class_='search-results__list__item')
28
- results[source] = [{
29
- 'name': item.find('h2').text.strip(),
30
- 'details': item.find('div', class_='search-result-tagline').text.strip(),
31
- 'score': item.find('div', class_='search-result-grade').text.strip()
32
- } for item in listings[:3]]
33
-
34
- elif source == "AreaVibes":
35
- # Similar parsing for other sources
36
- ...
37
-
38
  except Exception as e:
39
  continue
40
 
41
  return results
42
 
43
- def analyze_preferences(preferences):
44
- """Use Deepseek to analyze user preferences and generate search parameters"""
45
- prompt = f"""
46
- User preferences: {preferences}
47
- Generate search parameters for neighborhood hunting considering:
48
- - Key demographic factors
49
- - Important amenities
50
- - Commute considerations
51
- - Lifestyle priorities
52
- - Budget constraints
53
- """
54
-
55
- response = ds.generate(
56
- model="neighborhood-matcher",
57
- prompt=prompt,
58
- max_tokens=500
59
- )
60
- return response['choices'][0]['text']
61
-
62
- def generate_recommendations(criteria, locations):
63
- """Generate neighborhood recommendations with Deepseek's analysis"""
64
- base_prompt = f"""
65
- Based on these verified neighborhood data:
66
- {locations}
67
 
68
- And user criteria:
69
- {criteria}
 
70
 
71
- Create 5 recommendations including:
72
- 1. Best overall match
73
- 2. Best value option
74
- 3. Best for families
75
- 4. Best for young professionals
76
- 5. 'Outside the Box' option (creative suggestion)
77
 
78
- For each include:
79
- - Key strengths
80
- - Potential drawbacks
81
- - Notable amenities
82
- - Average home prices
83
- - Commute times
84
- - Unique character
85
  """
86
 
87
- response = ds.generate(
88
- model="neighborhood-matcher",
89
- prompt=base_prompt,
90
- max_tokens=1500,
91
- temperature=0.7
92
- )
93
- return response['choices'][0]['text']
 
 
 
 
 
 
 
 
 
94
 
95
  # Streamlit UI
96
- st.set_page_config(layout="wide")
97
- st.title("🏡 Neighborhood Matchmaker")
98
 
99
- with st.expander("🔍 Your Lifestyle Preferences"):
100
- col1, col2 = st.columns(2)
101
- with col1:
102
- budget = st.slider("Monthly Housing Budget ($)", 1000, 10000, 3000)
103
- commute = st.selectbox("Max Commute Time", ["15 mins", "30 mins", "45 mins", "1 hour"])
104
- amenities = st.multiselect("Must-Have Amenities", [
105
- "Good Schools", "Parks", "Public Transport",
106
- "Nightlife", "Shopping Centers", "Healthcare"
107
- ])
108
-
109
- with col2:
110
- lifestyle = st.selectbox("Primary Lifestyle", [
111
- "Family-Friendly", "Urban Professional", "Retirement",
112
- "Student", "Remote Worker", "Outdoor Enthusiast"
113
- ])
114
- safety = st.slider("Safety Priority (1-10)", 1, 10, 8)
115
- extra = st.text_input("Special Requirements", placeholder="e.g., Dog parks, historic district")
116
 
117
- # Generate recommendations
118
- if st.button("Find My Perfect Neighborhood"):
119
- with st.spinner("Analyzing preferences and searching neighborhoods..."):
120
  # Collect preferences
121
  preferences = {
122
- "budget": budget,
123
- "commute": commute,
 
124
  "amenities": amenities,
125
- "lifestyle": lifestyle,
126
- "safety": safety,
127
- "extra": extra
128
  }
129
 
130
- # Analyze preferences with AI
131
- search_params = analyze_preferences(preferences)
132
 
133
- # Search for matching locations
134
- location_data = search_neighborhood_data(search_params)
135
-
136
- # Generate final recommendations
137
- recommendations = generate_recommendations(preferences, location_data)
138
 
139
  # Display results
140
- st.subheader("Your Custom Neighborhood Recommendations")
141
- st.markdown(recommendations)
142
-
143
- # Always include an "outside the box" suggestion
144
- st.subheader("🚀 Outside the Box Option")
145
- st.markdown("""**Emerging Neighborhood - Innovation District**
146
- *Why we suggest it:*
147
- - Up-and-coming tech hub with new amenities
148
- - Lower prices before expected growth
149
- - Community development initiatives
150
- *Consider if:* You want to get in early on a growing area""")
 
151
 
152
- # Disclaimer
153
  st.markdown("---")
154
- st.caption("Recommendations are AI-generated and should be verified with local experts.")
 
1
  import streamlit as st
2
  import requests
3
  from bs4 import BeautifulSoup
4
+ from geopy.geocoders import Nominatim
5
+ from urllib.parse import urljoin, urlparse
6
  import re
7
+ import os
8
+ import pandas as pd
9
+ import folium
10
+ from streamlit_folium import folium_static
11
 
12
+ # Configure environment
13
+ DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_KEY")
14
+ API_ENDPOINT = "https://api.deepseek.com/v1/chat/completions"
15
 
16
+ # Cache expensive operations
17
+ @st.cache_data
18
+ def scrape_location_data(query):
19
+ """Scrape location data from public sources"""
20
  sources = {
21
  "Niche": f"https://www.niche.com/places-to-live/search/{query}",
22
  "AreaVibes": f"https://www.areavibes.com/search/?query={query}",
 
23
  }
24
 
25
+ results = []
26
  for source, url in sources.items():
27
  try:
28
+ response = requests.get(url, timeout=15)
29
  soup = BeautifulSoup(response.text, 'html.parser')
30
 
31
  if source == "Niche":
32
  listings = soup.find_all('div', class_='search-results__list__item')
33
+ for item in listings[:3]:
34
+ results.append({
35
+ 'name': item.find('h2').text.strip(),
36
+ 'details': item.find('div', class_='search-result-tagline').text.strip(),
37
+ 'score': item.find('div', class_='search-result-grade').text.strip()
38
+ })
39
+
 
 
 
40
  except Exception as e:
41
  continue
42
 
43
  return results
44
 
45
+ def generate_recommendations(preferences):
46
+ """Generate neighborhood recommendations using Deepseek API"""
47
+ headers = {
48
+ "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
49
+ "Content-Type": "application/json"
50
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
+ prompt = f"""
53
+ Create a neighborhood recommendation report based on these preferences:
54
+ {preferences}
55
 
56
+ Include these sections:
57
+ 1. Top 5 Neighborhood Matches
58
+ 2. Hidden Gem Recommendation
59
+ 3. Key Amenities Analysis
60
+ 4. Commute Times Overview
61
+ 5. Safety & Community Insights
62
 
63
+ Format with markdown headers and bullet points. Keep sections concise.
 
 
 
 
 
 
64
  """
65
 
66
+ try:
67
+ response = requests.post(
68
+ API_ENDPOINT,
69
+ json={
70
+ "model": "deepseek-chat",
71
+ "messages": [{"role": "user", "content": prompt}],
72
+ "temperature": 0.7,
73
+ "max_tokens": 1500
74
+ },
75
+ headers=headers,
76
+ timeout=30
77
+ )
78
+ return response.json()["choices"][0]["message"]["content"]
79
+ except Exception as e:
80
+ st.error(f"API Error: {str(e)}")
81
+ return None
82
 
83
  # Streamlit UI
84
+ st.set_page_config(layout="wide", page_icon="🏡")
85
+ st.title("Neighborhood Matchmaker")
86
 
87
+ with st.sidebar:
88
+ st.header("Search Preferences")
89
+ city = st.text_input("City/Region", "New York, NY")
90
+ budget = st.slider("Monthly Housing Budget ($)", 1000, 10000, 3000)
91
+ commute = st.selectbox("Max Commute Time", ["15 mins", "30 mins", "45 mins", "1 hour"])
92
+ amenities = st.multiselect("Must-Have Amenities", [
93
+ "Good Schools", "Parks", "Public Transport",
94
+ "Nightlife", "Shopping", "Healthcare"
95
+ ])
96
+ lifestyle = st.selectbox("Lifestyle Preference", [
97
+ "Family-Friendly", "Urban Professional", "Retirement",
98
+ "Student", "Remote Worker", "Outdoor Enthusiast"
99
+ ])
 
 
 
 
100
 
101
+ if st.button("Find My Neighborhood"):
102
+ with st.spinner("Analyzing locations..."):
 
103
  # Collect preferences
104
  preferences = {
105
+ "city": city,
106
+ "budget": f"${budget}/mo",
107
+ "max_commute": commute,
108
  "amenities": amenities,
109
+ "lifestyle": lifestyle
 
 
110
  }
111
 
112
+ # Get location data
113
+ location_data = scrape_location_data(city)
114
 
115
+ # Generate recommendations
116
+ report = generate_recommendations(preferences)
 
 
 
117
 
118
  # Display results
119
+ if report:
120
+ st.subheader("Your Personalized Neighborhood Report")
121
+ st.markdown(report)
122
+
123
+ # Show map
124
+ try:
125
+ geolocator = Nominatim(user_agent="neighborhood_finder")
126
+ location = geolocator.geocode(city)
127
+ m = folium.Map(location=[location.latitude, location.longitude], zoom_start=12)
128
+ folium_static(m, width=1200, height=500)
129
+ except Exception as e:
130
+ st.warning("Couldn't generate map visualization")
131
 
 
132
  st.markdown("---")
133
+ st.caption("Note: Recommendations generated by AI. Verify with local experts.")