FastAPI WebSocket
Use WebSocket
parameter type for websocket endpoints.
1
2
@app.websocket('/ws')
async def websocket_endpoint(socket: WebSocket): ...
Accept Connection
At the very first you need to accept the connection.
1
await socket.accept()
Send/Receive API
1
2
3
4
5
6
data_json = await socket.receive_json()
data_text = await socket.receive_text()
data_bytes = await socket.receive_bytes()
await socket.send_json(data_json)
await socket.send_text(data_text)
await socket.send_bytes(data_bytes)
Data Frame
When using json format, you can choose which data frame to contain data with mode
parameter.
Either text
or binary
is accepted, and default is text
.
1
2
data_binary_json = socket.receive_json(mode='binary')
socket.send_json(data, mode='binary')
Iterators
Most common lifetime of websocket is a loop of receive -> send.
This is easily done by receive
async iterators.
These iterators will exit when WebSocketDisconnected
is raised.
1
2
3
async for data_text in socket.iter_text(): ...
async for data_json in socket.iter_json(): ...
async for data_bytes in socket.iter_bytes(): ...
Close Connection
Server can also close the connection.
1
await socket.close()
What’s Happening Underneath?
WebSocket
type internally manages client and application state based on protocol,
which are CONNECTING
, CONNECTED
or DISCONNECTED
.
Initially both client and application state are CONNECTING
.
Client and application communicates over connection via sending and receiving socket Message
s.
To initiate the connection, client is expected to send connect
type message,
and then application is expected to respond with accept
type message to accept or close
type to refuse.
To close the connection properly, client is expected to send disconnect
type message (client side disconnect),
or server is expected to send close
type message (server side close).
However, keep in mind that the connection could be broken without closing handshake,
for example, when disconnected to network, server tries to send close
message but raises IOError.
WebSocket
provides low-level send
and receive
method that properly manages the states based on protocol.
When unexpected message is received or about to be sent, the socket will raise RuntimeError
.
- On client state
CONNECTING
, expects to receiveconnect
messageconnect
message transforms client state toCONNECTED
- On client state
CONNECTED
, expects to receivereceive
ordisconnect
messagereceive
message is normal message from clientdisconnect
message transforms client state toDISCONNECTED
- On app state
CONNECTING
, expects to sendaccept
orclose
messageaccept
message transforms app state toCONNECTED
close
message transforms app state toDISCONNECTED
- On app state
CONNECTED
, expects to sendsend
orclose
messagesend
message is normal message from appclose
message transforms app state toDISCONNECTED
- I/O error transforms app state
DISCONNECTED
and raisesWebSocketDisconnect
All other APIs are implemented using send
and receive
.
accept
method waits forconnect
message if client state isCONNECTING
(receive()
), then sendaccept
message (send()
).close
method sendsclose
message (send()
).- All
receive_text
,receive_json
,receive_bytes
expect the app state to beCONNECTED
beforereceive()
, and raiseWebSocketDisconnect
ondisconnect
message.receive_json
additionally validates the mode (text
orbinary
) beforereceive()
, thenjson.loads()
the data.receive_text
casts data tostr
.receive_bytes
casts data tobytes
.
- All
iter_text
,iter_json
,iter_bytes
wrap their corresponding methods:1 2 3 4 5
try: while True: yield await self.receive_something() except WebSocketDisconnect: pass
- All
send_text
,send_json
,send_bytes
attach the proper message type and callsend()
.send_json
additionally validates the mode andjson.dumps()
the data.