10.5. Řídicí API pro kameru¶
Majitel potřebuje nastavit citlivost detektoru pohybu odkudkoli – za větrného dne se stromy hýbou víc. To znamená cesty, ze kterých dashboard může číst aktuální nastavení a odesílat do nich změny.
K uchování ovládacích prvků stačí malý sdílený slovník stavu na úrovni modulu. Pozdější stránky do něj přidají další klíče; prozatím je v něm jeden:
state = {
'threshold': 12,
'frame_count': 0,
'trigger_count': 0,
}
10.5.1. GET pro čtení, POST pro zápis¶
Dvojice cest – jedna get, jedna post – dává dashboardu přístup pro čtení i zápis ke state:
from microdot import abort
@app.get('/config')
async def get_config(request):
return state
@app.post('/config')
async def set_config(request):
body = request.json
if not body or 'threshold' not in body:
abort(400, 'missing threshold')
try:
threshold = int(body['threshold'])
except (TypeError, ValueError):
abort(400, 'threshold must be an integer')
if not 0 <= threshold <= 100:
abort(400, 'threshold out of range')
state['threshold'] = threshold
return {'ok': True, 'threshold': threshold}
microdot.Request.json vrací tělo parsované jako JSON, nebo None, pokud Content-Type nebyl application/json. Handler post projde každý režim selhání – chybějící klíč, špatný typ, mimo rozsah – a skončí pomocí microdot.abort(), který vyvolá microdot.HTTPException, aby handler zkratoval s daným stavem a zprávou.
10.5.2. GET, POST, PUT, DELETE¶
get() a post() jsou ty dvě, které budeme používat nejvíce. put() a delete() existují pro případy, které dodržují konvence REST – PUT /events/42 k nahrazení události 42, DELETE /events/42 k jejímu zahození. Handler je jinak identický.
10.5.3. Čtení query stringů a formulářů¶
Dashboard odesílá JSON, takže request.json je to, co chceme. Dva další způsoby, jak může kamera přijímat data:
args– query string.?foo=1&bar=2se stanemicrodot.MultiDict, který lze číst pomocírequest.args.get('foo').form– HTML formulář odeslaný jakoapplication/x-www-form-urlencoded. Stejný typMultiDict.
MultiDict je podobný slovníku, ale umožňuje, aby jeden klíč nesl více hodnot (?tag=cat&tag=dog jsou dvě hodnoty tag); úplné rozhraní viz microdot.MultiDict.
10.5.4. Dynamické segmenty URL¶
Cesta routy může deklarovat typované zástupné symboly, které microdot předá handleru jako další argumenty:
@app.get('/events/<int:event_id>')
async def get_event(request, event_id):
return {'id': event_id, 'msg': 'placeholder'}
Podporované převodníky jsou <int:>, <re:> pro vlastní regulární výraz, <path:> pro segment, který může obsahovat lomítka, a výchozí (bez prefixu) pro „vše až do dalšího lomítka.“ <int:event_id> přijme /events/42 a odmítne /events/abc – odmítnutí se stane stavem 404 bez spuštění handleru.
10.5.5. Vlastní chybové odpovědi¶
Výchozí 404, kterou microdot odesílá, je obyčejné Not found. Dashboard očekává JSON pro každou odpověď; přepište handler pro 404 tak, aby vracel také JSON:
@app.errorhandler(404)
async def not_found(request):
return {'error': 'not found', 'path': request.path}, 404
errorhandler() přijímá buď stavový kód (zachytí každou chybu daného stavu), nebo třídu výjimky (zachytí každý handler, který danou výjimku vyvolal). N-tice (body, status) zkratuje odpověď bez konstruování Response.
Kamera nyní zveřejňuje svůj stav a přijímá úpravy.