dr.botzo/weather/lib.py

87 lines
3.8 KiB
Python

# coding: utf-8
"""Get results of weather queries."""
import logging
import requests
from urllib.parse import quote
logger = logging.getLogger(__name__)
def query_wttr_in(query):
"""Hit the wttr.in JSON API with the provided query."""
logger.info(f"about to query wttr.in with '{query}'")
response = requests.get(f'http://wttr.in/{quote(query)}?format=j1')
response.raise_for_status()
weather_info = response.json()
logger.debug(f"results: {weather_info}")
return weather_info
def weather_summary(query):
"""Create a more consumable version of the weather report."""
logger.info(f"assembling weather summary for '{query}'")
weather_info = query_wttr_in(query)
# get some common/nested stuff once now
current = weather_info['current_condition'][0]
weather_desc = current['weatherDesc'][0] if 'weatherDesc' in current else {}
today_forecast = weather_info['weather'][0]
tomorrow_forecast = weather_info['weather'][1]
day_after_tomorrow_forecast = weather_info['weather'][2]
today_notes = [{'code': int(item['weatherCode']), 'desc': item['weatherDesc'][0]['value'] }
for item in today_forecast['hourly']]
today_noteworthy = sorted(today_notes, key=lambda i: i['code'], reverse=True)[0]['desc']
tomorrow_notes = [{'code': int(item['weatherCode']), 'desc': item['weatherDesc'][0]['value'] }
for item in tomorrow_forecast['hourly']]
tomorrow_noteworthy = sorted(tomorrow_notes, key=lambda i: i['code'], reverse=True)[0]['desc']
day_after_tomorrow_notes = [{'code': int(item['weatherCode']), 'desc': item['weatherDesc'][0]['value'] }
for item in day_after_tomorrow_forecast['hourly']]
day_after_tomorrow_noteworthy = sorted(day_after_tomorrow_notes, key=lambda i: i['code'], reverse=True)[0]['desc']
summary = {
'location': query,
'current': {
'description': weather_desc.get('value'),
'temp_C': f"{current.get('temp_C')}°C",
'temp_F': f"{current.get('temp_F')}°F",
'feels_like_temp_C': f"{current.get('FeelsLikeC')}°C",
'feels_like_temp_F': f"{current.get('FeelsLikeF')}°F",
'cloud_cover': f"{current.get('cloudcover')}%",
'humidity': f"{current.get('humidity')}%",
'precipitation': f"{current.get('precipMM')} mm",
'visibility': f"{current.get('visibility')} mi",
'wind_speed': f"{current.get('windspeedMiles')} MPH",
'wind_direction': current.get('winddir16Point'),
'pressure': f"{current.get('pressure')} mb",
'uv_index': current.get('uvIndex'),
},
'today_forecast': {
'high_C': f"{today_forecast.get('maxtempC')}°C",
'high_F': f"{today_forecast.get('maxtempF')}°F",
'low_C': f"{today_forecast.get('mintempC')}°C",
'low_F': f"{today_forecast.get('mintempF')}°F",
'noteworthy': today_noteworthy,
},
'tomorrow_forecast': {
'high_C': f"{tomorrow_forecast.get('maxtempC')}°C",
'high_F': f"{tomorrow_forecast.get('maxtempF')}°F",
'low_C': f"{tomorrow_forecast.get('mintempC')}°C",
'low_F': f"{tomorrow_forecast.get('mintempF')}°F",
'noteworthy': tomorrow_noteworthy,
},
'day_after_tomorrow_forecast': {
'high_C': f"{day_after_tomorrow_forecast.get('maxtempC')}°C",
'high_F': f"{day_after_tomorrow_forecast.get('maxtempF')}°F",
'low_C': f"{day_after_tomorrow_forecast.get('mintempC')}°C",
'low_F': f"{day_after_tomorrow_forecast.get('mintempF')}°F",
'noteworthy': day_after_tomorrow_noteworthy,
},
}
logger.debug(f"results: {summary}")
return summary