10.5. Control API สำหรับกล้อง¶
เจ้าของต้องการตั้งค่าความไวของระบบตรวจจับการเคลื่อนไหวจากทุกที่ — วันที่ลมแรง ต้นไม้เคลื่อนไหวมากขึ้น ซึ่งหมายความว่าต้องมี route ที่แดชบอร์ดสามารถอ่านค่าการตั้งค่าปัจจุบันและส่งการเปลี่ยนแปลงได้
dict สถานะขนาดเล็กที่แชร์บนโมดูลก็เพียงพอสำหรับเก็บค่าที่ปรับได้ หน้าถัดไปจะเพิ่ม key เพิ่มเติม ตอนนี้มีแค่หนึ่ง:
state = {
'threshold': 12,
'frame_count': 0,
'trigger_count': 0,
}
10.5.1. GET เพื่ออ่าน POST เพื่อเขียน¶
route คู่หนึ่ง — 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 คืนค่า body ที่แยกวิเคราะห์เป็น JSON หรือ None หาก Content-Type ไม่ใช่ application/json handler ของ post ตรวจสอบทุกโหมดความล้มเหลว — key หาย, ประเภทผิด, ค่าเกินขอบเขต — และหยุดด้วย microdot.abort() ซึ่ง raise microdot.HTTPException เพื่อลัด handler ด้วยสถานะและข้อความที่กำหนด
10.5.2. GET, POST, PUT, DELETE¶
get() และ post() คือสองตัวที่เราจะใช้มากที่สุด put() และ delete() มีไว้สำหรับกรณีที่ปฏิบัติตาม REST convention — PUT /events/42 เพื่อแทนที่ event 42, DELETE /events/42 เพื่อลบออก handler ส่วนที่เหลือเหมือนกัน
10.5.3. การอ่าน query string และ form¶
แดชบอร์ดส่ง JSON ดังนั้น request.json คือสิ่งที่เราต้องการ อีกสองวิธีที่กล้องอาจรับข้อมูล:
args— query string?foo=1&bar=2กลายเป็นmicrodot.MultiDictที่อ่านได้ด้วยrequest.args.get('foo')form— HTML form ที่ส่งเป็นapplication/x-www-form-urlencodedใช้ประเภทMultiDictเดียวกัน
MultiDict ทำงานเหมือน dict แต่ให้ key หนึ่งรองรับหลายค่าได้ (?tag=cat&tag=dog คือค่า tag สองค่า) ดู microdot.MultiDict สำหรับ API ครบถ้วน
10.5.4. URL segment แบบ dynamic¶
path ของ route สามารถประกาศ placeholder ที่มีประเภทกำกับ ซึ่ง microdot จะส่งไปยัง handler เป็นอาร์กิวเมนต์เพิ่มเติม:
@app.get('/events/<int:event_id>')
async def get_event(request, event_id):
return {'id': event_id, 'msg': 'placeholder'}
converter ที่รองรับคือ <int:>, <re:> สำหรับ regex แบบกำหนดเอง, <path:> สำหรับ segment ที่มี slash ได้ และค่าเริ่มต้น (ไม่มี prefix) สำหรับ "จับคู่อะไรก็ได้จนถึง slash ถัดไป" <int:event_id> รับ /events/42 และปฏิเสธ /events/abc — การปฏิเสธกลายเป็น 404 โดยไม่รัน handler
10.5.5. Custom error response¶
404 ค่าเริ่มต้นที่ microdot ส่งคือ Not found ธรรมดา แดชบอร์ดคาดหวัง JSON สำหรับทุก response ดังนั้นให้ override handler ของ 404 ให้คืนค่า JSON ด้วย:
@app.errorhandler(404)
async def not_found(request):
return {'error': 'not found', 'path': request.path}, 404
errorhandler() รับทั้ง status code (จับทุก error ที่มีสถานะนั้น) หรือ exception class (จับทุก handler ที่ raise exception นั้น) tuple แบบ (body, status) ลัด response โดยไม่ต้องสร้าง Response
กล้องตอนนี้เปิดเผยสถานะและรับการแก้ไขได้แล้ว