Stream SEC Filings in Real-Time Using Python
This guide provides a step-by-step approach to connect to the Stream API with Python, enabling you to receive newly published SEC filings in real-time.
Begin with the installation of the WebSocket library by executing the following command in your terminal:
pip install websockets
After installation, proceed to copy the Python script provided below into a file on your local machine. Ensure you replace YOUR_API_KEY
with your actual API key obtained from your account.
With these preparations complete, you're ready to execute the Python script. The script will continuously listen for new filings and output their metadata in your terminal as soon as they are made available on EDGAR.
1
import asyncio
2
import websockets
3
import json
4
5
API_KEY = "YOUR_API_KEY" # Replace this with your actual API key
6
SERVER_URL = "wss://stream.sec-api.io"
7
WS_ENDPOINT = SERVER_URL + "?apiKey=" + API_KEY
8
9
async def websocket_client():
10
try:
11
async with websockets.connect(WS_ENDPOINT) as websocket:
12
print("✅ Connected to:", SERVER_URL)
13
14
while True:
15
message = await websocket.recv()
16
filings = json.loads(message)
17
for f in filings:
18
print(f["accessionNo"], f["formType"], f["filedAt"], f["cik"])
19
20
except Exception as e:
21
print(f"An unexpected error occurred: {e}")
22
23
24
asyncio.run(websocket_client())
Advanced Example: Auto-Reconnect, Heartbeats, and Keep-Alives
This advanced Python code sample introduces a robust reconnection mechanism. It enables the client to monitor the connection status actively and perform an automatic reconnection if the connection drops. The strategy involves dispatching a heartbeat ping to the server at 30-second intervals, awaiting a pong response. Should the server fail to reply within a 5-second window, the client terminates the current connection and initiates a new connection process, thereby maintaining continuous connectivity.
1
import asyncio
2
import websockets
3
import json
4
5
API_KEY = "YOUR_API_KEY" # Replace this with your actual API key
6
SERVER_URL = "wss://stream.sec-api.io"
7
WS_ENDPOINT = SERVER_URL + "?apiKey=" + API_KEY
8
9
10
async def send_ping(websocket):
11
while True:
12
try:
13
pong_waiter = await websocket.ping()
14
await asyncio.wait_for(pong_waiter, timeout=5) # Wait for a pong within 5 seconds
15
await asyncio.sleep(30) # Send ping every 30 seconds
16
except Exception as e:
17
print(f"An error occurred while sending ping: {e}")
18
await websocket.close() # Close the connection if an error occurs
19
return
20
21
22
async def websocket_client():
23
retry_counter = 0
24
max_retries = 5
25
ping_task = None
26
27
while retry_counter < max_retries:
28
try:
29
async with websockets.connect(WS_ENDPOINT) as websocket:
30
print("✅ Connected to:", SERVER_URL)
31
retry_counter = 0
32
# Start the ping/pong keep-alive routine
33
ping_task = asyncio.create_task(send_ping(websocket))
34
# Start the message-receiving loop
35
while True:
36
message = await websocket.recv()
37
filings = json.loads(message)
38
for f in filings:
39
print(f["accessionNo"], f["formType"], f["filedAt"], f["cik"])
40
41
except Exception as e:
42
retry_counter += 1
43
44
print(f"Connection closed with message: {e}")
45
print(f"Reconnecting in 5 sec... (Attempt {retry_counter}/{max_retries})")
46
47
# Cancel the ping task
48
if ping_task is not None:
49
try:
50
ping_task.cancel()
51
await ping_task
52
except Exception:
53
pass # Ignore any exceptions
54
ping_task = None
55
56
await asyncio.sleep(5) # Wait for 5 seconds before reconnecting
57
58
print("Maximum reconnection attempts reached. Stopping client.")
59
60
61
asyncio.run(websocket_client())
Example for Connecting to Deprecated Legacy Endpoints
This example illustrates the process of connecting to legacy streaming endpoints that are marked for deprecation. Please be advised that these endpoints will be phased out on April 5, 2024. To ensure uninterrupted access and take advantage of enhanced functionality, we strongly recommend migrating to the newly available endpoint as soon as possible.
pip install python-engineio==3.14.2 python-socketio[client]==4.6.0
1
import socketio
2
3
sio = socketio.Client()
4
5
@sio.on('connect', namespace='/all-filings')
6
def on_connect():
7
print("Connected to https://api.sec-api.io:3334/all-filings")
8
9
@sio.on('filing', namespace='/all-filings')
10
def on_filings(filing):
11
print(filing)
12
13
sio.connect('https://api.sec-api.io:3334?apiKey=YOUR_API_KEY', namespaces=['/all-filings'], transports=["websocket"])
14
sio.wait()