10.5. Ohjaus-API kameralle

Omistajan täytyy voida säätää liiketunnistimen herkkyyttä mistä tahansa – tuuli liikuttaa puita enemmän tuulisena päivänä. Se tarkoittaa reittejä, joista kojelauta voi lukea nykyiset asetukset ja joihin se voi lähettää muutoksia.

Pieni jaettu tilasanakirja moduulissa riittää pitämään säätimet. Myöhemmät sivut lisäävät siihen lisää avaimia; toistaiseksi niitä on yksi:

state = {
    'threshold': 12,
    'frame_count': 0,
    'trigger_count': 0,
}

10.5.1. GET lukemiseen, POST kirjoittamiseen

Reittipari – yksi get, yksi post – antaa kojelaudalle luku- ja kirjoitusoikeuden sanakirjaan 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 palauttaa rungon JSON:ksi jäsennettynä, tai None, jos Content-Type ei ollut application/json. post-käsittelijä käy läpi jokaisen vikatilanteen – puuttuva avain, väärä tyyppi, alueen ulkopuolella – ja keskeyttää funktiolla microdot.abort(), joka nostaa microdot.HTTPException-poikkeuksen oikosulkeakseen käsittelijän annetulla statuksella ja viestillä.

10.5.2. GET, POST, PUT, DELETE

get() ja post() ovat ne kaksi, joita käytämme eniten. put() ja delete() ovat olemassa tapauksiin, jotka noudattavat REST-konventioita – PUT /events/42 korvaamaan tapahtuman 42, DELETE /events/42 poistamaan sen. Käsittelijä on muuten identtinen.

10.5.3. Kyselymerkkijonojen ja lomakkeiden lukeminen

Kojelauta lähettää JSON:ia, joten request.json on se mitä haluamme. Kaksi muuta tapaa, joilla kamera voi vastaanottaa dataa:

  • args – kyselymerkkijono. ?foo=1&bar=2 muuttuu microdot.MultiDict-olioksi, jota voit lukea kutsulla request.args.get('foo').

  • form – HTML-lomake lähetettynä muodossa application/x-www-form-urlencoded. Sama MultiDict-tyyppi.

MultiDict on sanakirjamainen, mutta antaa yhden avaimen kantaa useita arvoja (?tag=cat&tag=dog on kaksi tag-arvoa); katso microdot.MultiDict koko rajapinnan osalta.

10.5.4. Dynaamiset URL-segmentit

Reittipolku voi ilmoittaa tyypitettyjä paikanvaraajia, jotka microdot välittää käsittelijälle ylimääräisinä argumentteina:

@app.get('/events/<int:event_id>')
async def get_event(request, event_id):
    return {'id': event_id, 'msg': 'placeholder'}

Tuetut muuntimet ovat <int:>, <re:> mukautetulle säännölliselle lausekkeelle, <path:> segmentille joka voi sisältää kauttaviivoja, sekä oletus (ei etuliitettä) merkitykseen ”täsmää mihin tahansa seuraavaan kauttaviivaan asti.” <int:event_id> hyväksyy /events/42 ja hylkää /events/abc – hylkäyksestä tulee 404 ilman, että käsittelijää suoritetaan.

10.5.5. Mukautetut virhevastaukset

Oletusarvoinen 404, jonka microdot lähettää, on pelkkä Not found. Kojelauta odottaa JSON:ia jokaiseen vastaukseen; ohita 404-käsittelijä niin, että se palauttaa myös JSON:ia:

@app.errorhandler(404)
async def not_found(request):
    return {'error': 'not found', 'path': request.path}, 404

errorhandler() ottaa joko statuskoodin (nappaa jokaisen kyseisen statuksen virheen) tai poikkeusluokan (nappaa jokaisen käsittelijän, joka nosti kyseisen poikkeuksen). (body, status)-monikko oikosulkee vastauksen rakentamatta Response-oliota.

Kamera paljastaa nyt tilansa ja hyväksyy muokkauksia.