Skip to main content

ASGI wrapper for combining FastAPI and Socket.IO in one app

Project description

asyncutilsx

CodSpeed

ASGI wrapper for combining FastAPI and Socket.IO in one app.

Author: Akshat kotpalliwar (alias IntegerAlex)
SPDX-License-Identifier: LGPL-2.1-only

Minimal and composable: one core function, isolated effects at the ASGI boundary.

Breaking changes (v0.3.0)

health_check_route has been removed from the public API. Add your own /health endpoint directly in your FastAPI app instead. See docs/user_guide.md for details.

Why asyncplus() / asyncutilsx?

Scenario: real-time chat app with REST API

# ❌ With mount() — problematic
app = FastAPI()
app.mount("/socket.io", socket_app)
# - Auth middleware may break Socket.IO handshake
# - CORS middleware may interfere
# - Extra latency on every Socket.IO message

# ✅ With asyncplus — clean
asgi_app = asyncplus(app, sio)
# - Socket.IO gets raw ASGI requests
# - FastAPI gets HTTP requests
# - Each handles its own concerns

FastAPI’s app.mount("/path", other_asgi) works, but you must serve Socket.IO on a subpath and deal with that path everywhere (client, CORS, proxies). asyncplus gives you a single ASGI app: one entry point for the server (e.g. uvicorn), no mount path, same origin for API and Socket.IO. Plug and play—no extra middleware added; you keep full control of the ASGI apps you pass in.

Install

pip install asyncutilsx

Usage

from fastapi import FastAPI
from socketio import AsyncServer
from asyncutilsx import asyncplus, create_app

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

@sio.event
async def connect(sid, environ):
    print("connect", sid)

asgi_app = asyncplus(app, sio)
# Run with: uvicorn asgi:asgi_app

Or use the convenience helper: asgi_app = create_app(app, sio).

  • HTTP (except /socket.io/*) → FastAPI
  • HTTP /socket.io/* → Socket.IO (polling)
  • WebSocket (path matching socketio_path) → Socket.IO; other WebSocket paths → FastAPI
  • Lifespan → both apps (startup/shutdown events are multiplexed so each app boots and shuts down properly)

Optional: asyncplus(app, sio, socketio_path="/custom/", debug_hook=..., socketio_fallback_on_error=False, timeout=30.0).

For custom routing (e.g. SSE, gRPC), use the pure router(routes, default_app) function: pass a sequence of (predicate, app) pairs; first match wins; default_app used when none match.

See docs/user_guide.md for common patterns and examples.

Development

pip install -e ".[dev]"
pytest

Benchmarks

Performance benchmarks are continuously monitored with CodSpeed. To run benchmarks locally:

pytest benchmarks/ --codspeed

asyncplus vs FastAPI mount

The suite includes direct comparisons between asyncplus and the FastAPI mount workaround (app.mount("/socket.io", socket_app)) on the same scenarios:

Scenario What’s measured
HTTP to FastAPI (/) Full ASGI dispatch to your FastAPI app
HTTP to Socket.IO (/socket.io/) Dispatch to the Socket.IO ASGI app
WebSocket to Socket.IO (/socket.io/) Dispatch to Socket.IO for the WebSocket
App creation Time to build the combined ASGI app

Same scopes and mocks are used for both approaches so results are comparable. See benchmarks/test_bench_asyncplus_vs_mount.py.

License

LGPL-2.1-only

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

asyncutilsx-0.3.0.tar.gz (29.4 kB view details)

Uploaded Source

Built Distribution

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

asyncutilsx-0.3.0-py3-none-any.whl (19.5 kB view details)

Uploaded Python 3

File details

Details for the file asyncutilsx-0.3.0.tar.gz.

File metadata

  • Download URL: asyncutilsx-0.3.0.tar.gz
  • Upload date:
  • Size: 29.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for asyncutilsx-0.3.0.tar.gz
Algorithm Hash digest
SHA256 97a5e6a199b521a69441896cf183db3adbf2ef874a71c1ceb25c9eb9bcf20f90
MD5 a6c59c986e6fdc8461729c5d9ff0167a
BLAKE2b-256 e0a8b389343f3b20ccbb9c20dbbf16d9dd711e0a2d0d6ccb94e50665d2044001

See more details on using hashes here.

File details

Details for the file asyncutilsx-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: asyncutilsx-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 19.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for asyncutilsx-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2507f060cb1b3d3160d90ec8ad9a3af9cd8305b3e90e317214490e1b1a4f526b
MD5 72e466cc5c1cb597f6a211d53886b856
BLAKE2b-256 4cfb3ba87fa4e7383168c2f5421517d773017f47c191ce02574d03966a7be480

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