comparison light_bridge.py @ 27:32cfefe3155b

try harder to crash if there's an mqtt error, so k8s does a full restart
author drewp@bigasterisk.com
date Sat, 23 Mar 2024 15:25:02 -0700
parents cee43f550577
children
comparison
equal deleted inserted replaced
26:33b3eb24506e 27:32cfefe3155b
2 replaces a lot of mqtt_to_rdf and rdf_to_mqtt 2 replaces a lot of mqtt_to_rdf and rdf_to_mqtt
3 """ 3 """
4 import asyncio 4 import asyncio
5 import json 5 import json
6 import logging 6 import logging
7 import os
7 import time 8 import time
8 from functools import partial 9 from functools import partial
9 from color import Color
10 10
11 import uvicorn
11 from patchablegraph import PatchableGraph 12 from patchablegraph import PatchableGraph
12 from patchablegraph.handler import GraphEvents, StaticGraph 13 from patchablegraph.handler import GraphEvents, StaticGraph
13 from sse_starlette.sse import EventSourceResponse 14 from sse_starlette.sse import EventSourceResponse
14 from starlette.applications import Starlette 15 from starlette.applications import Starlette
15 from starlette.requests import Request 16 from starlette.requests import Request
16 from starlette.responses import JSONResponse 17 from starlette.responses import JSONResponse
17 from starlette.routing import Route 18 from starlette.routing import Route
18 from starlette_exporter import PrometheusMiddleware, handle_metrics 19 from starlette_exporter import PrometheusMiddleware, handle_metrics
19 20
21 from color import Color
20 from light import Lights 22 from light import Lights
21 from mqtt_io import MqttIo 23 from mqtt_io import MqttIo
24
22 logging.basicConfig(level=logging.INFO) 25 logging.basicConfig(level=logging.INFO)
23 log = logging.getLogger() 26 log = logging.getLogger()
24 27
25 28
26 async def output(lights: Lights, request: Request) -> JSONResponse: 29 async def output(lights: Lights, request: Request) -> JSONResponse:
27 light = lights.byName(request.query_params['light']) 30 light = lights.byName(request.query_params['light'])
28 body = (await request.body()).decode('utf8') 31 body = (await request.body()).decode('utf8')
29 await light.setColor(Color.fromHex(body)) 32 await light.setColor(Color.fromHex(body))
30 return JSONResponse(light.to_dict()) 33 return JSONResponse(light.to_dict())
34
31 35
32 async def lightNames(lights: Lights, request: Request) -> JSONResponse: 36 async def lightNames(lights: Lights, request: Request) -> JSONResponse:
33 return JSONResponse({'lightNames': lights.allNames()}) 37 return JSONResponse({'lightNames': lights.allNames()})
34 38
35 39
46 await asyncio.sleep(.5) # slow down the inf loop 50 await asyncio.sleep(.5) # slow down the inf loop
47 51
48 return EventSourceResponse(g()) 52 return EventSourceResponse(g())
49 53
50 54
55 def crash(request: Request):
56 log.info('crash requested')
57 os.abort()
58
59
51 def main(): 60 def main():
52 mqtt = MqttIo() 61 mqtt = MqttIo()
53 lights = Lights(mqtt) 62 lights = Lights(mqtt)
54 graph = PatchableGraph() 63 graph = PatchableGraph()
55 app = Starlette(debug=True, 64 app = Starlette(debug=True,
57 Route('/api/output', partial(output, lights), methods=['PUT']), 66 Route('/api/output', partial(output, lights), methods=['PUT']),
58 Route('/api/lightNames', partial(lightNames, lights), methods=['GET']), 67 Route('/api/lightNames', partial(lightNames, lights), methods=['GET']),
59 Route('/api/table', partial(table, lights)), 68 Route('/api/table', partial(table, lights)),
60 Route('/api/graph', StaticGraph(graph)), 69 Route('/api/graph', StaticGraph(graph)),
61 Route('/api/graph/events', GraphEvents(graph)), 70 Route('/api/graph/events', GraphEvents(graph)),
71 Route('/api/crash', crash),
62 ]) 72 ])
63 73
64 app.add_middleware(PrometheusMiddleware, app_name='light-bridge') 74 app.add_middleware(PrometheusMiddleware, app_name='light-bridge')
65 app.add_route("/metrics", handle_metrics) 75 app.add_route("/metrics", handle_metrics)
66 76
67 return app 77 return app
68 78
69 79
70 app = main() 80 uvicorn.run(main, host="0.0.0.0", port=8001, log_level=logging.INFO, factory=True)