0
0
FastapiDebug / FixBeginner · 4 min read

How to Handle WebSocket Connection in FastAPI Correctly

To handle a WebSocket connection in FastAPI, use the WebSocket class in an async endpoint decorated with @app.websocket. Accept the connection with await websocket.accept(), then receive and send messages asynchronously using await websocket.receive_text() and await websocket.send_text().
🔍

Why This Happens

Many beginners try to handle WebSocket connections in FastAPI like normal HTTP requests, which causes errors because WebSockets require a persistent, two-way connection. Forgetting to accept the connection or using synchronous code leads to failures.

python
from fastapi import FastAPI, WebSocket

app = FastAPI()

@app.websocket("/ws")
def websocket_endpoint(websocket: WebSocket):
    data = await websocket.receive_text()
    await websocket.send_text(f"Message text was: {data}")
Output
RuntimeWarning: coroutine 'WebSocket.receive_text' was never awaited TypeError: object NoneType can't be used in 'await' expression
🔧

The Fix

Change the endpoint to be async, await the accept(), receive_text(), and send_text() methods properly. This ensures the WebSocket connection is established and messages are handled asynchronously.

python
from fastapi import FastAPI, WebSocket

app = FastAPI()

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    data = await websocket.receive_text()
    await websocket.send_text(f"Message text was: {data}")
Output
WebSocket connection accepted and message echoed back to client
🛡️

Prevention

Always define WebSocket endpoints as async functions and use await for all WebSocket methods. Remember to call await websocket.accept() before receiving or sending messages. Use proper error handling to close connections gracefully.

Use linters or IDEs that warn about missing await on async calls to catch mistakes early.

⚠️

Related Errors

Common errors include:

  • RuntimeWarning: coroutine was never awaited - caused by missing await.
  • WebSocketDisconnect exceptions - happens when client disconnects unexpectedly; handle with try-except.
  • Invalid state errors - caused by calling send_text or receive_text before accept().

Key Takeaways

Always define WebSocket endpoints as async functions in FastAPI.
Call await websocket.accept() before receiving or sending messages.
Use await with all WebSocket methods to avoid runtime errors.
Handle client disconnects gracefully with try-except blocks.
Use linters or IDE warnings to catch missing await calls early.