I tried to create fastapi application that uses websockets and could broadcast messages to all connected clients. I found out that it's not possible with websockets but found briliant library - socket.io. However I am not sure how could I use it and integrate it with my existing fastapi app.
1 Answer
# server.py from typing import Any import socketio import uvicorn from fastapi import FastAPI sio: Any = socketio.AsyncServer(async_mode="asgi") socket_app = socketio.ASGIApp(sio) app = FastAPI() @app.get("/test") async def test(): print("test") return "WORKS" app.mount("/", socket_app) # Here we mount socket app to main fastapi app @sio.on("connect") async def connect(sid, env): print("on connect") @sio.on("direct") async def direct(sid, msg): print(f"direct {msg}") # we can send message to specific sid await sio.emit("event_name", msg, room=sid) @sio.on("broadcast") async def broadcast(sid, msg): print(f"broadcast {msg}") await sio.emit("event_name", msg) # or send to everyone @sio.on("disconnect") async def disconnect(sid): print("on disconnect") if __name__ == "__main__": kwargs = {"host": "0.0.0.0", "port": 5000} kwargs.update({"debug": True, "reload": True}) uvicorn.run("server:app", **kwargs) # client.py import requests import socketio r = requests.get("http://127.0.0.1:5000/test") # server prints "test" cl = socketio.Client() cl2 = socketio.Client() @cl.on("event_name") def foo(data): print(f"client 1 {data}") @cl2.on("event_name") def foo2(data): print(f"client 2 {data}") cl.connect("http://127.0.0.1:5000/") # server prints "on connect" cl2.connect("http://127.0.0.1:5000/") cl.emit("direct", "msg_1") # prints client 1 msg_1 cl2.emit("broadcast", "msg_2") # prints client 2 msg_2 and client 1 msg_2 At the end install proper dependencies:
# server.py pip install python-socketio uvicorn fastapi # client.py pip install requests websocket-client 5 Comments
kosciej16
In case someone would like to see react client implementation, here you can find the example: stackoverflow.com/questions/70274482/…
Ben
great and simple example - I liked it :)
Michael Paccione
cannot import name 'socket' from partially initialized module 'socket' is what I get from this example
kosciej16
This example doesn't even import socket. What library it came from? I guess you have some version mismatched.
Michael Paccione
Oh good call... it looks like I had reworked it from another stackoverflow example and was importing sio instead of making a client. I missed the rewrite on that. Nice example guy.