aniketkno commited on
Commit
3b4ba4d
·
verified ·
1 Parent(s): 1671487

Create weather.py

Browse files
Files changed (1) hide show
  1. tools/weather.py +91 -0
tools/weather.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import requests
3
+ from typing import Any, Optional
4
+ from smolagents.tools import Tool
5
+
6
+
7
+ class WeatherForecast(Tool):
8
+ name = "weather_forecast"
9
+ description = "Performs a weather search via open-mateo with openstreetmaps to get latlon then returns the weather results."
10
+ inputs = {'city': {'type': 'string', 'description': 'The name of the city required for weather gathering.'}}
11
+ output_type = "string"
12
+
13
+ def __init__(self, max_results=10, **kwargs):
14
+ super().__init__()
15
+
16
+ def forward(self) -> str:
17
+ results = self.get_weather_forecast()
18
+ if len(results) == 0:
19
+ raise Exception("No results found! Try a less restrictive/shorter query.")
20
+ postprocessed_results = [f"[{result['title']}]({result['href']})\n{result['body']}" for result in results]
21
+ return "## Search Results\n\n" + "\n\n".join(postprocessed_results)
22
+
23
+
24
+ def get_weather_forecast(self, city_name: str) -> str:
25
+ """A tool that fetches the current weather/temperature of a specified city.
26
+ Args:
27
+ city_name: A string representing a valid city (e.g., 'Bangalore').
28
+ """
29
+
30
+ latitude, longitude = self.get_coordinates_no_api_key(city_name)
31
+
32
+ base_url = "https://api.open-meteo.com/v1/forecast" # No API key needed for this version
33
+ params = {
34
+ "latitude": latitude,
35
+ "longitude": longitude,
36
+ "hourly": "temperature_2m,precipitation,wind_speed",
37
+ "daily": "temperature_2m_max,temperature_2m_min,precipitation_sum",
38
+ "forecast_days": 7,
39
+ "timezone": "auto"
40
+ }
41
+
42
+ try:
43
+ response = requests.get(base_url, params=params) # No headers needed
44
+ response.raise_for_status()
45
+ weatherJSON = response.json()
46
+ cityName = weatherJSON.get('location').get('name')
47
+ cityTemp = weatherJSON.get('hourly').get('temperature_2m')
48
+ averageTemp = round(mean(cityTemp), 1)
49
+ hourlyunits = weatherJSON.get('hourly_units').get('temperature_2m')
50
+ return weather_data
51
+ return f"The current Temperature in {cityName} is {averageTemp}{hourlyunits}!"
52
+ except requests.exceptions.RequestException as e:
53
+ print(f"Error fetching weather data: {e}")
54
+ return None
55
+ except json.JSONDecodeError as e:
56
+ print(f"Error decoding JSON response: {e}")
57
+ return None
58
+
59
+ def get_coordinates_no_api_key(self, city_name: str) -> [float, float]:
60
+ """Gets coordinates using OpenStreetMap's Nominatim (no API key, but with limitations)."""
61
+
62
+ # This approach is less reliable and might have rate limits.
63
+ # It's suitable for basic use cases but not for production.
64
+
65
+ geocoding_url = "https://nominatim.openstreetmap.org/search" # No API Key needed
66
+ params = {
67
+ "q": city_name,
68
+ "format": "json",
69
+ "limit": 1
70
+ }
71
+
72
+ try:
73
+ response = requests.get(geocoding_url, params=params)
74
+ response.raise_for_status()
75
+ geocoding_data = response.json()
76
+
77
+ if geocoding_data: # Check if any results were found
78
+ latitude = float(geocoding_data[0]["lat"])
79
+ longitude = float(geocoding_data[0]["lon"])
80
+ return latitude, longitude
81
+ else:
82
+ print(f"Could not find coordinates for {city_name}")
83
+ return None, None
84
+
85
+ except requests.exceptions.RequestException as e:
86
+ print(f"Error during geocoding: {e}")
87
+ return None, None
88
+ except (KeyError, IndexError, ValueError) as e: # Handle more potential errors
89
+ print(f"Error parsing geocoding response: {e}")
90
+ return None, None
91
+