74 lines
2.8 KiB
Python
74 lines
2.8 KiB
Python
"""Open Meteo weather map tool spec."""
|
|
|
|
import logging
|
|
import requests
|
|
import pytz
|
|
from llama_index.core.tools import FunctionTool
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class OpenMeteoWeather:
|
|
geo_api = "https://geocoding-api.open-meteo.com/v1"
|
|
weather_api = "https://api.open-meteo.com/v1"
|
|
|
|
@classmethod
|
|
def _get_geo_location(cls, location: str) -> dict:
|
|
"""Get geo location from location name."""
|
|
params = {"name": location, "count": 10, "language": "en", "format": "json"}
|
|
response = requests.get(f"{cls.geo_api}/search", params=params)
|
|
if response.status_code != 200:
|
|
raise Exception(f"Failed to fetch geo location: {response.status_code}")
|
|
else:
|
|
data = response.json()
|
|
result = data["results"][0]
|
|
geo_location = {
|
|
"id": result["id"],
|
|
"name": result["name"],
|
|
"latitude": result["latitude"],
|
|
"longitude": result["longitude"],
|
|
}
|
|
return geo_location
|
|
|
|
@classmethod
|
|
def get_weather_information(cls, location: str) -> dict:
|
|
"""Use this function to get the weather of any given location.
|
|
Note that the weather code should follow WMO Weather interpretation codes (WW):
|
|
0: Clear sky
|
|
1, 2, 3: Mainly clear, partly cloudy, and overcast
|
|
45, 48: Fog and depositing rime fog
|
|
51, 53, 55: Drizzle: Light, moderate, and dense intensity
|
|
56, 57: Freezing Drizzle: Light and dense intensity
|
|
61, 63, 65: Rain: Slight, moderate and heavy intensity
|
|
66, 67: Freezing Rain: Light and heavy intensity
|
|
71, 73, 75: Snow fall: Slight, moderate, and heavy intensity
|
|
77: Snow grains
|
|
80, 81, 82: Rain showers: Slight, moderate, and violent
|
|
85, 86: Snow showers slight and heavy
|
|
95: Thunderstorm: Slight or moderate
|
|
96, 99: Thunderstorm with slight and heavy hail
|
|
"""
|
|
logger.info(
|
|
f"Calling open-meteo api to get weather information of location: {location}"
|
|
)
|
|
geo_location = cls._get_geo_location(location)
|
|
timezone = pytz.timezone("UTC").zone
|
|
params = {
|
|
"latitude": geo_location["latitude"],
|
|
"longitude": geo_location["longitude"],
|
|
"current": "temperature_2m,weather_code",
|
|
"hourly": "temperature_2m,weather_code",
|
|
"daily": "weather_code",
|
|
"timezone": timezone,
|
|
}
|
|
response = requests.get(f"{cls.weather_api}/forecast", params=params)
|
|
if response.status_code != 200:
|
|
raise Exception(
|
|
f"Failed to fetch weather information: {response.status_code}"
|
|
)
|
|
return response.json()
|
|
|
|
|
|
def get_tools(**kwargs):
|
|
return [FunctionTool.from_defaults(OpenMeteoWeather.get_weather_information)]
|