Package: apistar-websocket
API Star WebSocketA WebSocket Component for easily using WebSockets with API Star and UvicornEasy WebSocket component for API Star and Uvicorn.FeaturesInstallExamplesUvicornIssuesFeaturesIt's Easy to useSimply use it like any other component on a route handler that will accept WebSocket
connections# With WebSocketAutoHook in event_hooks is the easiest usage,# but see the Issues below about using WebSocketAutoHookasyncdefws_handler(ws:WebSocket):inbound_msg=awaitws.recv()...awaitws.send(outbound_msg)# Without the WebSocketAutoHookasyncdefws_handler(ws:WebSocket):awaitws.connect()inbound_msg=awaitws.recv()...awaitws.send(outbound_msg)awaitws.close()Auto connecting and closing event hook.When used with theWebSocketAutoHookthe WebSocket will be connected before the handler
is called. When the handler returns or is ended due to error the WebSocket will be automatically
closed. See theIssuesbelow concerningWebSocketAutoHook.Installpip install apistar-websocketor forPipenvuserspipenv install apistar-websocketExamplesHere's a basic example of sending 100 numbers to the connected client and waiting
for a return message after each send. The WebSocket is connected and closed for us
by theWebSocketAutoHook.importjsonfromapistarimportASyncApp,RoutefromwebsocketimportWebSocket,WebSocketComponent,WebSocketAutoHookasyncdefwelcome_ws(path:str,ws:WebSocket):"""A WebSocket endpoint used to play a terrible game of data ping pong."""foriinrange(100):awaitws.send(json.dumps({"msg":f"{path}is nice","count":i,}))# We'll pretend we're playing ping pongmsg=awaitws.receive()routes=[Route('/{+path}','GET',handler=welcome_ws,name='welcome_ws'),]event_hooks=[WebSocketAutoHook]components=[WebSocketComponent()]app=ASyncApp(routes=routes,components=components,event_hooks=event_hooks,)if__name__=='__main__':main()Same example as above, but without using theWebSocketAutoHook. Here the handler
must manage the WebSocket connection itself and run as a standaloneRouteto prevent
API Star from sending responses to the client.importjsonfromapistarimportASyncApp,RoutefromwebsocketimportWebSocket,WebSocketComponentasyncdefwelcome_ws(path:str,ws:WebSocket):"""A WebSocket endpoint used to subscribe to a stream of data."""# finish the connectionawait.connect()foriinrange(100):awaitws.send(json.dumps({"msg":f"{path}is nice","count":i,}))# We'll pretend we're playing ping pongmsg=awaitws.receive()# close the connectionawaitws.close()# Must run the route standalone to prevent the attempt at an HTTP Response being sentroutes=[Route('/{+path}','GET',handler=welcome_ws,name='welcome_ws',standalone=True),]components=[WebSocketComponent()]app=ASyncApp(routes=routes,components=components,)if__name__=='__main__':main()UvicornYou have to run your API Star with Uvicorn forapistar-websocketto work.To run you app with debug on and automatically reloading the app on file changes,
great for development, use:uvicorn --log-level DEBUG --reload app:appFor a production environment start from the command:uvicorn app:appAnd adjust as needed, seeuvicorn --helpfor more options.IssuesThe cleanest way to use the component is without theWebSocketAutoHookand as a standalone
route with the handler connecting and closing the WebSocket. This is because when a handler isnotused as a standalone route, the default, API Star will send an HTTP response after a handler
has finished. While this needed for regular HTTP requests, it is not for
WebSocket connections as they are already closed. You can use theWebSocketAutoHookand your handlers will function as you expect.
But to prevent API Star from sending the HTTP responseWebSocketAutoHookwill raise an exception after closing the WebSocket to prevent the HTTP
response causing an error condition in API Star.