feat: Weather is in

This commit is contained in:
2025-09-12 11:12:23 +01:00
parent f8816b1da6
commit 594f89e6b3
7 changed files with 759 additions and 27 deletions
+153
View File
@@ -0,0 +1,153 @@
import requests
import openmeteo_requests
import requests_cache
from retry_requests import retry
import json
# WMO Weather interpretation codes mapping
WEATHER_CODE_MAP = {
0: "Clear sky",
1: "Mainly clear",
2: "Partly cloudy",
3: "Overcast",
45: "Fog",
48: "Depositing rime fog",
51: "Light drizzle",
53: "Moderate drizzle",
55: "Dense drizzle",
56: "Light freezing drizzle",
57: "Dense freezing drizzle",
61: "Slight rain",
63: "Moderate rain",
65: "Heavy rain",
66: "Light freezing rain",
67: "Heavy freezing rain",
71: "Slight snow",
73: "Moderate snow",
75: "Heavy snow",
77: "Snow grains",
80: "Slight rain showers",
81: "Moderate rain showers",
82: "Violent rain showers",
85: "Slight snow showers",
86: "Heavy snow showers",
95: "Thunderstorm",
96: "Thunderstorm with slight hail",
99: "Thunderstorm with heavy hail"
}
class ToolExecutor:
def __init__(self):
self.tools = {
"get_weather": self.get_weather
}
def process_llm_response(self, llm_output):
# Parse the tool call from LLM response
if llm_output.startswith('{"tool":'):
llm_output = json.loads(llm_output)
print(llm_output)
tool_name = llm_output.get("tool",'no tool')
parameters = llm_output.get("parameters", 'no parameters')
print(f'parsed tool: {tool_name}, parsed parameters: {parameters}')
# Execute the actual function
result = self.tools[tool_name](**parameters)
# Return result for LLM to use
return result
return llm_output
def get_weather(self, city: str, units: str = "celsius"):
"""Get current weather for a location using Open-Meteo API with openmeteo-requests library."""
print(f'get weather called, city = {city}')
if not city:
raise ValueError("City parameter is required")
try:
# Setup the Open-Meteo API client with cache and retry on error
cache_session = requests_cache.CachedSession('.cache', expire_after=3600)
retry_session = retry(cache_session, retries=5, backoff_factor=0.2)
openmeteo = openmeteo_requests.Client(session=retry_session)
# Step 1: Get coordinates for the city using geocoding API
geocoding_url = "https://geocoding-api.open-meteo.com/v1/search"
geocoding_params = {
"name": city,
"count": 1,
"language": "en",
"format": "json"
}
geo_response = requests.get(geocoding_url, params=geocoding_params, timeout=10)
geo_response.raise_for_status()
geo_data = geo_response.json()
print(f'Geo data for city: {geo_data}')
if not geo_data.get("results"):
raise Exception(f"City '{city}' not found")
location = geo_data["results"][0]
latitude = location["latitude"]
longitude = location["longitude"]
city_name = location["name"]
country = location.get("country", "Unknown")
# Step 2: Get weather data using openmeteo-requests
url = "https://api.open-meteo.com/v1/forecast"
# Convert temperature units for the API
temperature_unit = "celsius" if units == "celsius" else "fahrenheit"
params = {
"latitude": latitude,
"longitude": longitude,
"current": [
"temperature_2m",
"relative_humidity_2m",
"weather_code",
"surface_pressure",
"wind_speed_10m"
],
"temperature_unit": temperature_unit,
"wind_speed_unit": "kmh"
}
responses = openmeteo.weather_api(url, params=params)
response = responses[0]
print(f'Weather API response: {response}')
# Get current weather data
current = response.Current()
print(f'Current weather data: {current}')
# Extract values using the library's methods
temperature = current.Variables(0).Value() # temperature_2m
humidity = current.Variables(1).Value() # relative_humidity_2m
weather_code = int(current.Variables(2).Value()) # weather_code
pressure = current.Variables(3).Value() # surface_pressure
wind_speed = current.Variables(4).Value() # wind_speed_10m
condition = WEATHER_CODE_MAP.get(weather_code, "Unknown")
json_reply = {
"temperature": temperature,
"condition": condition,
"humidity": humidity,
"pressure": pressure,
"wind_speed": wind_speed,
"units": units,
"city": city_name,
"country": country,
"coordinates": {"latitude": latitude, "longitude": longitude}
}
print(json_reply)
return json_reply
except Exception as e:
raise Exception(f"Weather lookup failed: {str(e)}")