microdot.sse — Server-Sent Events

Les Server-Sent Events (SSE) constituent un protocole de poussée unidirectionnel simple : le client ouvre une requête HTTP normale vers Content-Type: text/event-stream, et le serveur maintient la connexion ouverte et écrit des événements formatés au fur et à mesure qu’ils surviennent. Le navigateur expose le flux sous forme d’un objet JavaScript EventSource. Comparé aux WebSockets, SSE est plus simple lorsque seul le serveur pousse des données ; le client effectue toujours la demande.

L’usage typique sur une caméra consiste à publier des détections / lectures de capteur / mises à jour de statut vers un téléphone ou un tableau de bord au rythme où elles surviennent, sans que le tableau de bord ait à interroger.

class SSE

class microdot.sse.SSE

Le descripteur que reçoit la route. Transmis aux gestionnaires comme second argument lorsque with_sse() est utilisé.

async send(data, event: str | None = None, event_id: str | None = None, retry: int | None = None, comment: bool = False)

Pousse un seul événement vers le client.

data

La charge utile de l’événement. Les chaînes et les bytes sont envoyés tels quels. Les dicts et les listes sont sérialisés en JSON. Tout le reste est converti avec str().

event

Nom d’événement optionnel – l”EventSource du navigateur le distribue à un écouteur JavaScript du même nom lorsqu’il est défini.

event_id

Identifiant d’événement optionnel – le navigateur le renvoie sous forme de Last-Event-ID si la connexion est interrompue puis rétablie, ce qui permet au serveur de reprendre là où il s’était arrêté.

retry

Délai de reconnexion en secondes ; le navigateur l’utilise si la connexion est interrompue.

comment

Si True, la charge utile est envoyée comme ligne de commentaire SSE (ignorée par le navigateur). Utile comme battement de cœur de maintien en vie pour empêcher les délais d’expiration NAT de fermer un flux par ailleurs inactif.

Décorateurs au niveau du module

microdot.sse.with_sse(f)

Décorateur qui transforme une route en point de terminaison SSE. Le gestionnaire reçoit la requête et un objet SSE

from microdot import Microdot
from microdot.sse import with_sse

app = Microdot()

@app.get('/events')
@with_sse
async def events(request, sse):
    import asyncio
    while True:
        await sse.send({'temp': read_sensor()}, event='reading')
        await asyncio.sleep(1)

La durée de vie du gestionnaire est égale à celle du flux – il s’exécute aussi longtemps que le client reste connecté. L’annulation (le client se déconnecte, le serveur s’arrête) se propage sous forme d”asyncio.CancelledError, que le framework absorbe.

microdot.sse.sse_response(request, event_function, *args, **kwargs)

Point d’entrée de bas niveau : renvoie le tuple de réponse que with_sse() renvoie en coulisses. Utile lorsqu’un point de terminaison SSE a besoin d’en-têtes ou de codes de statut personnalisés que le décorateur n’autorise pas

from microdot.sse import sse_response

@app.get('/events')
async def events(request):
    if not request.g.current_user:
        return 401
    async def emit(req, sse):
        await sse.send('hello')
    return sse_response(request, emit)

event_function prend (request, sse, *args, **kwargs) et utilise await sse.send(...) pour pousser des événements.

La réponse SSE définit Content-Type: text/event-stream et maintient la connexion ouverte jusqu’à ce que event_function se termine ou que le client se déconnecte. Utilisez une boucle while True avec un await asyncio.sleep entre les envois pour éviter une boucle active intensive.