Implementing Server-Sent Events in Python FastAPI - Featured Image
Web development4 min read

Implementing Server-Sent Events in Python FastAPI

I'll walk you through implementing Server-Sent Events (SSE) in FastAPI from beginning to end, making it easy for beginners to understand.

Understanding SSE basics

Server-Sent Events (SSE) is a technology that allows one-way communication (server to client only), uses a simple text-based protocol with messages separated by double newlines, handles reconnection automatically in browsers, and is perfect for live updates like logs, tracking, and dashboard metrics.

Step 1: Setting up your FastAPI project

First, install the required packages:

pip install fastapi uvicorn

Step 2: Creating the basic FastAPI application

Create a new Python file (e.g., main.py) and set up the basic FastAPI application:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import uvicorn

# Initialize the FastAPI application
app = FastAPI()

# Add CORS middleware to allow requests from web browsers
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # For development; restrict in production
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8000)

Step 3: Creating the waypoints JSON file

Create a file named waypoints.json in the same directory with some sample coordinate data:

[
  {"lat": 37.7749, "lng": -122.4194},
  {"lat": 37.7750, "lng": -122.4195},
  {"lat": 37.7751, "lng": -122.4196},
  {"lat": 37.7752, "lng": -122.4197},
  {"lat": 37.7753, "lng": -122.4198},
  {"lat": 37.7754, "lng": -122.4199},
  {"lat": 37.7755, "lng": -122.4200},
  {"lat": 37.7756, "lng": -122.4201},
  {"lat": 37.7757, "lng": -122.4202},
  {"lat": 37.7758, "lng": -122.4203}
]

Step 4: Implementing the SSE generator function

Add the generator function to your main.py file:

import json
from asyncio import sleep
from fastapi.responses import StreamingResponse

# Generator function that yields waypoints as SSE events
async def waypoints_generator():
    # Open and load the waypoints JSON file
    waypoints = open('waypoints.json')
    waypoints = json.load(waypoints)
    
    # Iterate through the first 10 waypoints
    for waypoint in waypoints[0:10]:
        # Convert waypoint to JSON string
        data = json.dumps(waypoint)
        
        # Format as SSE event with event type and data
        yield f"event: locationUpdate\ndata: {data}\n\n"
        
        # Wait 1 second between events
        await sleep(1)

Step 5: Creating the SSE endpoint

Add the endpoint to your FastAPI application:

@app.get("/get-waypoints")
async def root():
    # Return a streaming response with our generator
    # The media_type is critical for SSE to work properly
    return StreamingResponse(
        waypoints_generator(), 
        media_type="text/event-stream"
    )

Step 6: Creating the frontend HTML page

Create an index.html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Live Vehicle Coordinates</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        #coordinates-container {
            border: 1px solid #ccc;
            padding: 20px;
            border-radius: 5px;
        }
        h2 {
            color: #333;
        }
    </style>
</head>
<body>
    <div id="coordinates-container">
        <h2>Live Vehicle Coordinates</h2>
        <div id="coordinates"></div>
    </div>
    <script src="script.js"></script>
</body>
</html>

Step 7: Implementing the frontend javaScript

Create a script.js file:

// Get the element where coordinates will be displayed
const coordinatesElement = document.getElementById('coordinates');
let coords;

// Create an EventSource pointing to our FastAPI endpoint
const eventSource = new EventSource('http://127.0.0.1:8000/get-waypoints');

// When the connection opens
eventSource.onopen = () => {
    console.log('EventSource connected');
    // Clear previous data when connection is established
    coordinatesElement.innerText = '';
}

// Listen for 'locationUpdate' events
eventSource.addEventListener('locationUpdate', function(event) {
    // Parse the JSON data from the event
    coords = JSON.parse(event.data);
    console.log('LocationUpdate', coords);
    // Update the UI with the new coordinates
    updateCoordinates(coords);
});

// Handle errors
eventSource.onerror = (error) => {
    console.error('EventSource failed', error);
    // Close the connection on error to prevent endless retry loops
    eventSource.close();
}

// Function to update and display coordinates
function updateCoordinates(coordinates) {
    // Create a new paragraph element for each coordinate
    const paragraph = document.createElement('p');
    paragraph.textContent = `Latitude: ${coordinates.lat}, Longitude: ${coordinates.lng}`;
    // Add it to the coordinates container
    coordinatesElement.appendChild(paragraph);
}

Start your FastAPI server with python main.py, then open the HTML file in your browser. You should see coordinates appearing one by one with a 1-second delay between each.

Key concepts that make SSE work

On the server side, the StreamingResponse handles the streaming mechanism, setting media_type="text/event-stream" tells the browser this is an SSE connection, the \n\n at the end of each message separates events, and the event: locationUpdate line categorizes the event type.

On the client side, the EventSource object connects to the SSE endpoint, event listeners process different event types, the browser handles reconnection automatically, and errors can be managed through the onerror handler.

Troubleshooting common issues

If coordinates don't appear, check browser console for errors. Ensure CORS is properly configured if testing on different domains. Make sure the waypoints.json file exists and has valid JSON. Verify your server is running on the expected port (8000).

This guide covers everything you need to implement Server-Sent Events with Python FastAPI, from setting up the server to creating the client interface.

hassaankhan789@gmail.com

Frontend Web Developer

Posted by





Subscribe to our newsletter

Join 2,000+ subscribers

Stay in the loop with everything you need to know.

We care about your data in our privacy policy

Background shadow leftBackground shadow right

Have something to share?

Write on the platform and dummy copy content

Be Part of Something Big

Shifters, a developer-first community platform, is launching soon with all the features. Don't miss out on day one access. Join the waitlist: