.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
open_meteo.py
Go to the documentation of this file.
1# SPDX-License-Identifier: AGPL-3.0-or-later
2"""Open Meteo (weather)"""
3
4from urllib.parse import urlencode
5from datetime import datetime
6
7from searx.result_types import EngineResults, WeatherAnswer
8from searx import weather
9
10
11about = {
12 "website": "https://open-meteo.com",
13 "wikidata_id": None,
14 "official_api_documentation": "https://open-meteo.com/en/docs",
15 "use_official_api": True,
16 "require_api_key": False,
17 "results": "JSON",
18}
19
20categories = ["weather"]
21
22geo_url = "https://geocoding-api.open-meteo.com"
23api_url = "https://api.open-meteo.com"
24
25data_of_interest = (
26 "temperature_2m",
27 "apparent_temperature",
28 "relative_humidity_2m",
29 "apparent_temperature",
30 "cloud_cover",
31 "pressure_msl",
32 "wind_speed_10m",
33 "wind_direction_10m",
34 "weather_code",
35 # "visibility",
36 # "is_day",
37)
38
39
40def request(query, params):
41
42 try:
43 location = weather.GeoLocation.by_query(query)
44 except ValueError:
45 return
46
47 args = {
48 "latitude": location.latitude,
49 "longitude": location.longitude,
50 "timeformat": "unixtime",
51 "timezone": "auto", # use timezone of the location
52 "format": "json",
53 "current": ",".join(data_of_interest),
54 "forecast_days": 3,
55 "hourly": ",".join(data_of_interest),
56 }
57
58 params["url"] = f"{api_url}/v1/forecast?{urlencode(args)}"
59
60
61# https://open-meteo.com/en/docs#weather_variable_documentation
62# https://nrkno.github.io/yr-weather-symbols/
63
64WMO_TO_CONDITION: dict[int, weather.WeatherConditionType] = {
65 # 0 Clear sky
66 0: "clear sky",
67 # 1, 2, 3 Mainly clear, partly cloudy, and overcast
68 1: "fair",
69 2: "partly cloudy",
70 3: "cloudy",
71 # 45, 48 Fog and depositing rime fog
72 45: "fog",
73 48: "fog",
74 # 51, 53, 55 Drizzle: Light, moderate, and dense intensity
75 51: "light rain",
76 53: "light rain",
77 55: "light rain",
78 # 56, 57 Freezing Drizzle: Light and dense intensity
79 56: "light sleet showers",
80 57: "light sleet",
81 # 61, 63, 65 Rain: Slight, moderate and heavy intensity
82 61: "light rain",
83 63: "rain",
84 65: "heavy rain",
85 # 66, 67 Freezing Rain: Light and heavy intensity
86 66: "light sleet showers",
87 67: "light sleet",
88 # 71, 73, 75 Snow fall: Slight, moderate, and heavy intensity
89 71: "light sleet",
90 73: "sleet",
91 75: "heavy sleet",
92 # 77 Snow grains
93 77: "snow",
94 # 80, 81, 82 Rain showers: Slight, moderate, and violent
95 80: "light rain showers",
96 81: "rain showers",
97 82: "heavy rain showers",
98 # 85, 86 Snow showers slight and heavy
99 85: "snow showers",
100 86: "heavy snow showers",
101 # 95 Thunderstorm: Slight or moderate
102 95: "rain and thunder",
103 # 96, 99 Thunderstorm with slight and heavy hail
104 96: "light snow and thunder",
105 99: "heavy snow and thunder",
106}
107
108
109def _weather_data(location: weather.GeoLocation, data: dict):
110
111 return WeatherAnswer.Item(
112 location=location,
113 temperature=weather.Temperature(unit="°C", value=data["temperature_2m"]),
114 condition=WMO_TO_CONDITION[data["weather_code"]],
115 feels_like=weather.Temperature(unit="°C", value=data["apparent_temperature"]),
116 wind_from=weather.Compass(data["wind_direction_10m"]),
117 wind_speed=weather.WindSpeed(data["wind_speed_10m"], unit="km/h"),
118 pressure=weather.Pressure(data["pressure_msl"], unit="hPa"),
119 humidity=weather.RelativeHumidity(data["relative_humidity_2m"]),
120 cloud_cover=data["cloud_cover"],
121 )
122
123
124def response(resp):
125 location = weather.GeoLocation.by_query(resp.search_params["query"])
126
127 res = EngineResults()
128 json_data = resp.json()
129
130 weather_answer = WeatherAnswer(
131 current=_weather_data(location, json_data["current"]),
132 service="Open-meteo",
133 # url="https://open-meteo.com/en/docs",
134 )
135
136 for index, time in enumerate(json_data["hourly"]["time"]):
137
138 if time < json_data["current"]["time"]:
139 # Cut off the hours that are already in the past
140 continue
141
142 hourly_data = {}
143 for key in data_of_interest:
144 hourly_data[key] = json_data["hourly"][key][index]
145
146 forecast_data = _weather_data(location, hourly_data)
147 forecast_data.datetime = weather.DateTime(datetime.fromtimestamp(time))
148 weather_answer.forecasts.append(forecast_data)
149
150 res.add(weather_answer)
151 return res
_weather_data(weather.GeoLocation location, dict data)
request(query, params)
Definition open_meteo.py:40