1

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.

kosciej16
  • 6,294
  • 1
  • 18
  • 29

1 Answers1

8
# server.py
from typing import Any

import uvicorn
from fastapi import FastAPI

import socketio

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}")
    await sio.emit("event_name", msg, room=sid)  # we can send message to specific 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
kosciej16
  • 6,294
  • 1
  • 18
  • 29
  • In case someone would like to see react client implementation, here you can find the example: https://stackoverflow.com/questions/70274482/socketio-implementation-with-fastapi-and-react – kosciej16 Dec 20 '21 at 23:34
  • great and simple example - I liked it :) – Ben Mar 27 '22 at 19:54
  • cannot import name 'socket' from partially initialized module 'socket' is what I get from this example – Michael Paccione May 26 '22 at 20:11
  • This example doesn't even import socket. What library it came from? I guess you have some version mismatched. – kosciej16 May 31 '22 at 23:59
  • 1
    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. – Michael Paccione Jun 02 '22 at 00:03