| 243 | yield data |
| 244 | |
| 245 | def decode(self, line: str) -> ServerSentEvent | None: |
| 246 | # See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501 |
| 247 | |
| 248 | if not line: |
| 249 | if not self._event and not self._data and not self._last_event_id and self._retry is None: |
| 250 | return None |
| 251 | |
| 252 | sse = ServerSentEvent( |
| 253 | event=self._event, |
| 254 | data="\n".join(self._data), |
| 255 | id=self._last_event_id, |
| 256 | retry=self._retry, |
| 257 | ) |
| 258 | |
| 259 | # NOTE: as per the SSE spec, do not reset last_event_id. |
| 260 | self._event = None |
| 261 | self._data = [] |
| 262 | self._retry = None |
| 263 | |
| 264 | return sse |
| 265 | |
| 266 | if line.startswith(":"): |
| 267 | return None |
| 268 | |
| 269 | fieldname, _, value = line.partition(":") |
| 270 | |
| 271 | if value.startswith(" "): |
| 272 | value = value[1:] |
| 273 | |
| 274 | if fieldname == "event": |
| 275 | self._event = value |
| 276 | elif fieldname == "data": |
| 277 | self._data.append(value) |
| 278 | elif fieldname == "id": |
| 279 | if "\0" in value: |
| 280 | pass |
| 281 | else: |
| 282 | self._last_event_id = value |
| 283 | elif fieldname == "retry": |
| 284 | try: |
| 285 | self._retry = int(value) |
| 286 | except (TypeError, ValueError): |
| 287 | pass |
| 288 | else: |
| 289 | pass # Field is ignored. |
| 290 | |
| 291 | return None |
| 292 | |
| 293 | |
| 294 | @runtime_checkable |