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 websocketsAfter 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()