bhardwaj08sarthak commited on
Commit
3505383
·
verified ·
1 Parent(s): 8ab1b8e

Update weather.py

Browse files
Files changed (1) hide show
  1. weather.py +201 -201
weather.py CHANGED
@@ -1,201 +1,201 @@
1
- import requests
2
- from geopy.geocoders import Nominatim
3
- from datetime import datetime, date, timedelta
4
- import pandas as pd
5
- import gradio as gr
6
-
7
- # Weather code to human-readable
8
- WEATHER_CODES = {
9
- 0: "Clear sky", 1: "Mainly clear", 2: "Partly cloudy", 3: "Overcast",
10
- 45: "Fog", 48: "Depositing rime fog", 51: "Light drizzle", 53: "Moderate drizzle", 55: "Dense drizzle",
11
- 61: "Slight rain", 63: "Moderate rain", 65: "Heavy rain", 71: "Slight snowfall", 73: "Moderate snowfall",
12
- 75: "Heavy snowfall", 80: "Slight rain showers", 81: "Moderate rain showers", 82: "Violent rain showers",
13
- 95: "Thunderstorm", 96: "Thunderstorm with hail"
14
- }
15
-
16
- def get_weather_forecast(location_name, target_date, include_hourly=False):
17
- try:
18
- if isinstance(target_date, str):
19
- target_date = datetime.strptime(target_date, "%Y-%m-%d").date()
20
- date_str = target_date.isoformat()
21
-
22
- geolocator = Nominatim(user_agent="weather_api")
23
- location = geolocator.geocode(location_name)
24
- if not location:
25
- return {"error": f"Could not find coordinates for '{location_name}'."}
26
- lat, lon = location.latitude, location.longitude
27
-
28
- url = "https://api.open-meteo.com/v1/forecast"
29
- params = {
30
- "latitude": lat,
31
- "longitude": lon,
32
- "daily": "sunrise,sunset,uv_index_max,temperature_2m_max,temperature_2m_min,weather_code",
33
- "temperature_unit": "celsius",
34
- "windspeed_unit": "kmh",
35
- "timeformat": "iso8601",
36
- "timezone": "auto",
37
- "start_date": date_str,
38
- "end_date": date_str
39
- }
40
-
41
- if include_hourly:
42
- params["hourly"] = "temperature_2m,weather_code,uv_index,visibility"
43
-
44
- response = requests.get(url, params=params)
45
- if response.status_code != 200:
46
- return {"error": f"API error {response.status_code}: {response.text}"}
47
- raw = response.json()
48
-
49
- if "daily" not in raw or date_str not in raw["daily"]["time"]:
50
- return {"error": f"Weather data for {date_str} not available."}
51
-
52
- idx = raw["daily"]["time"].index(date_str)
53
- result = {
54
- "date": date_str,
55
- "sunrise": raw["daily"]["sunrise"][idx].split("T")[1],
56
- "sunset": raw["daily"]["sunset"][idx].split("T")[1],
57
- "uv_max": round(raw["daily"]["uv_index_max"][idx], 1),
58
- "temp_min": round(raw["daily"]["temperature_2m_min"][idx]),
59
- "temp_max": round(raw["daily"]["temperature_2m_max"][idx]),
60
- "weather": WEATHER_CODES.get(int(raw["daily"]["weather_code"][idx]), "Unknown")
61
- }
62
-
63
- if include_hourly and "hourly" in raw:
64
- hourly_df = pd.DataFrame({
65
- "time": raw["hourly"]["time"],
66
- "temp": raw["hourly"]["temperature_2m"],
67
- "code": raw["hourly"]["weather_code"],
68
- "uv": raw["hourly"]["uv_index"],
69
- "visibility": [v / 1000 for v in raw["hourly"]["visibility"]]
70
- })
71
- hourly_df["time"] = pd.to_datetime(hourly_df["time"])
72
- hourly_df = hourly_df[hourly_df["time"].dt.date == target_date]
73
- hourly_df["weather"] = hourly_df["code"].apply(lambda c: WEATHER_CODES.get(int(c), "Unknown"))
74
-
75
- result["hourly"] = [
76
- {
77
- "time": t.strftime("%Y-%m-%d %H:%M"),
78
- "temp": f"{round(temp)}°C",
79
- "weather": w,
80
- "uv": round(uv, 1),
81
- "visibility": f"{round(vis, 1)} km"
82
- }
83
- for t, temp, w, uv, vis in zip(
84
- hourly_df["time"], hourly_df["temp"], hourly_df["weather"],
85
- hourly_df["uv"], hourly_df["visibility"]
86
- )
87
- ]
88
- elif include_hourly:
89
- result["note"] = "Hourly weather data unavailable for this date."
90
-
91
- return result
92
-
93
- except Exception as e:
94
- return {"error": str(e)}
95
-
96
-
97
- def get_weather_forecast_range(location_name, start_date, end_date):
98
- try:
99
- if isinstance(start_date, str):
100
- start_date = datetime.strptime(start_date, "%Y-%m-%d").date()
101
- if isinstance(end_date, str):
102
- end_date = datetime.strptime(end_date, "%Y-%m-%d").date()
103
-
104
- today = date.today()
105
- days_ahead = (end_date - today).days
106
-
107
- if days_ahead > 15:
108
- return {"error": "Weather data only available up to 15 days from today."}
109
-
110
- geolocator = Nominatim(user_agent="weather_api")
111
- location = geolocator.geocode(location_name)
112
- if not location:
113
- return {"error": f"Could not find coordinates for '{location_name}'."}
114
- lat, lon = location.latitude, location.longitude
115
-
116
- include_hourly = days_ahead <= 6
117
-
118
- url = "https://api.open-meteo.com/v1/forecast"
119
- params = {
120
- "latitude": lat,
121
- "longitude": lon,
122
- "daily": "sunrise,sunset,uv_index_max,temperature_2m_max,temperature_2m_min,weather_code",
123
- "temperature_unit": "celsius",
124
- "windspeed_unit": "kmh",
125
- "timeformat": "iso8601",
126
- "timezone": "auto",
127
- "start_date": start_date.isoformat(),
128
- "end_date": end_date.isoformat()
129
- }
130
-
131
- if include_hourly:
132
- params["hourly"] = "temperature_2m,weather_code,uv_index,visibility"
133
-
134
- response = requests.get(url, params=params)
135
- if response.status_code != 200:
136
- return {"error": f"API error {response.status_code}: {response.text}"}
137
- raw = response.json()
138
-
139
- forecasts = []
140
- for idx, d in enumerate(raw["daily"]["time"]):
141
- day_result = {
142
- "date": d,
143
- "sunrise": raw["daily"]["sunrise"][idx].split("T")[1],
144
- "sunset": raw["daily"]["sunset"][idx].split("T")[1],
145
- "uv_max": round(raw["daily"]["uv_index_max"][idx], 1),
146
- "temp_min": round(raw["daily"]["temperature_2m_min"][idx]),
147
- "temp_max": round(raw["daily"]["temperature_2m_max"][idx]),
148
- "weather": WEATHER_CODES.get(int(raw["daily"]["weather_code"][idx]), "Unknown")
149
- }
150
-
151
- if include_hourly and "hourly" in raw:
152
- hourly_df = pd.DataFrame({
153
- "time": raw["hourly"]["time"],
154
- "temp": raw["hourly"]["temperature_2m"],
155
- "code": raw["hourly"]["weather_code"],
156
- "uv": raw["hourly"]["uv_index"],
157
- "visibility": [v / 1000 for v in raw["hourly"]["visibility"]]
158
- })
159
-
160
- hourly_df["time"] = pd.to_datetime(hourly_df["time"])
161
- target_date = datetime.strptime(d, "%Y-%m-%d").date()
162
- df_day = hourly_df[hourly_df["time"].dt.date == target_date]
163
-
164
- df_day["weather"] = df_day["code"].apply(lambda c: WEATHER_CODES.get(int(c), "Unknown"))
165
-
166
- day_result["hourly"] = [
167
- {
168
- "time": t.strftime("%Y-%m-%d %H:%M"),
169
- "temp": f"{round(temp)}°C",
170
- "weather": w,
171
- "uv": round(uv, 1),
172
- "visibility": f"{round(vis, 1)} km"
173
- }
174
- for t, temp, w, uv, vis in zip(
175
- df_day["time"], df_day["temp"], df_day["weather"],
176
- df_day["uv"], df_day["visibility"]
177
- )
178
- ]
179
- else:
180
- day_result["note"] = "Hourly weather data is only available for the next 7 days."
181
-
182
- forecasts.append(day_result)
183
-
184
- return forecasts
185
-
186
- except Exception as e:
187
- return {"error": str(e)}
188
-
189
- demo= gr.Interface(
190
- fn=get_weather_forecast_range,
191
- inputs=[
192
- gr.Textbox(label="Location Name", placeholder="Enter a city or place name"),
193
- gr.Textbox(label="Start Date (YYYY-MM-DD)", value=date.today()),
194
- gr.Textbox(label="End Date (YYYY-MM-DD)", value=date.today() + timedelta(days=6))
195
- ],
196
- outputs=gr.JSON(label="Weather Forecast"),
197
- title="Weather Forecast Tool",
198
- description="Get weather forecasts for a specific location and date range."
199
- )
200
- if __name__ == "__main__":
201
- demo.launch(mcp_server=True, share=True)
 
1
+ import requests
2
+ from geopy.geocoders import Nominatim
3
+ from datetime import datetime, date, timedelta
4
+ import pandas as pd
5
+ import gradio as gr
6
+
7
+ # Weather code to human-readable
8
+ WEATHER_CODES = {
9
+ 0: "Clear sky", 1: "Mainly clear", 2: "Partly cloudy", 3: "Overcast",
10
+ 45: "Fog", 48: "Depositing rime fog", 51: "Light drizzle", 53: "Moderate drizzle", 55: "Dense drizzle",
11
+ 61: "Slight rain", 63: "Moderate rain", 65: "Heavy rain", 71: "Slight snowfall", 73: "Moderate snowfall",
12
+ 75: "Heavy snowfall", 80: "Slight rain showers", 81: "Moderate rain showers", 82: "Violent rain showers",
13
+ 95: "Thunderstorm", 96: "Thunderstorm with hail"
14
+ }
15
+
16
+ def get_weather_forecast(location_name, target_date, include_hourly=False):
17
+ try:
18
+ if isinstance(target_date, str):
19
+ target_date = datetime.strptime(target_date, "%Y-%m-%d").date()
20
+ date_str = target_date.isoformat()
21
+
22
+ geolocator = Nominatim(user_agent="weather_api")
23
+ location = geolocator.geocode(location_name)
24
+ if not location:
25
+ return {"error": f"Could not find coordinates for '{location_name}'."}
26
+ lat, lon = location.latitude, location.longitude
27
+
28
+ url = "https://api.open-meteo.com/v1/forecast"
29
+ params = {
30
+ "latitude": lat,
31
+ "longitude": lon,
32
+ "daily": "sunrise,sunset,uv_index_max,temperature_2m_max,temperature_2m_min,weather_code",
33
+ "temperature_unit": "celsius",
34
+ "windspeed_unit": "kmh",
35
+ "timeformat": "iso8601",
36
+ "timezone": "auto",
37
+ "start_date": date_str,
38
+ "end_date": date_str
39
+ }
40
+
41
+ if include_hourly:
42
+ params["hourly"] = "temperature_2m,weather_code,uv_index,visibility"
43
+
44
+ response = requests.get(url, params=params)
45
+ if response.status_code != 200:
46
+ return {"error": f"API error {response.status_code}: {response.text}"}
47
+ raw = response.json()
48
+
49
+ if "daily" not in raw or date_str not in raw["daily"]["time"]:
50
+ return {"error": f"Weather data for {date_str} not available."}
51
+
52
+ idx = raw["daily"]["time"].index(date_str)
53
+ result = {
54
+ "date": date_str,
55
+ "sunrise": raw["daily"]["sunrise"][idx].split("T")[1],
56
+ "sunset": raw["daily"]["sunset"][idx].split("T")[1],
57
+ "uv_max": round(raw["daily"]["uv_index_max"][idx], 1),
58
+ "temp_min": round(raw["daily"]["temperature_2m_min"][idx]),
59
+ "temp_max": round(raw["daily"]["temperature_2m_max"][idx]),
60
+ "weather": WEATHER_CODES.get(int(raw["daily"]["weather_code"][idx]), "Unknown")
61
+ }
62
+
63
+ if include_hourly and "hourly" in raw:
64
+ hourly_df = pd.DataFrame({
65
+ "time": raw["hourly"]["time"],
66
+ "temp": raw["hourly"]["temperature_2m"],
67
+ "code": raw["hourly"]["weather_code"],
68
+ "uv": raw["hourly"]["uv_index"],
69
+ "visibility": [v / 1000 for v in raw["hourly"]["visibility"]]
70
+ })
71
+ hourly_df["time"] = pd.to_datetime(hourly_df["time"])
72
+ hourly_df = hourly_df[hourly_df["time"].dt.date == target_date]
73
+ hourly_df["weather"] = hourly_df["code"].apply(lambda c: WEATHER_CODES.get(int(c), "Unknown"))
74
+
75
+ result["hourly"] = [
76
+ {
77
+ "time": t.strftime("%Y-%m-%d %H:%M"),
78
+ "temp": f"{round(temp)}°C",
79
+ "weather": w,
80
+ "uv": round(uv, 1),
81
+ "visibility": f"{round(vis, 1)} km"
82
+ }
83
+ for t, temp, w, uv, vis in zip(
84
+ hourly_df["time"], hourly_df["temp"], hourly_df["weather"],
85
+ hourly_df["uv"], hourly_df["visibility"]
86
+ )
87
+ ]
88
+ elif include_hourly:
89
+ result["note"] = "Hourly weather data unavailable for this date."
90
+
91
+ return result
92
+
93
+ except Exception as e:
94
+ return {"error": str(e)}
95
+
96
+
97
+ def get_weather_forecast_range(location_name, start_date, end_date):
98
+ try:
99
+ if isinstance(start_date, str):
100
+ start_date = datetime.strptime(start_date, "%Y-%m-%d").date()
101
+ if isinstance(end_date, str):
102
+ end_date = datetime.strptime(end_date, "%Y-%m-%d").date()
103
+
104
+ today = date.today()
105
+ days_ahead = (end_date - today).days
106
+
107
+ if days_ahead > 15:
108
+ return {"error": "Weather data only available up to 15 days from today."}
109
+
110
+ geolocator = Nominatim(user_agent="weather_api")
111
+ location = geolocator.geocode(location_name)
112
+ if not location:
113
+ return {"error": f"Could not find coordinates for '{location_name}'."}
114
+ lat, lon = location.latitude, location.longitude
115
+
116
+ include_hourly = days_ahead <= 6
117
+
118
+ url = "https://api.open-meteo.com/v1/forecast"
119
+ params = {
120
+ "latitude": lat,
121
+ "longitude": lon,
122
+ "daily": "sunrise,sunset,uv_index_max,temperature_2m_max,temperature_2m_min,weather_code",
123
+ "temperature_unit": "celsius",
124
+ "windspeed_unit": "kmh",
125
+ "timeformat": "iso8601",
126
+ "timezone": "auto",
127
+ "start_date": start_date.isoformat(),
128
+ "end_date": end_date.isoformat()
129
+ }
130
+
131
+ if include_hourly:
132
+ params["hourly"] = "temperature_2m,weather_code,uv_index,visibility"
133
+
134
+ response = requests.get(url, params=params)
135
+ if response.status_code != 200:
136
+ return {"error": f"API error {response.status_code}: {response.text}"}
137
+ raw = response.json()
138
+
139
+ forecasts = []
140
+ for idx, d in enumerate(raw["daily"]["time"]):
141
+ day_result = {
142
+ "date": d,
143
+ "sunrise": raw["daily"]["sunrise"][idx].split("T")[1],
144
+ "sunset": raw["daily"]["sunset"][idx].split("T")[1],
145
+ "uv_max": round(raw["daily"]["uv_index_max"][idx], 1),
146
+ "temp_min": round(raw["daily"]["temperature_2m_min"][idx]),
147
+ "temp_max": round(raw["daily"]["temperature_2m_max"][idx]),
148
+ "weather": WEATHER_CODES.get(int(raw["daily"]["weather_code"][idx]), "Unknown")
149
+ }
150
+
151
+ if include_hourly and "hourly" in raw:
152
+ hourly_df = pd.DataFrame({
153
+ "time": raw["hourly"]["time"],
154
+ "temp": raw["hourly"]["temperature_2m"],
155
+ "code": raw["hourly"]["weather_code"],
156
+ "uv": raw["hourly"]["uv_index"],
157
+ "visibility": [v / 1000 for v in raw["hourly"]["visibility"]]
158
+ })
159
+
160
+ hourly_df["time"] = pd.to_datetime(hourly_df["time"])
161
+ target_date = datetime.strptime(d, "%Y-%m-%d").date()
162
+ df_day = hourly_df[hourly_df["time"].dt.date == target_date]
163
+
164
+ df_day["weather"] = df_day["code"].apply(lambda c: WEATHER_CODES.get(int(c), "Unknown"))
165
+
166
+ day_result["hourly"] = [
167
+ {
168
+ "time": t.strftime("%Y-%m-%d %H:%M"),
169
+ "temp": f"{round(temp)}°C",
170
+ "weather": w,
171
+ "uv": round(uv, 1),
172
+ "visibility": f"{round(vis, 1)} km"
173
+ }
174
+ for t, temp, w, uv, vis in zip(
175
+ df_day["time"], df_day["temp"], df_day["weather"],
176
+ df_day["uv"], df_day["visibility"]
177
+ )
178
+ ]
179
+ else:
180
+ day_result["note"] = "Hourly weather data is only available for the next 7 days."
181
+
182
+ forecasts.append(day_result)
183
+
184
+ return forecasts
185
+
186
+ except Exception as e:
187
+ return {"error": str(e)}
188
+
189
+ demo= gr.Interface(
190
+ fn=get_weather_forecast_range,
191
+ inputs=[
192
+ gr.Textbox(label="Location Name", placeholder="Enter a city or place name"),
193
+ gr.Textbox(label="Start Date (YYYY-MM-DD)", value=date.today()),
194
+ gr.Textbox(label="End Date (YYYY-MM-DD)", value=date.today() + timedelta(days=6))
195
+ ],
196
+ outputs=gr.JSON(label="Weather Forecast"),
197
+ title="Weather Forecast Tool",
198
+ description="Get weather forecasts for a specific location and date range."
199
+ )
200
+
201
+ demo.launch(mcp_server=True, share=True)