Skip to main content

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

Metadata

Release files for asyncutilsx 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for asyncutilsx 0.3.0
File Size Uploaded
asyncutilsx-0.3.0.tar.gz 29.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for asyncutilsx 0.3.0
File Interpreter ABI Platform
asyncutilsx-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.9 kB

Release files / asyncutilsx-0.3.0.tar.gz

Download URL asyncutilsx-0.3.0.tar.gz
Size 29.4 kB
Tags Source
SHA-256 checksum
How to use checksums
97a5e6a199b521a69441896cf183db3adbf2ef874a71c1ceb25c9eb9bcf20f90
BLAKE2b-256 checksum
How to use checksums
e0a8b389343f3b20ccbb9c20dbbf16d9dd711e0a2d0d6ccb94e50665d2044001
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / asyncutilsx-0.3.0-py3-none-any.whl

Download URL asyncutilsx-0.3.0-py3-none-any.whl
Size 19.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2507f060cb1b3d3160d90ec8ad9a3af9cd8305b3e90e317214490e1b1a4f526b
BLAKE2b-256 checksum
How to use checksums
4cfb3ba87fa4e7383168c2f5421517d773017f47c191ce02574d03966a7be480
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page