fix(birdnet-pipy): serve API via gunicorn + gevent worker

Replace the legacy Werkzeug dev server (python -m core.api) with a single
gunicorn GeventWebSocketWorker, matching upstream BirdNET-PiPy 0.7.0's
production-server migration (the add-on already builds 0.7.0 source).

Single worker is mandatory: live detections fan out via an in-process
Socket.IO emit (no Redis message_queue), so >1 worker would silently drop
Live Feed broadcasts. Heavy maintenance jobs cooperatively yield to keep the
worker responsive. Bound to 127.0.0.1:5002 for single-container use. Also
fixes the now-stale 'Python core.api' comment in nginx/run.

Add-on packaging change only -> 0.7.0 -> 0.7.0-1 (suffix convention; base
tracks upstream via the updater bot).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yudong Sun
2026-05-19 08:32:34 -04:00
parent cc0510b653
commit 896adcd858
4 changed files with 18 additions and 3 deletions

View File

@@ -1,4 +1,7 @@
## 0.7.0-1 (2026-05-19)
- Serve the API via gunicorn + a gevent-websocket worker instead of the Werkzeug development server
## 0.7.0 (2026-05-19)
- Update to latest version from Suncuss/BirdNET-PiPy (changelog : https://github.com/Suncuss/BirdNET-PiPy/releases)

View File

@@ -96,4 +96,4 @@ schema:
ssl: bool?
slug: birdnet-pipy
url: https://github.com/alexbelgium/hassio-addons/tree/master/birdnet-pipy
version: "0.7.0"
version: "0.7.0-1"

View File

@@ -4,4 +4,16 @@ set -euo pipefail
export PYTHONPATH=/app
bashio::net.wait_for 5001 127.0.0.1 300
cd /app
exec python3 -m core.api
# Single gevent-websocket worker is mandatory: live detections fan out via an
# in-process socketio.emit (no Redis message_queue), so >1 worker would
# silently drop Live Feed broadcasts. Bind 127.0.0.1 (single container; nginx
# and core.main reach the API locally, satisfying the wait_for in nginx/run +
# main/run). Heavy admin jobs cooperatively yield to keep this worker live.
exec gunicorn wsgi:application \
--worker-class geventwebsocket.gunicorn.workers.GeventWebSocketWorker \
--workers 1 \
--bind 127.0.0.1:5002 \
--timeout 120 \
--graceful-timeout 30 \
--keep-alive 65 \
--error-logfile -

View File

@@ -2,7 +2,7 @@
# shellcheck shell=bash
set -euo pipefail
# Wait for the upstream API service (Python core.api) to bind 127.0.0.1:5002
# Wait for the upstream API service (gunicorn / wsgi:application) to bind 127.0.0.1:5002
# before starting nginx, so nginx never serves a 502 for the API/auth/socket
# paths during boot. A boot-time 502 can be cached by an upstream cache layer
# (HA's own PWA service worker, a Cloudflare edge worker, etc.), leaving the