10.5. 相機的控制 API¶
擁有者需要能從任何地方設定動作偵測器的靈敏度——在颳風的日子裡,風會更劇烈地搖動樹木。這代表需要一些路由,讓儀表板可以從中讀取目前的設定,並向其張貼變更。
模組上一個小巧的共享狀態 dict 就足以容納這些調節旋鈕。後續的頁面會為它加入更多鍵;目前只有一個:
state = {
'threshold': 12,
'frame_count': 0,
'trigger_count': 0,
}
10.5.1. 以 GET 讀取,以 POST 寫入¶
一對路由——一個 get、一個 post——讓儀表板對 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 會回傳解析為 JSON 的主體,若 Content-Type 不是 application/json 則回傳 None。post 處理常式會逐一走過每一種故障模式——缺少鍵、型別錯誤、超出範圍——並以 microdot.abort() 中止,後者會拋出 microdot.HTTPException,以給定的狀態與訊息將處理常式短路。
10.5.2. GET、POST、PUT、DELETE¶
get() 與 post() 是我們最常用的兩個。put() 與 delete() 則為遵循 REST 慣例的情況而存在——以 PUT /events/42 取代事件 42,以 DELETE /events/42 將其刪除。處理常式在其餘方面則完全相同。
10.5.3. 讀取查詢字串與表單¶
儀表板張貼的是 JSON,所以 request.json 正是我們要的。相機還可能透過另外兩種方式接收資料:
args——查詢字串。?foo=1&bar=2會變成一個microdot.MultiDict,你可以用request.args.get('foo')讀取它。form——以application/x-www-form-urlencoded張貼的 HTML 表單。同樣是MultiDict型別。
MultiDict 類似 dict,但允許一個鍵攜帶多個值(?tag=cat&tag=dog 就是兩個 tag 值);完整介面請參閱 microdot.MultiDict。
10.5.4. 動態 URL 區段¶
路由路徑可以宣告具型別的佔位符,microdot 會把它們作為額外引數傳給處理常式:
@app.get('/events/<int:event_id>')
async def get_event(request, event_id):
return {'id': event_id, 'msg': 'placeholder'}
支援的轉換器有 <int:>、用於自訂正規表示式的 <re:>、用於可包含斜線之區段的 <path:>,以及預設(無前綴)的「比對直到下一個斜線為止的任何內容」。<int:event_id> 接受 /events/42 並拒絕 /events/abc——遭拒會變成 404,處理常式不會執行。
10.5.5. 自訂錯誤回應¶
microdot 預設送出的 404 是純文字的 Not found。儀表板期望每個回應都是 JSON;請覆寫 404 處理常式,讓它同樣回傳 JSON:
@app.errorhandler(404)
async def not_found(request):
return {'error': 'not found', 'path': request.path}, 404
errorhandler() 接受狀態碼(攔截該狀態的所有錯誤)或例外類別(攔截每一個拋出該例外的處理常式)。(body, status) 元組會將回應短路,而無需建構一個 Response。
相機現在會公開其狀態並接受編輯了。