iridescentX commited on
Commit
aea7899
·
verified ·
1 Parent(s): 001fdf1

Update weather.py

Browse files
Files changed (1) hide show
  1. weather.py +206 -206
weather.py CHANGED
@@ -1,206 +1,206 @@
1
- """
2
- title: Keyless Weather
3
- author: spyci
4
- author_url: https://github.com/open-webui
5
- funding_url: https://github.com/open-webui
6
- version: 0.1.1
7
- """
8
-
9
- import os
10
- import requests
11
- import urllib.parse
12
- import datetime
13
-
14
-
15
- def get_city_info(city: str):
16
- url = f"https://geocoding-api.open-meteo.com/v1/search?name={urllib.parse.quote(city)}&count=1&language=en&format=json"
17
- response = requests.get(url)
18
-
19
- if response.status_code == 200:
20
- try:
21
- data = response.json()["results"][0]
22
- return data["latitude"], data["longitude"], data["timezone"]
23
- except (KeyError, IndexError):
24
- print(f"City '{city}' not found")
25
- return None
26
- else:
27
- print(f"Failed to retrieve data for city '{city}': {response.status_code}")
28
- return None
29
-
30
-
31
- wmo_weather_codes = {
32
- "0": "Clear sky",
33
- "1": "Mainly clear, partly cloudy, and overcast",
34
- "2": "Mainly clear, partly cloudy, and overcast",
35
- "3": "Mainly clear, partly cloudy, and overcast",
36
- "45": "Fog and depositing rime fog",
37
- "48": "Fog and depositing rime fog",
38
- "51": "Drizzle: Light, moderate, and dense intensity",
39
- "53": "Drizzle: Light, moderate, and dense intensity",
40
- "55": "Drizzle: Light, moderate, and dense intensity",
41
- "56": "Freezing Drizzle: Light and dense intensity",
42
- "57": "Freezing Drizzle: Light and dense intensity",
43
- "61": "Rain: Slight, moderate and heavy intensity",
44
- "63": "Rain: Slight, moderate and heavy intensity",
45
- "65": "Rain: Slight, moderate and heavy intensity",
46
- "66": "Freezing Rain: Light and heavy intensity",
47
- "67": "Freezing Rain: Light and heavy intensity",
48
- "71": "Snow fall: Slight, moderate, and heavy intensity",
49
- "73": "Snow fall: Slight, moderate, and heavy intensity",
50
- "75": "Snow fall: Slight, moderate, and heavy intensity",
51
- "77": "Snow grains",
52
- "80": "Rain showers: Slight, moderate, and violent",
53
- "81": "Rain showers: Slight, moderate, and violent",
54
- "82": "Rain showers: Slight, moderate, and violent",
55
- "85": "Snow showers slight and heavy",
56
- "86": "Snow showers slight and heavy",
57
- "95": "Thunderstorm: Slight or moderate",
58
- "96": "Thunderstorm with slight and heavy hail",
59
- "99": "Thunderstorm with slight and heavy hail",
60
- }
61
-
62
-
63
- def fetch_weather_data(base_url, params):
64
- try:
65
- response = requests.get(base_url, params=params)
66
- response.raise_for_status()
67
- data = response.json()
68
- if "error" in data:
69
- return f"Error fetching weather data: {data['message']}"
70
- return data
71
- except requests.RequestException as e:
72
- return f"Error fetching weather data: {str(e)}"
73
-
74
-
75
- def format_date(date_str, date_format="%Y-%m-%dT%H:%M", output_format="%I:%M %p"):
76
- dt = datetime.datetime.strptime(date_str, date_format)
77
- return dt.strftime(output_format)
78
-
79
-
80
- class Tools:
81
- def __init__(self):
82
- self.citation = True
83
- pass
84
-
85
- def get_future_weather_week(self, city: str) -> str:
86
- """
87
- Get the weather for the next week for a given city.
88
- :param city: The name of the city to get the weather for.(use english name)
89
- :return: The current weather information or an error message.
90
- """
91
- if not city:
92
- return """The location has not been defined by the user, so weather cannot be determined."""
93
-
94
- city_info = get_city_info(city)
95
- if not city_info:
96
- return """Error fetching weather data"""
97
-
98
- lat, lng, tmzone = city_info
99
- print(f"Latitude: {lat}, Longitude: {lng}, Timezone: {tmzone}")
100
-
101
- base_url = "https://api.open-meteo.com/v1/forecast"
102
- params = {
103
- "latitude": lat,
104
- "longitude": lng,
105
- "daily": [
106
- "weather_code",
107
- "temperature_2m_max",
108
- "temperature_2m_min",
109
- "uv_index_max",
110
- "precipitation_probability_max",
111
- "wind_speed_10m_max",
112
- ],
113
- "current": "temperature_2m",
114
- "timezone": tmzone,
115
- "temperature_unit": "celsius", # 修改为摄氏度
116
- "wind_speed_unit": "kmh", # 修改为公里/小时
117
- "precipitation_unit": "mm", # 修改为毫米
118
- "forecast_days": 7,
119
- }
120
-
121
- data = fetch_weather_data(base_url, params)
122
- if isinstance(data, str):
123
- return data
124
-
125
- formatted_timestamp = format_date(data["current"]["time"])
126
- data["daily"]["time"][0] += " (Today)"
127
-
128
- mapped_data = {
129
- date: {
130
- "weather_description": wmo_weather_codes[
131
- str(data["daily"]["weather_code"][i])
132
- ],
133
- "temperature_max_min": f'{data["daily"]["temperature_2m_max"][i]} {data["daily_units"]["temperature_2m_max"]} / {data["daily"]["temperature_2m_min"][i]} {data["daily_units"]["temperature_2m_min"]}',
134
- "uv_index_max": f'{data["daily"]["uv_index_max"][i]} {data["daily_units"]["uv_index_max"]}',
135
- "precipitation_probability_max": f'{data["daily"]["precipitation_probability_max"][i]} {data["daily_units"]["precipitation_probability_max"]}',
136
- "max_wind_speed": f'{data["daily"]["wind_speed_10m_max"][i]} {data["daily_units"]["wind_speed_10m_max"]}',
137
- }
138
- for i, date in enumerate(data["daily"]["time"])
139
- }
140
-
141
- return f"""
142
- Give a weather description for the next week, include the time of the data ({formatted_timestamp} {data['timezone_abbreviation']} in {city}):
143
- Show a standard table layout of each of these days: {mapped_data}
144
- Summarize the overall weather trend for the week, noting any significant changes or patterns, like warming, cooling, or major weather events.
145
- Highlight key days with notable weather, such as extreme temperatures or precipitation.
146
- Provide practical advice for the week, including clothing suggestions and tips for outdoor activities based on the forecast.
147
- Keep the tone supportive and informative to help the user plan effectively."""
148
-
149
- def get_current_weather(self, city: str) -> str:
150
- """
151
- Get the current weather for a given city.
152
- :param city: The name of the city to get the weather for.(use english name)
153
- :return: The current weather information or an error message.
154
- """
155
- if not city:
156
- return """The location has not been defined by the user, so weather cannot be determined."""
157
-
158
- city_info = get_city_info(city)
159
- if not city_info:
160
- return """Error fetching weather data"""
161
-
162
- lat, lng, tmzone = city_info
163
- print(f"Latitude: {lat}, Longitude: {lng}, Timezone: {tmzone}")
164
-
165
- base_url = "https://api.open-meteo.com/v1/forecast"
166
- params = {
167
- "latitude": lat,
168
- "longitude": lng,
169
- "current": [
170
- "temperature_2m",
171
- "relative_humidity_2m",
172
- "apparent_temperature",
173
- "wind_speed_10m",
174
- "weather_code",
175
- ],
176
- "timezone": tmzone,
177
- "temperature_unit": "celsius", # 修改为摄氏度
178
- "wind_speed_unit": "kmh", # 修改为公里/小时
179
- "precipitation_unit": "mm", # 修改为毫米
180
- "forecast_days": 1,
181
- }
182
-
183
- data = fetch_weather_data(base_url, params)
184
- if isinstance(data, str):
185
- return data
186
-
187
- formatted_timestamp = format_date(data["current"]["time"])
188
- data["current"]["weather_code"] = wmo_weather_codes[
189
- str(data["current"]["weather_code"])
190
- ]
191
- formatted_data = ", ".join(
192
- [
193
- f"{x} ({data['current_units'][x]}) = '{data['current'][x]}'"
194
- for x in data["current"].keys()
195
- ]
196
- ).replace("weather_code", "weather_description")
197
-
198
- return f"""
199
- Give a weather description, include the time of the data ({formatted_timestamp} {data['timezone_abbreviation']} in {city}):
200
- Include all the following data in a clear format: [{formatted_data}]
201
- Ensure you mention the real temperature and the "feels like"(apparent_temperature) temperature. Convert all numbers to integers.
202
- Based on the weather conditions, provide suggestions for appropriate clothing. For example, if it's cold, recommend wearing a coat or if it's hot, suggest lighter clothing.
203
- Additionally, if there's a high chance of precipitation, remind the user to carry an umbrella or raincoat.
204
- If the weather conditions might affect travel (like fog, snow, or strong winds), include a warning or advice on how to prepare.
205
- Offer advice on outdoor activities. For instance, if it's sunny, recommend sunscreen, or if it's windy, suggest avoiding certain outdoor sports.
206
- """
 
1
+ """
2
+ title: Keyless Weather
3
+ author: spyci
4
+ author_url: https://github.com/open-webui
5
+ funding_url: https://github.com/open-webui
6
+ version: 0.1.1
7
+ """
8
+
9
+ import os
10
+ import requests
11
+ import urllib.parse
12
+ import datetime
13
+
14
+
15
+ def get_city_info(city: str):
16
+ url = f"https://geocoding-api.open-meteo.com/v1/search?name={urllib.parse.quote(city)}&count=1&language=en&format=json"
17
+ response = requests.get(url)
18
+
19
+ if response.status_code == 200:
20
+ try:
21
+ data = response.json()["results"][0]
22
+ return data["latitude"], data["longitude"], data["timezone"]
23
+ except (KeyError, IndexError):
24
+ print(f"City '{city}' not found")
25
+ return None
26
+ else:
27
+ print(f"Failed to retrieve data for city '{city}': {response.status_code}")
28
+ return None
29
+
30
+
31
+ wmo_weather_codes = {
32
+ "0": "Clear sky",
33
+ "1": "Mainly clear, partly cloudy, and overcast",
34
+ "2": "Mainly clear, partly cloudy, and overcast",
35
+ "3": "Mainly clear, partly cloudy, and overcast",
36
+ "45": "Fog and depositing rime fog",
37
+ "48": "Fog and depositing rime fog",
38
+ "51": "Drizzle: Light, moderate, and dense intensity",
39
+ "53": "Drizzle: Light, moderate, and dense intensity",
40
+ "55": "Drizzle: Light, moderate, and dense intensity",
41
+ "56": "Freezing Drizzle: Light and dense intensity",
42
+ "57": "Freezing Drizzle: Light and dense intensity",
43
+ "61": "Rain: Slight, moderate and heavy intensity",
44
+ "63": "Rain: Slight, moderate and heavy intensity",
45
+ "65": "Rain: Slight, moderate and heavy intensity",
46
+ "66": "Freezing Rain: Light and heavy intensity",
47
+ "67": "Freezing Rain: Light and heavy intensity",
48
+ "71": "Snow fall: Slight, moderate, and heavy intensity",
49
+ "73": "Snow fall: Slight, moderate, and heavy intensity",
50
+ "75": "Snow fall: Slight, moderate, and heavy intensity",
51
+ "77": "Snow grains",
52
+ "80": "Rain showers: Slight, moderate, and violent",
53
+ "81": "Rain showers: Slight, moderate, and violent",
54
+ "82": "Rain showers: Slight, moderate, and violent",
55
+ "85": "Snow showers slight and heavy",
56
+ "86": "Snow showers slight and heavy",
57
+ "95": "Thunderstorm: Slight or moderate",
58
+ "96": "Thunderstorm with slight and heavy hail",
59
+ "99": "Thunderstorm with slight and heavy hail",
60
+ }
61
+
62
+
63
+ def fetch_weather_data(base_url, params):
64
+ try:
65
+ response = requests.get(base_url, params=params)
66
+ response.raise_for_status()
67
+ data = response.json()
68
+ if "error" in data:
69
+ return f"Error fetching weather data: {data['message']}"
70
+ return data
71
+ except requests.RequestException as e:
72
+ return f"Error fetching weather data: {str(e)}"
73
+
74
+
75
+ def format_date(date_str, date_format="%Y-%m-%dT%H:%M", output_format="%I:%M %p"):
76
+ dt = datetime.datetime.strptime(date_str, date_format)
77
+ return dt.strftime(output_format)
78
+
79
+
80
+ class Tools:
81
+ def __init__(self):
82
+ self.citation = True
83
+ pass
84
+
85
+ def get_future_weather_week(self, city: str) -> str:
86
+ """
87
+ Get the weather for the next week for a given city.
88
+ :param city: The name of the city to get the weather for.(use english name)
89
+ :return: The current weather information or an error message.
90
+ """
91
+ if not city:
92
+ return """The location has not been defined by the user, so weather cannot be determined."""
93
+
94
+ city_info = get_city_info(city)
95
+ if not city_info:
96
+ return """Error fetching weather data"""
97
+
98
+ lat, lng, tmzone = city_info
99
+ print(f"Latitude: {lat}, Longitude: {lng}, Timezone: {tmzone}")
100
+
101
+ base_url = "https://api.open-meteo.com/v1/forecast"
102
+ params = {
103
+ "latitude": lat,
104
+ "longitude": lng,
105
+ "daily": [
106
+ "weather_code",
107
+ "temperature_2m_max",
108
+ "temperature_2m_min",
109
+ "uv_index_max",
110
+ "precipitation_probability_max",
111
+ "wind_speed_10m_max",
112
+ ],
113
+ "current": "temperature_2m",
114
+ "timezone": tmzone,
115
+ "temperature_unit": "celsius", # 修改为摄氏度
116
+ "wind_speed_unit": "kmh", # 修改为公里/小时
117
+ "precipitation_unit": "mm", # 修改为毫米
118
+ "forecast_days": 7,
119
+ }
120
+
121
+ data = fetch_weather_data(base_url, params)
122
+ if isinstance(data, str):
123
+ return data
124
+
125
+ formatted_timestamp = format_date(data["current"]["time"])
126
+ data["daily"]["time"][0] += " (Today)"
127
+
128
+ mapped_data = {
129
+ date: {
130
+ "weather_description": wmo_weather_codes[
131
+ str(data["daily"]["weather_code"][i])
132
+ ],
133
+ "temperature_max_min": f'{data["daily"]["temperature_2m_max"][i]} {data["daily_units"]["temperature_2m_max"]} / {data["daily"]["temperature_2m_min"][i]} {data["daily_units"]["temperature_2m_min"]}',
134
+ "uv_index_max": f'{data["daily"]["uv_index_max"][i]} {data["daily_units"]["uv_index_max"]}',
135
+ "precipitation_probability_max": f'{data["daily"]["precipitation_probability_max"][i]} {data["daily_units"]["precipitation_probability_max"]}',
136
+ "max_wind_speed": f'{data["daily"]["wind_speed_10m_max"][i]} {data["daily_units"]["wind_speed_10m_max"]}',
137
+ }
138
+ for i, date in enumerate(data["daily"]["time"])
139
+ }
140
+
141
+ return f"""
142
+ Give a weather description for the next week, include the time of the data ({formatted_timestamp} {data['timezone_abbreviation']} in {city}):
143
+ Show a standard table layout of each of these days: {mapped_data}
144
+ Summarize the overall weather trend for the week, noting any significant changes or patterns, like warming, cooling, or major weather events.
145
+ Highlight key days with notable weather, such as extreme temperatures or precipitation.
146
+ Provide practical advice for the week, including clothing suggestions and tips for outdoor activities based on the forecast.
147
+ Keep the tone supportive and informative to help the user plan effectively."""
148
+
149
+ def get_current_weather(self, city: str) -> str:
150
+ """
151
+ Get the current weather for a given city.
152
+ :param city: The name of the city to get the weather for.(use english name)
153
+ :return: The current weather information or an error message.
154
+ """
155
+ if not city:
156
+ return """The location has not been defined by the user, so weather cannot be determined."""
157
+
158
+ city_info = get_city_info(city)
159
+ if not city_info:
160
+ return """Error fetching weather data"""
161
+
162
+ lat, lng, tmzone = city_info
163
+ print(f"Latitude: {lat}, Longitude: {lng}, Timezone: {tmzone}")
164
+
165
+ base_url = "https://api.open-meteo.com/v1/forecast"
166
+ params = {
167
+ "latitude": lat,
168
+ "longitude": lng,
169
+ "current": [
170
+ "temperature_2m",
171
+ "relative_humidity_2m",
172
+ "apparent_temperature",
173
+ "wind_speed_10m",
174
+ "weather_code",
175
+ ],
176
+ "timezone": tmzone,
177
+ "temperature_unit": "celsius", # 修改为摄氏度
178
+ "wind_speed_unit": "kmh", # 修改为公里/小时
179
+ "precipitation_unit": "mm", # 修改为毫米
180
+ "forecast_days": 1,
181
+ }
182
+
183
+ data = fetch_weather_data(base_url, params)
184
+ if isinstance(data, str):
185
+ return data
186
+
187
+ formatted_timestamp = format_date(data["current"]["time"])
188
+ data["current"]["weather_code"] = wmo_weather_codes[
189
+ str(data["current"]["weather_code"])
190
+ ]
191
+ formatted_data = ", ".join(
192
+ [
193
+ f"{x} ({data['current_units'][x]}) = '{data['current'][x]}'"
194
+ for x in data["current"].keys()
195
+ ]
196
+ ).replace("weather_code", "weather_description")
197
+
198
+ return f"""
199
+ Give a weather description, include the time of the data ({formatted_timestamp} {data['timezone_abbreviation']} in {city}):
200
+ Include all the following data in a clear list: [{formatted_data}]
201
+ Ensure you mention the real temperature and the "feels like"(apparent_temperature) temperature. Convert all numbers to integers.
202
+ Based on the weather conditions, provide suggestions for appropriate clothing. For example, if it's cold, recommend wearing a coat or if it's hot, suggest lighter clothing.
203
+ Additionally, if there's a high chance of precipitation, remind the user to carry an umbrella or raincoat.
204
+ If the weather conditions might affect travel (like fog, snow, or strong winds), include a warning or advice on how to prepare.
205
+ Offer advice on outdoor activities. For instance, if it's sunny, recommend sunscreen, or if it's windy, suggest avoiding certain outdoor sports.
206
+ """