10.5. Ett styr-API för kameran¶
Ägaren behöver kunna ställa in rörelsedetektorns känslighet varifrån som helst – vinden rör träden mer en blåsig dag. Det innebär rutter som instrumentpanelen kan läsa de aktuella inställningarna från och posta ändringar till.
En liten delad tillstånds-dict på modulen räcker för att hålla rattarna. Senare sidor lägger till fler nycklar i den; för tillfället finns det en:
state = {
'threshold': 12,
'frame_count': 0,
'trigger_count': 0,
}
10.5.1. GET för att läsa, POST för att skriva¶
Ett par rutter – en get, en post – ger instrumentpanelen läs-/skrivåtkomst till 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 returnerar kroppen tolkad som JSON, eller None om Content-Type inte var application/json. post-hanteraren går igenom varje felscenario – saknad nyckel, fel typ, utanför intervallet – och avbryter med microdot.abort(), som genererar microdot.HTTPException för att kortsluta hanteraren med den givna statusen och meddelandet.
10.5.2. GET, POST, PUT, DELETE¶
get() och post() är de två vi använder mest. put() och delete() finns för fall som följer REST-konventioner – ett PUT /events/42 för att ersätta händelse 42, ett DELETE /events/42 för att ta bort den. Hanteraren är i övrigt identisk.
10.5.3. Läsa frågesträngar och formulär¶
Instrumentpanelen postar JSON, så request.json är det vi vill ha. Två andra sätt som kameran kan ta emot data på:
args– frågesträngen.?foo=1&bar=2blir enmicrodot.MultiDictsom du kan läsa medrequest.args.get('foo').form– ett HTML-formulär postat somapplication/x-www-form-urlencoded. SammaMultiDict-typ.
MultiDict är dict-liknande men låter en nyckel bära flera värden (?tag=cat&tag=dog är två tag-värden); se microdot.MultiDict för det fullständiga gränssnittet.
10.5.4. Dynamiska URL-segment¶
En ruttsökväg kan deklarera typade platshållare som microdot skickar till hanteraren som extra argument:
@app.get('/events/<int:event_id>')
async def get_event(request, event_id):
return {'id': event_id, 'msg': 'placeholder'}
De konverterare som stöds är <int:>, <re:> för ett anpassat reguljärt uttryck, <path:> för ett segment som kan innehålla snedstreck, och standardvärdet (inget prefix) för ”matcha vad som helst fram till nästa snedstreck.” <int:event_id> accepterar /events/42 och avvisar /events/abc – avvisningen blir en 404 utan att hanteraren körs.
10.5.5. Anpassade felsvar¶
Standard-404:an som microdot skickar är vanlig Not found. Instrumentpanelen förväntar sig JSON för varje svar; åsidosätt 404-hanteraren så att den också returnerar JSON:
@app.errorhandler(404)
async def not_found(request):
return {'error': 'not found', 'path': request.path}, 404
errorhandler() tar antingen en statuskod (fångar varje fel med den statusen) eller en undantagsklass (fångar varje hanterare som genererade det undantaget). Tupeln (body, status) kortsluter svaret utan att konstruera ett Response.
Kameran exponerar nu sitt tillstånd och accepterar ändringar.