Python SSE Client
The `sseclient` library (version 0.0.27) is a Python client for consuming Server-Sent Events (SSE) streams, also known as EventSource. It provides an `SSEClient` class that acts as an iterator, allowing easy processing of messages from a server. This version, last updated in September 2020, handles automatic reconnections and parses event data. While functional, it is no longer actively developed, with more recent and actively maintained forks (e.g., `sseclient-py`) addressing modern Python features and known issues.
Common errors
-
ValueError: Unterminated string starting at...
cause This error often occurs when `json.loads(event.data)` is attempted on incomplete or corrupted JSON data within an SSE event. This can be due to `sseclient` not correctly handling fragmented HTTP chunks for large events.fixAs per warnings, this is a known issue with `sseclient` 0.0.27. Consider using `sseclient-py` which has addressed this, or implement robust error handling around `json.loads` and potentially reassemble fragmented data manually if the server is known to send it that way. -
requests.exceptions.InvalidURL: Failed to parse: <Response [200]>
cause This error happens when attempting to initialize `SSEClient` by passing a `requests.Response` object's URL attribute (`response.url`) instead of the `response` object itself. `SSEClient` expects the raw streaming response object, not just its URL.fixInitialize the `SSEClient` with the `requests.Response` object directly: `client = SSEClient(response)` where `response = requests.get(url, stream=True, ...)`. -
requests.exceptions.HTTPError: 405 Client Error: Method Not Allowed
cause This typically occurs when the HTTP method used to request the SSE stream (e.g., `requests.post` or `requests.put`) is not supported by the server for SSE connections. SSE streams are almost universally initiated with a `GET` request.fixEnsure you are using `requests.get()` to initiate the SSE stream. If the server requires parameters, include them as `params` in the `requests.get()` call.
Warnings
- breaking Version 0.0.27, due to an unmerged fix for a `read1()` issue, can corrupt data or lose events when consuming long streams or fragmented JSON data, leading to `ValueError: Unterminated string...` during parsing.
- gotcha The original `sseclient` (btubbs) is not actively maintained since 2020. While it generally works, it may lack support for newer Python versions or not have fixes for recently discovered edge cases.
- gotcha When using `requests.get(..., stream=True)` with `sseclient`, ensure the `headers={'Accept': 'text/event-stream'}` is included. Without it, some servers might not correctly identify the request as an SSE subscription and might not stream events as expected.
Install
-
pip install sseclient
Imports
- SSEClient
from sseclient import SSEClient
Quickstart
import requests
from sseclient import SSEClient
import os
# Replace with your actual SSE endpoint URL
sse_url = os.environ.get('SSE_ENDPOINT_URL', 'http://localhost:8000/events')
try:
# Establish a streaming connection using requests
response = requests.get(sse_url, stream=True, headers={'Accept': 'text/event-stream'})
response.raise_for_status() # Raise an exception for HTTP errors
client = SSEClient(response)
print(f"Connected to SSE stream at {sse_url}. Listening for events...")
for event in client.events():
if event.data:
print(f"Received Event (ID: {event.id}, Type: {event.event}): {event.data}")
else:
print(f"Received heartbeat/empty event (ID: {event.id}, Type: {event.event})")
except requests.exceptions.RequestException as e:
print(f"Error connecting to SSE stream: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")