diff environment.py @ 3:e7f33fa31883

port to starlette/asyncio
author drewp@bigasterisk.com
date Sun, 24 Apr 2022 14:46:32 -0700
parents 0f532eb91364
children b5bfd0dd69d6
line wrap: on
line diff
--- a/environment.py	Fri Apr 01 00:44:01 2022 -0700
+++ b/environment.py	Sun Apr 24 14:46:32 2022 -0700
@@ -4,51 +4,37 @@
 daytime/night, overall modes like 'maintenance mode', etc
 
 """
+import asyncio
 import datetime
-
-import cyclone.web
+import logging
 from dateutil.relativedelta import FR, relativedelta
 from dateutil.tz import tzlocal
-from docopt import docopt
+from prometheus_client import Gauge, Summary
 from rdflib import Literal, Namespace
-from twisted.internet import defer, reactor, task
+from starlette.applications import Starlette
+from starlette.routing import Route
+from starlette.staticfiles import StaticFiles
+from starlette_exporter import PrometheusMiddleware, handle_metrics
 
-from standardservice.logsetup import log, verboseLogging
-from patchablegraph import (CycloneGraphEventsHandler, CycloneGraphHandler, PatchableGraph)
-
-from patch_cyclone import patch_sse
-from rdfdoc import Doc
+import background_loop
+from patchablegraph import PatchableGraph
+from patchablegraph.handler import StaticGraph, GraphEvents
+# from rdfdoc import Doc
 from twilight import isWithinTwilight
 
-patch_sse()
-
 ROOM = Namespace("http://projects.bigasterisk.com/room/")
 DEV = Namespace("http://projects.bigasterisk.com/device/")
 
-# STATS = scales.collection(
-#     '/root',
-#     scales.PmfStat('update'),
-# )
+logging.basicConfig(level=logging.INFO)
+
+STAT_UPDATE_UP = Gauge('background_loop_up', 'not erroring')
+STAT_UPDATE_CALLS = Summary('background_loop_calls', 'calls')
 
 
-# see pending fix in patchablegraph.py
-class CycloneGraphEventsHandlerWithCors(CycloneGraphEventsHandler):
-
-    def __init__(self, application, request, masterGraph, allowOrigins=None):
-        super().__init__(application, request, masterGraph)
-        self.allowOrigins = allowOrigins or []
+def update(masterGraph):
 
-    def flush(self):
-        origin = self.request.headers.get('origin', None)
-        if origin and origin in self.allowOrigins:
-            self.set_header(b"Access-Control-Allow-Origin", origin.encode('utf8'))
-            self.set_header(b"Access-Control-Allow-Credentials", b"true")
-        return CycloneGraphEventsHandler.flush(self)
-
-
-# @STATS.update.time()
-def update(masterGraph):
-    stmt = lambda s, p, o: masterGraph.patchObject(ROOM.environment, s, p, o)
+    def stmt(s, p, o):
+        masterGraph.patchObject(ROOM.environment, s, p, o)
 
     now = datetime.datetime.now(tzlocal())
 
@@ -70,41 +56,22 @@
 
 
 def main():
-    arg = docopt("""
-    Usage: environment.py [options]
-
-    -v                    Verbose
-    """)
-    verboseLogging(arg['-v'])
-
     masterGraph = PatchableGraph()
 
-    class Application(cyclone.web.Application):
+    asyncio.create_task(background_loop.loop_forever(lambda first: update(masterGraph), 1, STAT_UPDATE_UP, STAT_UPDATE_CALLS))
 
-        def __init__(self):
-            handlers = [
-                (r"/()", cyclone.web.StaticFileHandler, {
-                    "path": ".",
-                    "default_filename": "index.html"
-                }),
-                (r'/graph/environment', CycloneGraphHandler, {
-                    'masterGraph': masterGraph
-                }),
-                (r'/graph/environment/events', CycloneGraphEventsHandlerWithCors, {
-                    'masterGraph': masterGraph,
-                    'allowOrigins': ['http://localhost:8001'],
-                }),
-                (r'/doc', Doc),  # to be shared
-                # (r'/stats/(.*)', StatsHandler, {
-                #     'serverName': 'environment'
-                # }),
-            ]
-            cyclone.web.Application.__init__(self, handlers, masterGraph=masterGraph)
+    app = Starlette(
+        debug=True,
+        routes=[
+            Route('/', StaticFiles(directory='.', html=True)),
+            Route('/graph/environment', StaticGraph(masterGraph)),
+            Route('/graph/environment/events', GraphEvents(masterGraph)),
+            # Route('/doc', Doc),
+        ])
 
-    task.LoopingCall(update, masterGraph).start(1)
-    reactor.listenTCP(8000, Application())
-    reactor.run()
+    app.add_middleware(PrometheusMiddleware, app_name='environment')
+    app.add_route("/metrics", handle_metrics)
+    return app
 
 
-if __name__ == '__main__':
-    main()
+app = main()