Skip to content

Commit

Permalink
refactor wsgi and asgi middlewares
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelgrinberg committed Nov 24, 2018
1 parent 84faa99 commit 1f78785
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 48 deletions.
1 change: 1 addition & 0 deletions docs/_static/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Place static files used by the documentation here.
24 changes: 18 additions & 6 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ API Reference

.. module:: engineio

``Middleware`` class
--------------------

.. autoclass:: Middleware
:members:

``Server`` class
----------------

Expand All @@ -24,3 +18,21 @@ API Reference
.. autoclass:: AsyncServer
:members:
:inherited-members:

``WSGIApp`` class
-----------------

.. autoclass:: WSGIApp
:members:

``ASGIApp`` class
-----------------

.. autoclass:: ASGIApp

``Middleware`` class (deprecated)
---------------------------------

.. autoclass:: Middleware
:members:

8 changes: 4 additions & 4 deletions engineio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import sys

from .middleware import Middleware
from .middleware import WSGIApp, Middleware
from .server import Server
if sys.version_info >= (3, 5): # pragma: no cover
from .asyncio_server import AsyncServer
from .async_tornado import get_tornado_handler
from .async_asgi import create_asgi_app
from .async_asgi import ASGIApp
else: # pragma: no cover
AsyncServer = None

__version__ = '2.3.2'

__all__ = ['__version__', 'Middleware', 'Server']
__all__ = ['__version__', 'Server', 'WSGIApp', 'Middleware']
if AsyncServer is not None: # pragma: no cover
__all__ += ['AsyncServer', 'get_tornado_handler', 'create_asgi_app']
__all__ += ['AsyncServer', 'ASGIApp', 'get_tornado_handler']
48 changes: 36 additions & 12 deletions engineio/async_asgi.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,41 @@
import sys


class Asgi:
def __init__(self, engineio_server, asgi_app=None,
engineio_path='engine.io', static_files=None):
class ASGIApp:
"""ASGI application middleware for Engine.IO.
This middleware dispatches traffic to an Engine.IO application, and
optionally serve a list of static files to the client or forward regular
HTTP traffic to another ASGI application.
:param engineio_server: The Engine.IO server.
:param static_files: A dictionary where the keys are URLs that should be
served as static files. For each URL, the value is
a dictionary with ``content_type`` and ``filename``
keys. This option is intended to be used for serving
client files during development.
:param other_asgi_app: A separate ASGI app that receives all other traffic.
:param engineio_path: The endpoint where the Engine.IO application should
be installed. The default value is appropriate for
most cases.
Example usage::
import engineio
import uvicorn
eio = engineio.Server()
app = engineio.ASGIApp(eio, static_files={
'/': {'content_type': 'text/html', 'filename': 'index.html'},
'/index.html': {'content_type': 'text/html',
'filename': 'index.html'},
})
uvicorn.run(app, '127.0.0.1', 5000)
"""
def __init__(self, engineio_server, other_asgi_app=None,
static_files=None, engineio_path='engine.io'):
self.engineio_server = engineio_server
self.asgi_app = asgi_app
self.other_asgi_app = other_asgi_app
self.engineio_path = engineio_path.strip('/')
self.static_files = static_files or {}

Expand All @@ -15,8 +45,8 @@ def __call__(self, scope):
return self.engineio_asgi_app(scope)
elif scope['type'] == 'http' and scope['path'] in self.static_files:
return self.serve_static_file(scope)
elif self.asgi_app is not None:
return self.asgi_app(scope)
elif self.other_asgi_app is not None:
return self.other_asgi_app(scope)
elif scope['type'] == 'lifespan':
return self.lifespan
else:
Expand Down Expand Up @@ -65,12 +95,6 @@ async def not_found(self, receive, send):
'body': b'not found'})


def create_asgi_app(engineio_server, asgi_app=None, engineio_path='engine.io',
static_files=None):
return Asgi(engineio_server, asgi_app=asgi_app,
engineio_path=engineio_path, static_files=static_files)


async def translate_request(scope, receive, send):
class AwaitablePayload(object):
def __init__(self, payload):
Expand Down
29 changes: 19 additions & 10 deletions engineio/middleware.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
class Middleware(object):
"""WSGI middleware for Engine.IO.
class WSGIApp(object):
"""WSGI application middleware for Engine.IO.
This middleware dispatches traffic to an Engine.IO application, and
optionally forwards regular HTTP traffic to a WSGI application.
optionally forwards regular HTTP traffic to a WSGI application, or serve
a list of predefined static files to clients.
:param engineio_app: The Engine.IO server.
:param wsgi_app: The WSGI app that receives all other traffic.
:param engineio_path: The endpoint where the Engine.IO application should
be installed. The default value is appropriate for
most cases.
:param static_files: A dictionary where the keys are URLs that should be
served as static files. For each URL, the value is
a dictionary with ``content_type`` and ``filename``
keys. This option is intended to be used for serving
client files during development.
:param engineio_path: The endpoint where the Engine.IO application should
be installed. The default value is appropriate for
most cases.
Example usage::
import engineio
import eventlet
from . import wsgi_app
eio = engineio.Server()
app = engineio.Middleware(eio, wsgi_app)
app = engineio.WSGIApp(eio, static_files={
'/': {'content_type': 'text/html', 'filename': 'index.html'},
'/index.html': {'content_type': 'text/html',
'filename': 'index.html'},
})
eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
"""
def __init__(self, engineio_app, wsgi_app=None, engineio_path='engine.io',
static_files=None):
def __init__(self, engineio_app, wsgi_app=None, static_files=None,
engineio_path='engine.io'):
self.engineio_app = engineio_app
self.wsgi_app = wsgi_app
self.engineio_path = engineio_path.strip('/')
Expand Down Expand Up @@ -63,3 +67,8 @@ def get_socket(self):
else:
start_response("404 Not Found", [('Content-type', 'text/plain')])
return ['Not Found']


class Middleware(WSGIApp):
"""This class has been renamed to WSGIApp and is now deprecated."""
pass
8 changes: 1 addition & 7 deletions examples/asgi/latency.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import os
import uvicorn

import engineio

eio = engineio.AsyncServer(async_mode='asgi')
app = engineio.create_asgi_app(eio, static_files={
app = engineio.ASGIApp(eio, static_files={
'/': {'content_type': 'text/html', 'filename': 'latency.html'},
'/static/engine.io.js': {'content_type': 'application/javascript',
'filename': 'static/engine.io.js'},
Expand All @@ -13,11 +12,6 @@
})


async def index(request):
with open('latency.html') as f:
return web.Response(text=f.read(), content_type='text/html')


@eio.on('message')
async def message(sid, data):
await eio.send(sid, 'pong', binary=False)
Expand Down
7 changes: 1 addition & 6 deletions examples/asgi/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,13 @@
import engineio

eio = engineio.AsyncServer(async_mode='asgi')
app = engineio.create_asgi_app(eio, static_files={
app = engineio.ASGIApp(eio, static_files={
'/': {'content_type': 'text/html', 'filename': 'simple.html'},
'/static/engine.io.js': {'content_type': 'application/javascript',
'filename': 'static/engine.io.js'}
})


async def index(request):
with open('simple.html') as f:
return web.Response(text=f.read(), content_type='text/html')


@eio.on('connect')
def connect(sid, environ):
print("connect ", sid)
Expand Down
2 changes: 1 addition & 1 deletion examples/tornado/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
tornado==5.0.2
tornado==5.1.1
python-engineio
six==1.10.0
2 changes: 1 addition & 1 deletion examples/wsgi/latency.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

eio = engineio.Server(async_mode=async_mode)
app = Flask(__name__)
app.wsgi_app = engineio.Middleware(eio, app.wsgi_app)
app.wsgi_app = engineio.WSGIApp(eio, app.wsgi_app)


@app.route('/')
Expand Down
2 changes: 1 addition & 1 deletion examples/wsgi/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

eio = engineio.Server(async_mode=async_mode)
app = Flask(__name__)
app.wsgi_app = engineio.Middleware(eio, app.wsgi_app)
app.wsgi_app = engineio.WSGIApp(eio, app.wsgi_app)


@app.route('/')
Expand Down

0 comments on commit 1f78785

Please sign in to comment.