# © Copyright 2021-2022, Scott Gasch
-"""How's the weather?"""
+"""A cache of weather data for Bellevue, WA.
+:class:`CachedWeatherData` class that derives from :class:`Persistent`
+so that, on creation, the decorator transparently pulls in data from
+disk, if possible, to avoid a network request.
+"""
import datetime
import json
@dataclass
class WeatherData:
- date: datetime.date # The date
- high: float # The predicted high in F
- low: float # The predicted low in F
- precipitation_inches: float # Number of inches of precipitation / day
- conditions: List[str] # Conditions per ~3h window
- most_common_condition: str # The most common condition
- icon: str # An icon to represent it
+ date: datetime.date
+ """The date of the forecast"""
+
+ high: float
+ """The predicted high temperature in F"""
+
+ low: float
+ """The predicted low temperature in F"""
+
+ precipitation_inches: float
+ """Number of inches of precipitation / day"""
+
+ conditions: List[str]
+ """Conditions per ~3h window"""
+
+ most_common_condition: str
+ """The most common condition of the day"""
+
+ icon: str
+ """An icon representing the most common condition of the day"""
@persistent.persistent_autoloaded_singleton() # type: ignore
class CachedWeatherData(persistent.Persistent):
def __init__(self, weather_data: Dict[datetime.date, WeatherData] = None):
+ """C'tor. Do not pass a dict except for testing purposes.
+
+ The @persistent_autoloaded_singleton decorator handles
+ invoking our load and save methods at construction time for
+ you.
+ """
+
if weather_data is not None:
self.weather_data = weather_data
return
@classmethod
@overrides
def load(cls) -> Any:
+
+ """Depending on whether we have fresh data persisted either uses that
+ data to instantiate the class or makes an HTTP request to fetch the
+ necessary data.
+
+ Note that because this is a subclass of Persistent this is taken
+ care of automatically.
+ """
+
if persistent.was_file_written_within_n_seconds(
config.config['weather_data_cachefile'],
config.config['weather_data_stalest_acceptable'].total_seconds(),
@overrides
def save(self) -> bool:
+ """
+ Saves the current data to disk if required. Again, because this is
+ a subclass of Persistent this is taken care of for you.
+ """
+
import pickle
with open(config.config['weather_data_cachefile'], 'wb') as wf: