| 425 | yield data |
| 426 | |
| 427 | def decode(self, line: str) -> ServerSentEvent | None: |
| 428 | # See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501 |
| 429 | |
| 430 | if not line: |
| 431 | if not self._event and not self._data and not self._last_event_id and self._retry is None: |
| 432 | self._raw = [] |
| 433 | return None |
| 434 | |
| 435 | sse = ServerSentEvent( |
| 436 | event=self._event, |
| 437 | data="\n".join(self._data), |
| 438 | id=self._last_event_id, |
| 439 | retry=self._retry, |
| 440 | raw=self._raw, |
| 441 | ) |
| 442 | |
| 443 | # NOTE: as per the SSE spec, do not reset last_event_id. |
| 444 | self._event = None |
| 445 | self._data = [] |
| 446 | self._retry = None |
| 447 | self._raw = [] |
| 448 | |
| 449 | return sse |
| 450 | |
| 451 | self._raw.append(line) |
| 452 | |
| 453 | if line.startswith(":"): |
| 454 | return None |
| 455 | |
| 456 | fieldname, _, value = line.partition(":") |
| 457 | |
| 458 | if value.startswith(" "): |
| 459 | value = value[1:] |
| 460 | |
| 461 | if fieldname == "event": |
| 462 | self._event = value |
| 463 | elif fieldname == "data": |
| 464 | self._data.append(value) |
| 465 | elif fieldname == "id": |
| 466 | if "\0" in value: |
| 467 | pass |
| 468 | else: |
| 469 | self._last_event_id = value |
| 470 | elif fieldname == "retry": |
| 471 | try: |
| 472 | self._retry = int(value) |
| 473 | except (TypeError, ValueError): |
| 474 | pass |
| 475 | else: |
| 476 | pass # Field is ignored. |
| 477 | |
| 478 | return None |
| 479 | |
| 480 | |
| 481 | @runtime_checkable |