|
import streamlit as st |
|
import requests |
|
from streamlit_folium import st_folium |
|
import folium |
|
from langchain_nvidia_ai_endpoints import ChatNVIDIA |
|
|
|
# Google Maps API key with Places scope |
|
GOOGLE_MAPS_API_KEY = "" |
|
|
|
# https://build.nvidia.com/ |
|
NVIDIA_API_KEY = "" |
|
|
|
|
|
llm = ChatNVIDIA(api_key=NVIDIA_API_KEY, model="meta/llama-3.3-70b-instruct") |
|
|
|
|
|
def get_google_reviews(place_id): |
|
"""Fetches reviews for a shop using its Place ID.""" |
|
url = f"https://maps.googleapis.com/maps/api/place/details/json?place_id={place_id}&fields=reviews,url&key={GOOGLE_MAPS_API_KEY}" |
|
response = requests.get(url) |
|
data = response.json() |
|
|
|
if data["status"] == "OK": |
|
reviews = data["result"].get("reviews", []) |
|
return reviews |
|
else: |
|
print("No reviews found for the given place ID.") |
|
return [], None |
|
|
|
|
|
def get_coffee_shop_review_text(place_id, shop): |
|
reviews = get_google_reviews(place_id) |
|
reviews_text = [r["text"] for r in reviews] |
|
return f"\n\n {shop.title()} REVIEWS: \n \n".join(reviews_text) |
|
|
|
|
|
def get_coordinates(address): |
|
url = f"https://maps.googleapis.com/maps/api/geocode/json?address={address}&key={GOOGLE_MAPS_API_KEY}" |
|
response = requests.get(url) |
|
data = response.json() |
|
|
|
if data["status"] == "OK": |
|
location = data["results"][0]["geometry"]["location"] |
|
return location["lat"], location["lng"] |
|
else: |
|
st.error("Unable to get coordinates for the provided address.") |
|
return None, None |
|
|
|
|
|
def find_nearby_coffee_shops(lat, lng): |
|
url = f"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={lat},{lng}&radius=1500&type=cafe&key={GOOGLE_MAPS_API_KEY}" |
|
response = requests.get(url) |
|
data = response.json() |
|
|
|
if data["status"] == "OK": |
|
coffee_shops = [] |
|
for place in data["results"][:3]: # Limit to 3 shops |
|
coffee_shops.append( |
|
{ |
|
"name": place["name"], |
|
"lat": place["geometry"]["location"]["lat"], |
|
"lng": place["geometry"]["location"]["lng"], |
|
"placeid": place["place_id"], |
|
} |
|
) |
|
return coffee_shops |
|
else: |
|
st.error("Unable to find nearby coffee shops.") |
|
return [] |
|
|
|
|
|
def ask_llm(reviews): |
|
prompt = f""" |
|
Please recommend a coffee shop based on the following reviews. |
|
|
|
REVIEWS |
|
|
|
{reviews} |
|
|
|
Format your response as |
|
Recommendation: |
|
Alternatives Considered: |
|
|
|
In the recommendation include a brief reason why. For each alternative include a brief reason why not. |
|
""" |
|
response = llm.invoke(prompt) |
|
return response.content |
|
|
|
|
|
# Streamlit App |
|
st.set_page_config(layout="wide") |
|
if "clicked" not in st.session_state: |
|
st.session_state.clicked = False |
|
|
|
|
|
def lookup(): |
|
st.session_state.clicked = True |
|
|
|
|
|
st.title("Find Your Perfect Coffee Spot") |
|
col1, col2 = st.columns(2) |
|
|
|
with col1: |
|
# User Input |
|
address = st.text_input("Enter your address") |
|
st.button("Locate Coffee Shops", on_click=lookup) |
|
|
|
if st.session_state.clicked: |
|
if address: |
|
lat, lng = get_coordinates(address) |
|
|
|
if lat and lng: |
|
coffee_shops = find_nearby_coffee_shops(lat, lng) |
|
|
|
# Display map |
|
map_ = folium.Map(location=[lat, lng], zoom_start=15) |
|
folium.Marker( |
|
[lat, lng], popup="Your Location", icon=folium.Icon(color="blue") |
|
).add_to(map_) |
|
|
|
for shop in coffee_shops: |
|
folium.Marker( |
|
[shop["lat"], shop["lng"]], |
|
popup=shop["name"], |
|
icon=folium.Icon(color="green"), |
|
).add_to(map_) |
|
|
|
st_folium(map_, width=700, height=500) |
|
|
|
|
|
with col2: |
|
if st.session_state.clicked: |
|
st.subheader("Nearby Coffee Shop Reviews & AI Recommendation") |
|
review_texts = [ |
|
get_coffee_shop_review_text(shop["placeid"], shop["name"]) |
|
for shop in coffee_shops |
|
] |
|
review_text = "\n\n".join(review_texts) |
|
|
|
tab1, tab2 = st.tabs(["Recommendation", "Raw Reviews"]) |
|
|
|
with tab1: |
|
st.text(ask_llm(review_text)) |
|
with tab2: |
|
st.text(review_text) |
|
|
|
else: |
|
st.error("Please enter an address.") |
|
|
|
# used for debugging |
|
if __name__ == "__main__": |
|
address = "1001 soda creek rd evergreen co 80439" |
|
lat, lng = get_coordinates(address) |
|
coffee_shops = find_nearby_coffee_shops(lat, lng) |
|
review_texts = [ |
|
get_coffee_shop_review_text(shop["placeid"], shop["name"]) |
|
for shop in coffee_shops |
|
] |