cb0b036e2650 — Arnaud Campeas[arnaud.campeas@pythonian.fr] 1 year, 1 month ago
http: backport horizon feature from tshistory
2 files changed, 87 insertions(+), 2 deletions(-)

M test/test_http.py
M tshistory_supervision/http.py
M test/test_http.py +66 -0
@@ 84,3 84,69 @@ 2020-01-01 00:00:00+00:00    False
 2020-01-02 00:00:00+00:00    False
 2020-01-03 00:00:00+00:00     True
 """, markers)
+
+
+def test_get_by_horizon(client):
+    ts = genserie(utcdt(2023, 1, 1), 'D', 60)
+    client.patch('/series/state', params={
+        'name': 'horizon',
+        'series': util.tojson(ts),
+        'author': 'Babar',
+        'insertion_date': utcdt(2023, 1, 1),
+        'tzaware': util.tzaware_series(ts),
+        'supervision': json.dumps(False),
+    })
+
+    res = client.get('/series/supervision', params={
+        'name': 'horizon',
+        'horizon': (
+            '(horizon #:date (date "2023-2-1")'
+            '         #:offset 0'
+            '         #:past (delta #:days -2) '
+            '         #:future (delta #:days 1))'
+        )
+    })
+    assert res.json == {
+        '2023-01-30T00:00:00.000Z': {'markers': False, 'series': 29.0},
+        '2023-01-31T00:00:00.000Z': {'markers': False, 'series': 30.0},
+        '2023-02-01T00:00:00.000Z': {'markers': False, 'series': 31.0},
+        '2023-02-02T00:00:00.000Z': {'markers': False, 'series': 32.0}
+    }
+    df = pd.read_json(res.text, orient='index')
+    ts = df['series']
+    ts[-1] = 42
+
+    client.patch('/series/state', params={
+        'name': 'horizon',
+        'series': util.tojson(ts),
+        'author': 'Babar',
+        'insertion_date': utcdt(2023, 1, 1, 1),
+        'tzaware': util.tzaware_series(ts),
+        'supervision': json.dumps(True),
+    })
+
+    res = client.get('/series/supervision', params={
+        'name': 'horizon',
+        'horizon': (
+            '(horizon #:date (date "2023-2-1")'
+            '         #:offset 0'
+            '         #:past (delta #:days -2) '
+            '         #:future (delta #:days 1))'
+        ),
+        'format': 'tshpack'
+    })
+    ts, marker = util.unpack_many_series(res.body)
+
+    assert_df("""
+2023-01-30 00:00:00+00:00    29.0
+2023-01-31 00:00:00+00:00    30.0
+2023-02-01 00:00:00+00:00    31.0
+2023-02-02 00:00:00+00:00    42.0
+""", ts)
+
+    assert_df("""
+2023-01-30 00:00:00+00:00    False
+2023-01-31 00:00:00+00:00    False
+2023-02-01 00:00:00+00:00    False
+2023-02-02 00:00:00+00:00     True
+""", marker)

          
M tshistory_supervision/http.py +21 -2
@@ 1,4 1,5 @@ 
 import pandas as pd
+from psyl import lisp
 
 from flask import make_response
 

          
@@ 19,6 20,8 @@ from tshistory.http.util import (
     onerror,
     utcdt
 )
+from tshistory.http.horizon import OPERATORS
+
 
 base = reqparse.RequestParser()
 base.add_argument(

          
@@ 42,6 45,10 @@ edited.add_argument(
 edited.add_argument(
     'format', type=enum('json', 'tshpack'), default='json'
 )
+edited.add_argument(
+    'horizon', type=str, default=None,
+    help='override from/to_value_date'
+)
 
 
 class supervision_httpapi(httpapi):

          
@@ 66,11 73,23 @@ class supervision_httpapi(httpapi):
                     if tsa.formula(args.name):
                         api.abort(404, f'`{args.name}` is a formula')
 
+                # handle the horizon parameter
+                fvd = args.from_value_date
+                tvd = args.to_value_date
+                hz = args.get('horizon')
+                if hz:
+                    env = lisp.Env(OPERATORS)
+                    try:
+                        horizon = lisp.evaluate(hz, env)
+                    except:
+                        api.abort(400, f'bad horizon expression for `{args.name}`')
+                    fvd = horizon.past
+                    tvd = horizon.future
                 series, markers = tsa.edited(
                     args.name,
                     revision_date=args.insertion_date,
-                    from_value_date=args.from_value_date,
-                    to_value_date=args.to_value_date,
+                    from_value_date=fvd,
+                    to_value_date=tvd,
                 )
                 metadata = tsa.metadata(args.name, all=True)
                 assert metadata is not None, f'series {args.name} has no metadata'