Skip to content
This repository was archived by the owner on Apr 4, 2024. It is now read-only.

Add basic socketio fastapi integration #1

Merged
merged 3 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ venv
.pytest_cache
*.egg-info
.DS_Store
.vscode/
3 changes: 2 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ neovim = "*"
fastapi = "==0.61.1"
netifaces = "==0.10.6"
pydantic = "==1.6.1"
socketio = "==0.2.1"
starlette = "==0.13.6"
python-socketio = "==4.6.0"
python-engineio = "*"

[test]
pytest = "==6.0.1"
Expand Down
156 changes: 85 additions & 71 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,40 @@ Install this plugin using `pip`:

## Usage

Usage instructions go here.
To add SocketIO support to FastAPI all you need to do is import `SocketManager` and pass it `FastAPI` object.

```python
# app.py
from fastapi import FastAPI
from fastapi_socketio import SocketManager

app = FastAPI()
socket_manager = SocketManager(app=app)
```


Now you can use SocketIO directly from your `FastAPI` app object.
```python
# socket_handlers.py
from .app import app

@app.sio.on('join')
async def handle_join(sid, *args, **kwargs):
await app.sio.emit('lobby', 'User joined')

```

Or you can import `SocketManager` object that exposes most of the SocketIO functionality.

```python
# socket_handlers2.py
from .app import socket_manager as sm

@sm.on('leave')
async def handle_leave(sid, *args, **kwargs):
await sm.emit('lobby', 'User left')

```

## Development

Expand Down
28 changes: 28 additions & 0 deletions examples/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from fastapi import FastAPI
from fastapi_socketio import SocketManager

app = FastAPI()
sio = SocketManager(app=app)


@app.sio.on('join')
async def handle_join(sid, *args, **kwargs):
await sio.emit('lobby', 'User joined')


@sio.on('test')
async def test(sid, *args, **kwargs):
await sio.emit('hey', 'joe')



if __name__ == '__main__':
import logging
import sys

logging.basicConfig(level=logging.DEBUG,
stream=sys.stdout)

import uvicorn

uvicorn.run("examples:app", host='0.0.0.0', port=8000, reload=True, debug=False)
2 changes: 2 additions & 0 deletions fastapi_socketio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
from .socket_manager import SocketManager

def example_function():
return 1 + 1
88 changes: 88 additions & 0 deletions fastapi_socketio/socket_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import socketio
from fastapi import FastAPI


class SocketManager:
"""
Integrates SocketIO with FastAPI app.
Adds `sio` property to FastAPI object (app).

Default mount location for SocketIO app is at `/ws`
and defautl SocketIO path is `socket.io`.
(e.g. full path: `ws://www.example.com/ws/socket.io/)

SocketManager exposes basic underlying SocketIO functionality

e.g. emit, on, send, call, etc.
"""

def __init__(
self,
app: FastAPI,
mount_location: str = "/ws",
socketio_path: str = "socket.io",
cors_allowed_origins: list = [],
) -> None:
# TODO: Change Cors policy based on fastapi cors Middleware
self._sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins="*")
self._app = socketio.ASGIApp(
socketio_server=self._sio, socketio_path=socketio_path
)

app.mount(mount_location, self._app)
app.sio = self._sio

def is_asyncio_based(self) -> bool:
return True

@property
def on(self):
return self._sio.on

@property
def attach(self):
return self._sio.attach

@property
def emit(self):
return self._sio.emit

@property
def send(self):
return self._sio.send

@property
def call(self):
return self._sio.call

@property
def close_room(self):
return self._sio.close_room

@property
def get_session(self):
return self._sio.get_session

@property
def save_session(self):
return self._sio.save_session

@property
def session(self):
return self._sio.session

@property
def disconnect(self):
return self._sio.disconnect

@property
def handle_request(self):
return self._sio.handle_request

@property
def start_background_task(self):
return self._sio.start_background_task

@property
def sleep(self):
return self._sio.sleep