brian-yu-nexusflow commited on
Commit
6db0fcc
Β·
1 Parent(s): 63b3c15

Update tools.py

Browse files
Files changed (1) hide show
  1. tools.py +59 -21
tools.py CHANGED
@@ -2,8 +2,10 @@
2
  These are all the tools used in the NexusRaven V2 demo! You can provide any tools you want to Raven.
3
 
4
  Nothing in this file is specific to Raven, code/information related to Raven can be found in the `raven_demo.py` file.
 
 
5
  """
6
- from typing import Dict, List, Union
7
 
8
  from math import radians, cos, sin, asin, sqrt
9
 
@@ -23,6 +25,12 @@ class Tools:
23
  self.gmaps = Client(config.gmaps_client_key)
24
  self.client_ip: str | None = None
25
 
 
 
 
 
 
 
26
  def haversine(self, lon1, lat1, lon2, lat2) -> float:
27
  """
28
  Calculate the great circle distance in kilometers between two points on the earth (specified in decimal degrees).
@@ -52,7 +60,9 @@ class Tools:
52
  except:
53
  return "San Francisco, California, US"
54
 
55
- def sort_results(self, places : list, sort: str, descending: bool = True, first_n : int = None) -> List:
 
 
56
  """
57
  Sorts the results by either 'distance', 'rating' or 'price'.
58
 
@@ -60,7 +70,7 @@ class Tools:
60
  - sort (str): If set, sorts by either 'distance' or 'rating' or 'price'. ONLY supports 'distance' or 'rating' or 'price'.
61
  - descending (bool): If descending is set, setting this boolean to true will sort the results such that the highest values are first.
62
  - first_n (int): If provided, only retains the first n items in the final sorted list.
63
-
64
  When people ask for 'closest' or 'nearest', sort by 'distance'.
65
  When people ask for 'cheapest' or 'most expensive', sort by 'price'.
66
  When people ask for 'best' or 'highest rated', sort by rating.
@@ -88,7 +98,13 @@ class Tools:
88
 
89
  - location: This can be a city like 'Austin', or a place like 'Austin Airport', etc.
90
  """
91
- return self.gmaps.geocode(location)
 
 
 
 
 
 
92
 
93
  def get_distance(self, place_1: str, place_2: str):
94
  """
@@ -101,30 +117,41 @@ class Tools:
101
  """
102
  if isinstance(place_1, list) and len(place_1) > 0:
103
  place_1 = place_1[0]
104
-
105
  if isinstance(place_2, list) and len(place_2) > 0:
106
  place_2 = place_2[0]
107
 
108
- latlong_1 = self.get_latitude_longitude(place_1)
109
- latlong_2 = self.get_latitude_longitude(place_2)
110
-
111
  if isinstance(place_1, dict):
112
- place_1 = place_1["name"]
113
  if isinstance(place_2, dict):
114
- place_2 = place_2["name"]
115
 
116
- if len(latlong_1) == 0 or len(latlong_2) == 0:
117
- return "No place found for the query. Please be more explicit."
 
118
 
119
- latlong1 = latlong_1[0]["geometry"]["location"]
120
- latlong2 = latlong_2[0]["geometry"]["location"]
 
 
 
 
 
 
 
121
 
122
  dist = self.haversine(
123
- latlong1["lng"], latlong1["lat"], latlong2["lng"], latlong2["lat"]
 
 
 
124
  )
125
  dist = dist * 0.621371
126
 
127
- return [f"The distance between {place_1} and {place_2} is {dist:.3f} miles"]
 
 
 
 
128
 
129
  def get_recommendations(self, topics: list, lat_long: tuple):
130
  """
@@ -138,6 +165,7 @@ class Tools:
138
 
139
  topic = " ".join(topics)
140
  latlong = lat_long[0]["geometry"]["location"]
 
141
  results = self.gmaps.places(
142
  query=topic,
143
  location=latlong,
@@ -165,6 +193,7 @@ class Tools:
165
 
166
  type_of_place = " ".join(type_of_place)
167
  # Perform the search using Google Places API
 
168
  places_result = self.gmaps.places_nearby(
169
  location=location, keyword=type_of_place, radius=radius_miles * 1609.34
170
  )
@@ -181,7 +210,8 @@ class Tools:
181
  if distance == 0.0:
182
  continue
183
 
184
- place["distance"] = f"{distance} kilometers from {verb_location}"
 
185
  new_places.append(place)
186
 
187
  places = new_places
@@ -212,18 +242,26 @@ class Tools:
212
  location = None
213
  if location and isinstance(location, str):
214
  place_name += " , " + location
215
- elif isinstance(place_name, dict) and "results" in place_name and "name" in place_name["results"]:
 
 
 
 
216
  place_name = place_name["results"]["name"]
217
  elif isinstance(place_name, dict) and "name" in place_name:
218
  place_name = place_name["name"]
219
 
220
- search_results = self.gmaps.places(place_name)
 
 
 
221
 
222
- if not search_results.get("results"):
223
  return []
224
 
225
  # Assuming the first result is the most relevant
226
- place_id = search_results["results"][0]["place_id"]
 
227
  place_details = self.gmaps.place(place_id=place_id)
228
  reviews = place_details["result"].get("reviews", [])
229
 
 
2
  These are all the tools used in the NexusRaven V2 demo! You can provide any tools you want to Raven.
3
 
4
  Nothing in this file is specific to Raven, code/information related to Raven can be found in the `raven_demo.py` file.
5
+
6
+ For more information about the Google Maps Places API Python client, see https://github.com/googlemaps/google-maps-services-python
7
  """
8
+ from typing import Dict, List
9
 
10
  from math import radians, cos, sin, asin, sqrt
11
 
 
25
  self.gmaps = Client(config.gmaps_client_key)
26
  self.client_ip: str | None = None
27
 
28
+ def capitalize(self, s: str) -> str:
29
+ if s.lower() != s:
30
+ return s
31
+
32
+ return s.title()
33
+
34
  def haversine(self, lon1, lat1, lon2, lat2) -> float:
35
  """
36
  Calculate the great circle distance in kilometers between two points on the earth (specified in decimal degrees).
 
60
  except:
61
  return "San Francisco, California, US"
62
 
63
+ def sort_results(
64
+ self, places: list, sort: str, descending: bool = True, first_n: int = None
65
+ ) -> List:
66
  """
67
  Sorts the results by either 'distance', 'rating' or 'price'.
68
 
 
70
  - sort (str): If set, sorts by either 'distance' or 'rating' or 'price'. ONLY supports 'distance' or 'rating' or 'price'.
71
  - descending (bool): If descending is set, setting this boolean to true will sort the results such that the highest values are first.
72
  - first_n (int): If provided, only retains the first n items in the final sorted list.
73
+
74
  When people ask for 'closest' or 'nearest', sort by 'distance'.
75
  When people ask for 'cheapest' or 'most expensive', sort by 'price'.
76
  When people ask for 'best' or 'highest rated', sort by rating.
 
98
 
99
  - location: This can be a city like 'Austin', or a place like 'Austin Airport', etc.
100
  """
101
+
102
+ # For response content, see https://developers.google.com/maps/documentation/geocoding/requests-geocoding#GeocodingResponses
103
+ results = self.gmaps.geocode(location)
104
+ location = self.capitalize(location)
105
+ for r in results:
106
+ r["name"] = location
107
+ return results
108
 
109
  def get_distance(self, place_1: str, place_2: str):
110
  """
 
117
  """
118
  if isinstance(place_1, list) and len(place_1) > 0:
119
  place_1 = place_1[0]
 
120
  if isinstance(place_2, list) and len(place_2) > 0:
121
  place_2 = place_2[0]
122
 
 
 
 
123
  if isinstance(place_1, dict):
124
+ place_1: str = place_1["name"]
125
  if isinstance(place_2, dict):
126
+ place_2: str = place_2["name"]
127
 
128
+ latlong_1 = self.get_latitude_longitude(place_1)
129
+ if len(latlong_1) == 0:
130
+ return f"No place found for `{place_1}`. Please be more explicit."
131
 
132
+ latlong_2 = self.get_latitude_longitude(place_2)
133
+ if len(latlong_2) == 0:
134
+ return f"No place found for `{place_2}`. Please be more explicit."
135
+
136
+ latlong_1 = latlong_1[0]
137
+ latlong_2 = latlong_2[0]
138
+
139
+ latlong_values_1 = latlong_1["geometry"]["location"]
140
+ latlong_values_2 = latlong_2["geometry"]["location"]
141
 
142
  dist = self.haversine(
143
+ latlong_values_1["lng"],
144
+ latlong_values_1["lat"],
145
+ latlong_values_2["lng"],
146
+ latlong_values_2["lat"],
147
  )
148
  dist = dist * 0.621371
149
 
150
+ return [
151
+ latlong_1,
152
+ latlong_2,
153
+ f"The distance between {place_1} and {place_2} is {dist:.3f} miles",
154
+ ]
155
 
156
  def get_recommendations(self, topics: list, lat_long: tuple):
157
  """
 
165
 
166
  topic = " ".join(topics)
167
  latlong = lat_long[0]["geometry"]["location"]
168
+ # For response format, see https://developers.google.com/maps/documentation/places/web-service/search-find-place#find-place-responses
169
  results = self.gmaps.places(
170
  query=topic,
171
  location=latlong,
 
193
 
194
  type_of_place = " ".join(type_of_place)
195
  # Perform the search using Google Places API
196
+ # For response format, see https://developers.google.com/maps/documentation/places/web-service/search-nearby#nearby-search-responses
197
  places_result = self.gmaps.places_nearby(
198
  location=location, keyword=type_of_place, radius=radius_miles * 1609.34
199
  )
 
210
  if distance == 0.0:
211
  continue
212
 
213
+ distance = distance * 0.621371
214
+ place["distance"] = f"{distance} miles from {verb_location}"
215
  new_places.append(place)
216
 
217
  places = new_places
 
242
  location = None
243
  if location and isinstance(location, str):
244
  place_name += " , " + location
245
+ elif (
246
+ isinstance(place_name, dict)
247
+ and "results" in place_name
248
+ and "name" in place_name["results"]
249
+ ):
250
  place_name = place_name["results"]["name"]
251
  elif isinstance(place_name, dict) and "name" in place_name:
252
  place_name = place_name["name"]
253
 
254
+ # For response format, see https://developers.google.com/maps/documentation/places/web-service/search-find-place#find-place-responses
255
+ search_results = self.gmaps.find_place(
256
+ place_name, input_type="textquery", location_bias="ipbias"
257
+ )
258
 
259
+ if len(search_results.get("candidates", [])) == 0:
260
  return []
261
 
262
  # Assuming the first result is the most relevant
263
+ place_id = search_results["candidates"][0]["place_id"]
264
+ # For response format, see https://developers.google.com/maps/documentation/places/web-service/details#PlaceDetailsResponses
265
  place_details = self.gmaps.place(place_id=place_id)
266
  reviews = place_details["result"].get("reviews", [])
267