Skip to main content

light and typization Socket.IO server and client for Python

Project description

fastsio (Fast Socket.IO for Python)

Build status codecov

fastsio is a fork of python-socketio with modern Python development improvements inspired by FastAPI.

Key Features

  • Strong typing and FastAPI-like DX with dependency injection
  • Automatic validation of data through Pydantic models
  • Lightweight routers for code organization via RouterSIO
  • Exception handlers on servers and routers
  • Flexible middleware system for authentication, logging, rate limiting, and more
  • Compatibility with existing ASGI/WSGI stacks
  • Full support for the Socket.IO protocol

Installation

pip install fastsio

Key Differences from python-socketio

Feature python-socketio fastsio
Type Safety Minimal Strong typing with annotations
Dependency Injection ✅ FastAPI-style
Pydantic Validation ✅ Automatic
Routers ✅ RouterSIO for code organization
Exception Handlers ✅ Server and router scopes
Middlewares ✅ Flexible middleware system
Parameter Annotations SocketID, Environ, Auth, etc.
Compatibility ✅ Full backward compatibility

Quick Start

Simple Server

import fastsio
from fastsio import ASGIApp, SocketID, Environ, Auth, Data

# Create server
sio = fastsio.AsyncServer(
    async_mode="asgi",
    cors_allowed_origins="*"
)

@sio.event
async def connect(
    sid: SocketID, 
    environ: Environ, 
    auth: Auth,
):
    print(f"Client {sid} connected")
    return True

@sio.event
async def disconnect(sid: SocketID):
    print(f"Client {sid} disconnected")

@sio.on("message")
async def handle_message(sid: SocketID, data: Data):
    await sio.emit("response", f"Received: {data}", to=sid)

# ASGI application
app = ASGIApp(sio)

With Type Safety and Dependency Injection

from pydantic import BaseModel
from fastsio import (
    AsyncServer, RouterSIO, SocketID, 
    Environ, Auth, ASGIApp
)

router = RouterSIO()

class Message(BaseModel):
    text: str
    room: str

class JoinRoom(BaseModel):
    room: str

@router.on("connect")
async def on_connect(
    sid: SocketID, 
    environ: Environ, 
    auth: Auth, 
    server: AsyncServer
):
    """Connection with automatic dependency injection"""
    print(f"Connection: {sid}, auth: {auth}")
    return True

@router.on("join_room")
async def on_join_room(
    sid: SocketID, 
    server: AsyncServer, 
    data: JoinRoom  # Automatic Pydantic validation
):
    """Join room with data validation"""
    await server.enter_room(sid, data.room)
    await server.emit("joined", {"room": data.room}, to=sid)

@router.on("send_message")
async def on_send_message(
    sid: SocketID, 
    server: AsyncServer, 
    data: Message
):
    """Send message with validation"""
    await server.emit(
        "new_message", 
        data.model_dump(), 
        room=data.room
    )

# Create server and attach router
sio = AsyncServer(async_mode="asgi", cors_allowed_origins="*")
sio.add_router(router)

app = ASGIApp(sio)

Exception Handlers

class RoomClosed(Exception):
    pass

@router.exception_handler(RoomClosed)
async def room_closed_handler(
    sio: AsyncServer,
    sid: SocketID,
    exc: RoomClosed,
):
    await sio.emit("error", {"message": "room closed"}, to=sid)

@router.on("message")
async def message():
    raise RoomClosed()

FastAPI Integration

import uvicorn
from fastapi import FastAPI
from fastapi.responses import FileResponse
import fastsio
from fastsio import Environ, Auth, SocketID

app = FastAPI()
sio = fastsio.AsyncServer(async_mode="asgi")

@app.get("/")
async def index():
    return {"message": "FastAPI + fastsio"}

@sio.event
async def connect(sid: SocketID, environ: Environ, auth: Auth):
    await sio.emit("hello", {"message": "Welcome!"}, to=sid)

# Combine FastAPI and Socket.IO
combined_app = fastsio.ASGIApp(sio, app)

if __name__ == "__main__":
    uvicorn.run(combined_app, host="127.0.0.1", port=5000)

Advanced Features

Middlewares for Cross-Cutting Concerns

from typing import Any
from fastsio import AsyncServer, BaseMiddleware, auth_middleware, logging_middleware

# Custom authentication middleware
class AuthMiddleware(BaseMiddleware):
    def __init__(self):
        super().__init__(events=["join_room", "send_message"])
    
    async def before_event(self, event: str, sid: str, data: Any, environ: dict = None, **kwargs):
        if not environ or not environ.get("HTTP_AUTHORIZATION"):
            raise PermissionError("Authentication required")
        return data

# Create server with middlewares
sio = AsyncServer(async_mode="asgi")

# Add middlewares with different scopes
sio.add_middleware(logging_middleware(), global_middleware=True)  # All events
sio.add_middleware(AuthMiddleware())  # Specific events only
sio.add_middleware(
    logging_middleware(), 
    namespace="/admin", 
    events=["admin_action"]
)  # Namespace + event specific

@sio.event
async def join_room(sid: SocketID, data: dict):
    # This will go through AuthMiddleware
    return {"status": "joined"}

Routers for Code Organization

from fastsio import RouterSIO

# Chat router
chat_router = RouterSIO(namespace="/chat")

@chat_router.on("message")
async def chat_message(sid: SocketID, data: Message):
    # Chat logic
    pass

# Admin router
admin_router = RouterSIO(namespace="/admin")

@admin_router.on("user_ban")
async def ban_user(sid: SocketID, data: BanRequest):
    # Ban logic
    pass

# Attach routers
sio.add_router(chat_router)
sio.add_router(admin_router)

Available Types for Injection

from fastsio import (
    SocketID,    # Connection ID
    Environ,     # WSGI/ASGI environ
    Auth,        # Auth data (connect handler only)
    Reason,      # Disconnect reason (disconnect handler only)
    Data,        # Raw event data
    Event,       # Event name
    AsyncServer  # Server instance
)

@router.on("example")
async def example_handler(
    sid: SocketID,
    server: AsyncServer,
    environ: Environ,
    data: Data,
    event: Event
):
    print(f"Event {event} from {sid}: {data}")

Version Compatibility

Compatibility table with JavaScript Socket.IO:

JavaScript Socket.IO Socket.IO protocol Engine.IO protocol fastsio version
0.9.x 1, 2 1, 2 Not supported
1.x and 2.x 3, 4 3 Any version
3.x and 4.x 5 4 Any version

Documentation

Contributing

fastsio is based on the excellent work by Miguel Grinberg on python-socketio. We've added modern capabilities while maintaining full compatibility with the original API.

License

MIT License - see LICENSE file


🌍 Other Languages: Русский

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastsio-0.3.5.tar.gz (85.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastsio-0.3.5-py3-none-any.whl (101.2 kB view details)

Uploaded Python 3

File details

Details for the file fastsio-0.3.5.tar.gz.

File metadata

  • Download URL: fastsio-0.3.5.tar.gz
  • Upload date:
  • Size: 85.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.3 Linux/6.17.0-1018-azure

File hashes

Hashes for fastsio-0.3.5.tar.gz
Algorithm Hash digest
SHA256 ed4328868590da0d823043fbf23830176fd0a39ef8fb3fcb4bef092598258fa9
MD5 fdf651236b66c83ed72669c3be8a18b5
BLAKE2b-256 6bb70d465c093fdb6620f5882df9b8f87a17c54c746950973c2449ba5e266bfd

See more details on using hashes here.

File details

Details for the file fastsio-0.3.5-py3-none-any.whl.

File metadata

  • Download URL: fastsio-0.3.5-py3-none-any.whl
  • Upload date:
  • Size: 101.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.3 Linux/6.17.0-1018-azure

File hashes

Hashes for fastsio-0.3.5-py3-none-any.whl
Algorithm Hash digest
SHA256 4c59aa80b5e59af4f70621adaf094ba77a5ecc7f1af34402eddad7533a87b7da
MD5 db19c237eb5961b0cbcfdf292669b3a9
BLAKE2b-256 9c71ae730ba2131a1fe90ca5f6134df8fb9782239a63033f42a5e8c4b8af929b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page