WebSockets
WebSockets give you a persistent, bidirectional connection: after a single HTTP upgrade, both client and server can send messages at any time. FastAPI supports them with the WebSocket endpoint type and a websocket parameter, which makes chat rooms, live dashboards, and notification streams straightforward.
A Basic Echo Endpoint
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"server received: {data}")
Test in a browser console:
const ws = new WebSocket("ws://127.0.0.1:8000/ws");
ws.onopen = () => ws.send("hello");
ws.onmessage = (e) => console.log(e.data);
Broadcasting to Many Clients
Keep a set of connected websockets and send to everyone on each message - the classic chat-room pattern:
from fastapi import FastAPI, WebSocket
app = FastAPI()
connections: set[WebSocket] = set()
@app.websocket("/ws")
async def chat(websocket: WebSocket):
await websocket.accept()
connections.add(websocket)
try:
while True:
text = await websocket.receive_text()
for c in connections:
await c.send_text(text)
except Exception:
connections.discard(websocket)
await websocket.close()
JSON and Binary Messages
@app.websocket("/ws/json")
async def json_ws(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_json()
await websocket.send_json({"echo": data})
# binary:
# raw = await websocket.receive_bytes()
# await websocket.send_bytes(raw)
Closing and Errors
- websocket.close(code=1000) ends the connection cleanly.
- Wrap the receive loop in try/except to catch WebSocketDisconnect and clean up.
- Send pings or use a client-side timeout to detect dead connections.
Summary
Define WebSocket routes with @app.websocket and an async function taking a WebSocket parameter: accept the connection, loop on receive_text/receive_json, and send back with send_text/send_json. Maintain a set of connections to broadcast to many clients, and handle disconnects explicitly.