10.5. API керування камерою¶
Власникові потрібно налаштовувати чутливість детектора руху звідусіль – у вітряний день вітер рухає деревами більше. Це означає маршрути, з яких панель моніторингу може читати поточні налаштування і публікувати зміни.
Невеликий спільний словник стану на рівні модуля достатній для зберігання параметрів. На наступних сторінках до нього додаються нові ключі; поки що є лише один:
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, або None, якщо Content-Type не був application/json. Обробник 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– HTML-форма, опублікована якapplication/x-www-form-urlencoded. Той самий тип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. Нестандартні відповіді на помилки¶
Стандартне повідомлення 404 від microdot – це простий текст 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.
Камера тепер відкриває свій стан і приймає зміни.