python-engineio

Python implementation of the Engine.IO realtime transport protocol powering Socket.IO servers and clients.

Library
PyPI
v4.13.5
258stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
81/100Excellent
Development Activity84
Maintenance84
Community76
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
85/100Excellent
Architecture88
Code Quality78
Innovation72
Learning Curve100

python-engineio is a Python implementation of the Engine.IO realtime transport protocol: the HTTP long-polling-with-WebSocket-upgrade layer that Socket.IO is built on. It ships both synchronous (Server/Client, for threading, eventlet, and gevent) and asynchronous (AsyncServer/AsyncClient, for aiohttp, ASGI, Tornado, and Sanic) implementations behind a shared API, so the same application code can run under a traditional WSGI deployment or a modern asyncio-based one.

It is maintained by Miguel Grinberg and serves as the transport foundation for his python-socketio package, but it can also be used directly by anyone who wants Engine.IO’s connection lifecycle (automatic transport upgrade, ping/pong monitoring, CORS, binary/JSON payload framing) without adopting Socket.IO’s full event and namespace model.

What You Get

  • Synchronous Server/Client classes for threading, eventlet, and gevent deployments
  • Asynchronous AsyncServer/AsyncClient classes for aiohttp, ASGI, Tornado, and Sanic deployments
  • WSGI and ASGI middleware (Middleware, WSGIApp, ASGIApp) for mounting alongside existing apps
  • Low-level packet/payload encoding utilities for the Engine.IO wire protocol

Common Use Cases

  • Adding realtime WebSocket/long-polling transport to a Flask, aiohttp, or FastAPI backend
  • Serving as the transport layer under a Socket.IO server via python-socketio
  • Building a lightweight custom realtime client/server pair without a full Socket.IO event system

Under The Hood

Architecture base_server.py and base_client.py define the shared Engine.IO connection logic (packet handling, ping/pong lifecycle, transport-upgrade state machine), which server.py/client.py extend for synchronous deployments and async_server.py/async_client.py extend for asyncio-based ones. Transport-specific concerns live behind a pluggable driver layer in async_drivers/ (aiohttp.py, asgi.py, tornado.py, sanic.py, eventlet.py, gevent.py, gevent_uwsgi.py, threading.py), each providing driver-specific socket read/write and background-task primitives behind a uniform interface consumed by the base classes. socket.py/async_socket.py model a single client session’s state machine, while packet.py/payload.py handle wire-level encoding (packet type plus optional JSON or base64 binary payload) and payload batching for the polling transport. middleware.py exposes WSGIApp/Middleware so the engine can be mounted inside an arbitrary WSGI application.

Tech Stack A pure-Python package (Python >=3.8) built with setuptools/pyproject.toml, with a single required runtime dependency (simple-websocket>=0.10.0) and optional extras for client (requests, websocket-client), asyncio_client (aiohttp>=3.11), dev (tox), and docs (sphinx, furo). Async support spans aiohttp, ASGI (compatible with Starlette/FastAPI), Tornado, Sanic, eventlet, and gevent through the pluggable driver layer, letting the same server code target either a WSGI host or an asyncio-based one.

Code Quality The test suite splits into tests/common (shared sync/async parity coverage) and tests/async (asyncio-specific drivers: aiohttp, ASGI, Tornado, Sanic, socket, server, client), totalling well over 200 individual test functions run with pytest and branch coverage enforced through pytest-cov in a tox matrix. flake8 lints src, tests, and examples. Error handling goes through an explicit engineio.exceptions module rather than swallowing failures, though the codebase does not use static type hints or mypy, relying on extensive docstrings instead.

What Makes It Unique The standout technical choice is the breadth of its pluggable async-driver abstraction: the same Server/AsyncServer API can run under threading, eventlet, gevent, gevent_uwsgi, aiohttp, ASGI, Tornado, or Sanic without application code changes, letting a team migrate from a WSGI deployment to an asyncio one incrementally. It doesn’t attempt to define a new realtime protocol (Engine.IO itself is specified by the upstream Socket.IO project) — its value is portability and reliability as the transport foundation beneath python-socketio.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search