10.1. İlk uç noktanız¶
Kamera ilginç bir şey yapabilmeden önce, ağın geri kalanının ona erişebilmesi gerekir. Sunucunun çalıştığını kanıtlayan en ucuz yöntem, biraz JSON döndüren tek rotalı bir HTTP uç noktasıdır:
from microdot import Microdot
app = Microdot()
frame_count = 0
trigger_count = 0
@app.get('/status')
async def status(request):
return {'frames': frame_count, 'triggers': trigger_count}
app.run(host='0.0.0.0', port=80)
Bunu IDE’de çalıştırın. LAN üzerindeki başka herhangi bir makineden http://<cam-ip>/status adresini açın. Tarayıcı şunu gösterir:
{"frames": 0, "triggers": 0}
Sayaçlar yer tutuculardır – henüz hiçbir şey onlara dokunmuyor – ancak istek ağı geçti, kamera onu yönlendirdi, bir işleyici çalıştırdı ve geri JSON gönderdi.
10.1.1. Her satırın yaptığı iş¶
Betik başına bir microdot.Microdot örneği. Bu örnek, yönlendirme tablosunun, hata işleyicilerinin ve yaşam döngüsünün (başlat, sun, durdur) sahibidir. Büyük uygulamalar birkaç Python modülüne bölünür ama yine de tek bir app nesnesini paylaşır.
@app.get('/status') rota dekoratörüdür. Burada yalnızca microdot.Microdot.get() kullanıyoruz; post(), put() ve delete(), kamera yazma işlemlerini kabul etmeye başladığında ilerideki sayfalarda görünür.
Her rota işleyicisi bir asyncio eşyordamıdır ve isteği ilk argümanı olarak alır. İşleyicinin request kullanması zorunlu değildir – bu işleyici onu yok sayar – ama parametre her zaman oradadır, böylece imza tutarlı kalır.
JSON göndermenin en kısa yolu bir dict döndürmektir. Microdot dict’i otomatik olarak JSON’a serileştirir ve yanıtta Content-Type: application/json ayarlar. Bir dize döndürmek text/plain gönderir. Açıkça bir microdot.Response döndürmek uzun yoldur – gövde ikili olduğunda veya yanıt özel başlıklar istediğinde gereklidir.
app.run(host='0.0.0.0', port=80) sunucuyu başlatır. 0.0.0.0, kameranın sahip olduğu her arabirimde dinle anlamına gelir – hem kablolu ethernet hem de wifi STA, ikisi de etkinse. 80 numaralı bağlantı noktası HTTP varsayılanıdır, bu yüzden tarayıcıların bir bağlantı noktası numarası yazmasına gerek yoktur.
10.1.2. Bir istek, baştan sona¶
Telefon bir TCP bağlantısı açar, istek satırını ve başlıklarını yazar ve bekler. Kamera soketten baytları okur, bunları bir microdot.Request nesnesine ayrıştırır, yolu ve yöntemi yönlendirme tablosuyla eşleştirir, işleyici eşyordamını bekler (await), döndürdüğü her şeyi serileştirir, sokete bir durum satırı, başlıklar ve gövde yazar, ardından bağlantıyı kapatır (HTTP/1.0 varsayılanı) veya yeniden kullanır (Connection: keep-alive ile HTTP/1.1). Tüm bu alışveriş, ağ gidiş-dönüş süresi artı işleyicinin yaptığı her şey kadar sürer.
10.1.3. Engelleme hakkında bir not¶
run() engelleyicidir – sunucu durana kadar asla geri dönmez. Tek amaçlı bir sunucu için bu uygundur. Ayrıca çerçeve yakalayan veya başka eşyordamlar çalıştıran bir uygulama bunun yerine bir asyncio.run() içinde start_server() kullanır, böylece HTTP sunucusu döngüyü diğer her şeyle paylaşabilir.
Uygulama tek bir URL’ye yanıt verir.