10.5. Một API điều khiển cho camera¶
Chủ nhân cần đặt độ nhạy của bộ phát hiện chuyển động từ bất kỳ đâu -- gió làm cây rung nhiều hơn vào ngày có gió. Điều đó có nghĩa là các route mà bảng điều khiển có thể đọc các cài đặt hiện tại và đăng các thay đổi.
Một dict trạng thái chung nhỏ trên module là đủ để giữ các thông số điều chỉnh. Các trang sau bổ sung thêm khóa vào đó; hiện tại chỉ có một khóa:
state = {
'threshold': 12,
'frame_count': 0,
'trigger_count': 0,
}
10.5.1. GET để đọc, POST để ghi¶
Một cặp route -- một get, một post -- cho bảng điều khiển quyền truy cập đọc/ghi vào 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 trả về nội dung được phân tích cú pháp dưới dạng JSON, hoặc None nếu Content-Type không phải là application/json. Handler post xử lý từng trường hợp lỗi -- thiếu khóa, sai kiểu, ngoài phạm vi -- và thoát với microdot.abort(), hàm này ném ra microdot.HTTPException để ngắn mạch handler với trạng thái và thông báo đã cho.
10.5.2. GET, POST, PUT, DELETE¶
get() và post() là hai phương thức chúng ta sẽ sử dụng nhiều nhất. put() và delete() tồn tại cho các trường hợp tuân theo quy ước REST -- PUT /events/42 để thay thế sự kiện 42, DELETE /events/42 để xóa nó. Handler về cơ bản là giống nhau.
10.5.3. Đọc query strings và forms¶
Bảng điều khiển gửi JSON, vì vậy request.json là thứ chúng ta muốn. Hai cách khác mà camera có thể nhận dữ liệu:
args-- query string.?foo=1&bar=2trở thànhmicrodot.MultiDictbạn có thể đọc vớirequest.args.get('foo').form-- một HTML form được gửi dưới dạngapplication/x-www-form-urlencoded. Cùng kiểuMultiDict.
MultiDict giống dict nhưng cho phép một khóa mang nhiều giá trị (?tag=cat&tag=dog là hai giá trị tag); xem microdot.MultiDict để có toàn bộ giao diện.
10.5.4. Các phân đoạn URL động¶
Đường dẫn route có thể khai báo các placeholder có kiểu dữ liệu mà microdot truyền vào handler dưới dạng đối số bổ sung:
@app.get('/events/<int:event_id>')
async def get_event(request, event_id):
return {'id': event_id, 'msg': 'placeholder'}
Các bộ chuyển đổi được hỗ trợ là <int:>, <re:> cho regex tùy chỉnh, <path:> cho phân đoạn có thể chứa dấu gạch chéo, và mặc định (không có tiền tố) cho "khớp bất kỳ thứ gì đến dấu gạch chéo tiếp theo." <int:event_id> chấp nhận /events/42 và từ chối /events/abc -- sự từ chối trở thành 404 mà không cần handler chạy.
10.5.5. Phản hồi lỗi tùy chỉnh¶
404 mặc định mà microdot gửi là Not found thuần túy. Bảng điều khiển mong đợi JSON cho mọi phản hồi; ghi đè handler 404 để nó cũng trả về JSON:
@app.errorhandler(404)
async def not_found(request):
return {'error': 'not found', 'path': request.path}, 404
errorhandler() nhận một mã trạng thái (bắt mọi lỗi có trạng thái đó) hoặc một lớp ngoại lệ (bắt mọi handler ném ra ngoại lệ đó). Tuple (body, status) ngắn mạch phản hồi mà không cần xây dựng Response.
Camera bây giờ hiển thị trạng thái của nó và chấp nhận các chỉnh sửa.