Source code for todays_paper_web.widgets.weather.yr

from datetime import datetime, timezone

import requests
from pydantic import Field

from todays_paper_web.widgets import DataSource, registerDataSource
from todays_paper_web.widgets.datasource import DataSourceParams
from todays_paper_web.widgets.params import Number
from .core import (
    WeatherForecast,
    WeatherIcon,
    WeatherType,
    WeatherForecastModel,
    TimeOfDay,
)


def YrToCoreIcon(symbolCode: str) -> WeatherIcon:
    icons = {
        "clearsky": WeatherType.ClearSky,
        "cloudy": WeatherType.ScatteredClouds,
        "fair": WeatherType.FewClouds,
        "fog": WeatherType.Mist,
        "heavyrain": WeatherType.Rain,
        # "heavyrainandthunder",
        # "heavyrainshowers",
        # "heavyrainshowersandthunder",
        # "heavysleet",
        # "heavysleetandthunder",
        # "heavysleetshowers",
        # "heavysleetshowersandthunder",
        "heavysnow": WeatherType.Snow,
        # "heavysnowandthunder",
        # "heavysnowshowers",
        # "heavysnowshowersandthunder",
        "lightrain": WeatherType.ShowerRain,
        # "lightrainandthunder",
        # "lightrainshowers",
        # "lightrainshowersandthunder",
        # "lightsleet",
        # "lightsleetandthunder",
        # "lightsleetshowers",
        "lightsnow": WeatherType.Snow,
        # "lightsnowandthunder",
        # "lightsnowshowers",
        # "lightssleetshowersandthunder",
        # "lightssnowshowersandthunder",
        "partlycloudy": WeatherType.FewClouds,
        "rain": WeatherType.Rain,
        # "rainandthunder",
        "rainshowers": WeatherType.ShowerRain,
        # "rainshowersandthunder",
        # "sleet",
        # "sleetandthunder",
        # "sleetshowers",
        # "sleetshowersandthunder",
        "snow": WeatherType.Snow,
        # "snowandthunder",
        "snowshowers": WeatherType.Snow,
        # "snowshowersandthunder",
    }
    tods = {"day": TimeOfDay.Day, "night": TimeOfDay.Night}

    try:
        weather, todStr = symbolCode.split("_", 1)
    except:
        weather = symbolCode
        todStr = "day"
    try:
        return WeatherIcon(weather=icons[weather], timeOfDay=tods[todStr])
    except:
        return WeatherIcon(weather=WeatherType.Unknown, timeOfDay=TimeOfDay.Day)


[docs] class YrParams(DataSourceParams): lat: Number = Field(..., description="Latitude to forecast for.") lon: Number = Field(..., description="Longitude to forecast for.") altitude: Number = Field( ..., description="Site altitude in meters - the API uses this to adjust the forecast." )
@registerDataSource("weather.yr") class YrDataSource(DataSource): Params = YrParams def fetch(self): r = requests.get( "https://api.met.no/weatherapi/locationforecast/2.0/compact", headers={ "User-Agent": "Todays-Paper 1.0", }, params={ "lat": self.params.lat, "lon": self.params.lon, "altitude": self.params.altitude, }, ) return WeatherForecastModel( [ YrDataSource.YrToWeatherForecast(x) for x in r.json().get("properties", []).get("timeseries", []) ] ) @staticmethod def YrToWeatherForecast(data: dict) -> WeatherForecast: summary = data.get("data", {}).get("next_1_hours", {}).get("summary", {}) instant = data.get("data", {}).get("instant", {}).get("details", {}) return WeatherForecast( timestamp=datetime.fromisoformat(data["time"][:-1]).replace( tzinfo=timezone.utc ), icon=YrToCoreIcon(summary.get("symbol_code", "")), airTemperature=instant.get("air_temperature", None), windSpeed=instant.get("wind_speed", None), )