10.5. Kamera için bir kontrol API’si

Sahibinin, hareket dedektörünün hassasiyetini her yerden ayarlaması gerekir; rüzgar, rüzgarlı bir günde ağaçları daha çok hareket ettirir. Bu, panonun mevcut ayarları okuyabileceği ve değişiklikleri gönderebileceği rotalar anlamına gelir.

Düğmeleri tutmak için modül üzerinde küçük bir paylaşılan durum sözlüğü yeterlidir. Sonraki sayfalar buna daha fazla anahtar ekler; şimdilik bir tane var:

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

10.5.1. Okumak için GET, yazmak için POST

Bir çift rota – biri get, biri post – panoya state üzerinde okuma/yazma erişimi verir:

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, gövdeyi JSON olarak ayrıştırılmış şekilde döndürür veya Content-Type application/json değilse None döndürür. post işleyicisi her hata durumunu – eksik anahtar, yanlış tür, aralık dışı – gezer ve microdot.abort() ile çıkar; bu, işleyiciyi verilen durum ve mesajla kısa devre yapmak için microdot.HTTPException oluşturur.

10.5.2. GET, POST, PUT, DELETE

get() ve post(), en çok kullanacağımız ikisidir. put() ve delete(), REST kurallarına uyan durumlar için vardır; 42 numaralı olayı değiştirmek için PUT /events/42, onu kaldırmak için DELETE /events/42. İşleyici bunun dışında aynıdır.

10.5.3. Sorgu dizgelerini ve formları okuma

Pano JSON gönderir, bu nedenle istediğimiz şey request.json olur. Kameranın veri alabileceği diğer iki yol:

  • args – sorgu dizgesi. ?foo=1&bar=2, request.args.get('foo') ile okuyabileceğiniz bir microdot.MultiDict olur.

  • formapplication/x-www-form-urlencoded olarak gönderilen bir HTML formu. Aynı MultiDict türü.

MultiDict, sözlük gibidir ancak bir anahtarın birden çok değer taşımasına izin verir (?tag=cat&tag=dog iki tag değeridir); tam yüzey için microdot.MultiDict belgesine bakın.

10.5.4. Dinamik URL segmentleri

Bir rota yolu, microdot’un işleyiciye ekstra argümanlar olarak ilettiği türlenmiş yer tutucular bildirebilir:

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

Desteklenen dönüştürücüler <int:>, özel bir düzenli ifade için <re:>, eğik çizgi içerebilen bir segment için <path:> ve varsayılan (ön ek yok) olan “bir sonraki eğik çizgiye kadar herhangi bir şeyle eşleş” şeklindedir. <int:event_id>, /events/42 ifadesini kabul eder ve /events/abc ifadesini reddeder; reddetme, işleyici çalışmadan bir 404 olur.

10.5.5. Özel hata yanıtları

microdot’un gönderdiği varsayılan 404, düz Not found ifadesidir. Pano her yanıt için JSON bekler; 404 işleyicisini geçersiz kılın, böylece o da JSON döndürür:

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

errorhandler(), ya bir durum kodu (o durumun her hatasını yakalar) ya da bir istisna sınıfı (o istisnayı oluşturan her işleyiciyi yakalar) alır. (body, status) demeti, bir Response oluşturmadan yanıtı kısa devre yapar.

Kamera artık durumunu açığa çıkarır ve düzenlemeleri kabul eder.