changeset 11:52ef21607b31

server: Create endpoint to get some recent readings.
author Paul Fisher <paul@pfish.zone>
date Sun, 06 Oct 2019 13:11:11 -0400
parents 6d59f038a58b
children 9e6289598d8c
files weather_server/common.py weather_server/server.py weather_server/types.py
diffstat 3 files changed, 50 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/weather_server/common.py	Sun Sep 29 20:42:11 2019 -0400
+++ b/weather_server/common.py	Sun Oct 06 13:11:11 2019 -0400
@@ -1,3 +1,5 @@
+import datetime
+import json
 import typing as t
 
 import bson
@@ -9,3 +11,22 @@
 
 def bson_encode(data: t.Dict[str, t.Any]) -> bytes:
     return bson.BSON.encode(data, codec_options=BSON_OPTIONS)
+
+
+class DateEncoder(json.JSONEncoder):
+
+    def default(self, o: t.Any) -> t.Any:
+        if not isinstance(o, datetime.datetime):
+            return super().default(o)
+        return o.timestamp()
+
+
+JSON_ENCODER = DateEncoder(sort_keys=True)
+
+
+def json_dumps(data: t.Any) -> str:
+    return JSON_ENCODER.encode(data)
+
+
+def utc_now():
+    return datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)
--- a/weather_server/server.py	Sun Sep 29 20:42:11 2019 -0400
+++ b/weather_server/server.py	Sun Oct 06 13:11:11 2019 -0400
@@ -1,3 +1,4 @@
+import datetime
 import hmac
 import sys
 
@@ -48,7 +49,7 @@
         return flask.jsonify({'status': 'OK'})
 
     @app.route('/<location>')
-    def show(location):
+    def show(location: str):
         try:
             loc, logger = locs.get(location)
         except KeyError:
@@ -67,6 +68,30 @@
             last_reading=last_reading,
             date=date)
 
+    @app.route('/<location>/recent')
+    def recent(location: str):
+        try:
+            loc, logger = locs.get(location)
+        except KeyError:
+            flask.abort(404)
+        req = flask.request
+
+        try:
+            seconds = int(req.args['seconds'])
+        except (KeyError, ValueError):
+            flask.abort(400)
+
+        start = common.utc_now() - datetime.timedelta(seconds=seconds)
+
+        readings = [
+            r.as_dict() for r in logger.data
+            if start < r.sample_time
+        ]
+        resp = flask.Response()
+        resp.content_type = 'application/json'
+        resp.data = common.json_dumps(readings)
+        return resp
+
     return app
 
 
--- a/weather_server/types.py	Sun Sep 29 20:42:11 2019 -0400
+++ b/weather_server/types.py	Sun Oct 06 13:11:11 2019 -0400
@@ -5,7 +5,8 @@
 import typing as t
 
 import attr
-import pytz
+
+from . import common
 
 
 def c_to_f(c: float) -> float:
@@ -55,14 +56,10 @@
 
     @classmethod
     def from_now(cls, **kwargs) -> 'Reading':
-        return cls(ingest_time=_utc_now(), **kwargs)
+        return cls(ingest_time=common.utc_now(), **kwargs)
 
     @property
     def _gamma(self) -> float:
         return (
             math.log(self.rh_pct / 100) +
             _MAGNUS_B * self.temp_c / (_MAGNUS_C + self.temp_c))
-
-
-def _utc_now():
-    return datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)