# coding: utf-8 """Get results of weather queries.""" import logging from urllib.parse import quote import requests logger = logging.getLogger(__name__) def query_wttr_in(query): """Hit the wttr.in JSON API with the provided query.""" logger.info("about to query wttr.in with '%s'", query) response = requests.get(f'http://wttr.in/{quote(query)}?format=j1') response.raise_for_status() weather_info = response.json() logger.debug("results: %s", weather_info) return weather_info def weather_summary(query): """Create a more consumable version of the weather report.""" logger.info("assembling weather summary for '%s'", 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'] location_str = None locations = [] # try to get a smarter location nearest_areas = weather_info.get('nearest_area', None) if nearest_areas: nearest_area = nearest_areas[0] area_name = nearest_area.get('areaName') if area_name: locations.append(area_name[0]['value']) region = nearest_area.get('region') if region: locations.append(region[0]['value']) country = nearest_area.get('country') if country: locations.append(country[0]['value']) if locations: location_str = ', '.join(locations) else: latitude = nearest_area.get('latitude') longitude = nearest_area.get('longitude') if latitude and longitude: location_str = f'{latitude},{longitude}' if not location_str: location_str = query summary = { 'location': location_str, '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("results: %s", summary) return summary