Skip to content

Commit

Permalink
filter forecasts with times ending in past (#49)
Browse files Browse the repository at this point in the history
* filter_forecasts

* pin isort

* use strptime for 3.6 compatibility

* remove colon for 3.6

* black and lint
  • Loading branch information
MatthewFlamm authored Jul 18, 2020
1 parent f533bbd commit e3e87bd
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 11 deletions.
1 change: 1 addition & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ ignore=tests
disable=invalid-name,
too-many-instance-attributes,
too-many-arguments,
too-many-branches,
duplicate-code,
format
1 change: 1 addition & 0 deletions example.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import asyncio

import aiohttp

import pynws

PHILLY = (39.95, -75.16)
Expand Down
31 changes: 24 additions & 7 deletions pynws/simple_nws.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Support for NWS weather service."""
from datetime import datetime, timedelta, timezone
from statistics import mean

from metar import Metar
Expand Down Expand Up @@ -159,13 +160,17 @@ async def update_observation(self, limit=0, start_time=None):
self._observation = obs
self._metar_obs = [self.extract_metar(iobs) for iobs in self._observation]

async def update_forecast(self):
async def update_forecast(self, filter_time=True):
"""Update forecast."""
self._forecast = await self.get_gridpoints_forecast()
self._forecast = self._convert_forecast(
await self.get_gridpoints_forecast(), filter_time
)

async def update_forecast_hourly(self):
async def update_forecast_hourly(self, filter_time=True):
"""Update forecast."""
self._forecast_hourly = await self.get_gridpoints_forecast_hourly()
self._forecast_hourly = self._convert_forecast(
await self.get_gridpoints_forecast_hourly(), filter_time
)

@staticmethod
def _unique_alert_ids(alerts):
Expand Down Expand Up @@ -281,21 +286,33 @@ def observation(self):
@property
def forecast(self):
"""Return forecast."""
return self._convert_forecast(self._forecast)
return self._forecast

@property
def forecast_hourly(self):
"""Return forecast hourly."""
return self._convert_forecast(self._forecast_hourly)
return self._forecast_hourly

@staticmethod
def _convert_forecast(input_forecast):
def _convert_forecast(input_forecast, filter_time):
"""Converts forecast to common dict."""
if not input_forecast:
return []
forecast = []
for forecast_entry in input_forecast:
# get weather
if filter_time:
end_time = forecast_entry.get("endTime")
if not end_time:
continue
# needed for python 3.6
# https://stackoverflow.com/questions/30999230/how-to-parse-timezone-with-colon
if end_time[-3] == ":":
end_time = end_time[:-3] + end_time[-2:]
if datetime.now(timezone.utc) - datetime.strptime(
end_time, "%Y-%m-%dT%H:%M:%S%z"
) > timedelta(seconds=0):
continue
if forecast_entry.get("temperature"):
forecast_entry["temperature"] = int(forecast_entry["temperature"])

Expand Down
3 changes: 2 additions & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
aiohttp
freezegun
metar
black
isort
isort<5
pylint
pytest
pytest-asyncio
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ def mock_urls():
mock_gridpoints_forecast_hourly_url.return_value = "/gridpoints_forecast_hourly"
mock_points_stations_url.return_value = "/points_stations"
mock_alerts_active_zone_url.return_value = "/alerts_active_zone"

yield mock_stations_observations_url, mock_points_url, mock_gridpoints_forecast_url, mock_gridpoints_forecast_hourly_url, mock_points_stations_url, mock_alerts_active_zone_url
26 changes: 23 additions & 3 deletions tests/test_simple_nws.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pynws import NwsError, SimpleNWS
from freezegun import freeze_time
import pytest

from pynws import NwsError, SimpleNWS
from tests.helpers import data_return_function, setup_app

LATLON = (0, 0)
Expand Down Expand Up @@ -150,6 +151,7 @@ async def test_nws_observation_missing_value(aiohttp_client, loop, mock_urls):
assert observation["iconWeather"] is None


@freeze_time("2019-10-13T14:30:00-04:00")
async def test_nws_forecast(aiohttp_client, loop, mock_urls):
app = setup_app()
client = await aiohttp_client(app)
Expand All @@ -165,16 +167,33 @@ async def test_nws_forecast(aiohttp_client, loop, mock_urls):
assert forecast[0]["windBearing"] == 180


@freeze_time("2019-10-14T21:30:00-04:00")
async def test_nws_forecast_discard_stale(aiohttp_client, loop, mock_urls):
app = setup_app()
client = await aiohttp_client(app)
nws = SimpleNWS(*LATLON, USERID, client)
await nws.update_forecast_hourly(filter_time=True)
forecast = nws.forecast_hourly
assert forecast[0]["temperature"] == 77

await nws.update_forecast_hourly(filter_time=False)
forecast = nws.forecast_hourly

assert forecast[0]["temperature"] == 78


@freeze_time("2019-10-14T20:30:00-04:00")
async def test_nws_forecast_hourly(aiohttp_client, loop, mock_urls):
app = setup_app()
client = await aiohttp_client(app)
nws = SimpleNWS(*LATLON, USERID, client)
await nws.update_forecast_hourly()
forecast = nws.forecast_hourly

assert forecast
assert forecast[0]["temperature"] == 78


@freeze_time("2019-10-13T14:30:00-04:00")
async def test_nws_forecast_strings(aiohttp_client, loop, mock_urls):
app = setup_app(gridpoints_forecast="gridpoints_forecast_strings.json")
client = await aiohttp_client(app)
Expand All @@ -190,14 +209,15 @@ async def test_nws_forecast_strings(aiohttp_client, loop, mock_urls):
assert forecast[0]["windBearing"] == 180


@freeze_time("2019-10-13T14:30:00-04:00")
async def test_nws_forecast_empty(aiohttp_client, loop, mock_urls):
app = setup_app(gridpoints_forecast="gridpoints_forecast_empty.json")
client = await aiohttp_client(app)
nws = SimpleNWS(*LATLON, USERID, client)
await nws.update_forecast()
forecast = nws.forecast

assert forecast
assert forecast == []


async def test_nws_alerts_forecast_zone(aiohttp_client, loop, mock_urls):
Expand Down

0 comments on commit e3e87bd

Please sign in to comment.