comparison environment.py @ 9:145779f2d79d

wedge in an allow-origin response for tests that aren't serving on our domain
author drewp@bigasterisk.com
date Sun, 07 May 2023 16:00:19 -0700
parents b5bfd0dd69d6
children
comparison
equal deleted inserted replaced
8:92e31a078643 9:145779f2d79d
4 daytime/night, overall modes like 'maintenance mode', etc 4 daytime/night, overall modes like 'maintenance mode', etc
5 5
6 """ 6 """
7 import datetime 7 import datetime
8 import logging 8 import logging
9 import os
9 10
10 import background_loop 11 import background_loop
11 from dateutil.relativedelta import FR, relativedelta 12 from dateutil.relativedelta import FR, relativedelta
12 from dateutil.tz import tzlocal 13 from dateutil.tz import tzlocal
13 from patchablegraph import PatchableGraph 14 from patchablegraph import PatchableGraph
14 from patchablegraph.handler import GraphEvents, StaticGraph 15 from patchablegraph.handler import GraphEvents, StaticGraph
15 from rdflib import Literal, Namespace 16 from rdflib import Literal, Namespace
17 from sse_starlette import EventSourceResponse, ServerSentEvent
16 from starlette.applications import Starlette 18 from starlette.applications import Starlette
19 from starlette.requests import Request
17 from starlette.routing import Route 20 from starlette.routing import Route
18 from starlette.staticfiles import StaticFiles 21 from starlette.staticfiles import StaticFiles
19 from starlette_exporter import PrometheusMiddleware, handle_metrics 22 from starlette_exporter import PrometheusMiddleware, handle_metrics
20 23
21 # from rdfdoc import Doc 24 # from rdfdoc import Doc
25 DEV = Namespace("http://projects.bigasterisk.com/device/") 28 DEV = Namespace("http://projects.bigasterisk.com/device/")
26 29
27 logging.basicConfig(level=logging.INFO) 30 logging.basicConfig(level=logging.INFO)
28 logging.getLogger('patchablegraph').setLevel(logging.WARNING) 31 logging.getLogger('patchablegraph').setLevel(logging.WARNING)
29 32
33 allowOrigin = os.environ.get('ALLOW_ORIGIN', '')
34
35 # factor this back into GraphEvents
36 def GE2(masterGraph:PatchableGraph):
37
38 async def generateEvents():
39 events = masterGraph.subscribeToPatches()
40 while True: # we'll get cancelled by EventSourceResponse when the conn drops
41 etype, data = await events.get()
42 # Are there more to get? We might throttle and combine patches here- ideally we could see how
43 # long the latency to the client is to make a better rate choice
44 yield ServerSentEvent(event=etype, data=data)
45
46 async def handle(request: Request):
47 """
48 One session with one client.
49
50 returns current graph plus future patches to keep remote version
51 in sync with ours.
52
53 instead of turning off buffering all over, it may work for this
54 response to send 'x-accel-buffering: no', per
55 http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering
56 """
57 headers = {}
58 if allowOrigin:
59 headers={'Access-Control-Allow-Origin':allowOrigin}
60 return EventSourceResponse(generateEvents(), headers=headers)
61
62 return handle
30 63
31 def update(masterGraph): 64 def update(masterGraph):
32 65
33 def stmt(s, p, o): 66 def stmt(s, p, o):
34 masterGraph.patchObject(ROOM.environment, s, p, o) 67 masterGraph.patchObject(ROOM.environment, s, p, o)
60 app = Starlette( 93 app = Starlette(
61 debug=True, 94 debug=True,
62 routes=[ 95 routes=[
63 Route('/', StaticFiles(directory='.', html=True)), 96 Route('/', StaticFiles(directory='.', html=True)),
64 Route('/graph/environment', StaticGraph(masterGraph)), 97 Route('/graph/environment', StaticGraph(masterGraph)),
65 Route('/graph/environment/events', GraphEvents(masterGraph)), 98 Route('/graph/environment/events', GE2(masterGraph)),
66 # Route('/doc', Doc), 99 # Route('/doc', Doc),
67 ]) 100 ])
68 101
69 app.add_middleware(PrometheusMiddleware, app_name='environment') 102 app.add_middleware(PrometheusMiddleware, app_name='environment')
70 app.add_route("/metrics", handle_metrics) 103 app.add_route("/metrics", handle_metrics)