[Web-SIG] Combine wsgi and asyncio - possible?

Frank Millman frank at chagford.com
Mon Sep 29 15:26:22 CEST 2014

Hi all

I am developing a business/accounting application. It is not a web server in
the conventional sense, but it uses http, and clients connect to it via a
web browser.  The server responds to an initial connection by sending a
block of javascript which uses on_load() to display a welcome page. After
that, all communication is handled by ajax-style messages passed between
server and client. At no point is a new page requested or reloaded.

My first attempt was written using the wsgi protocol and the cherrypy wsgi
server. It worked fine, but things progressed.

My second version is written using python 3.4 and asyncio. In theory it
could also use wsgi, but I use a particular technique which I think is
incompatible with wsgi, so I handle the requests directly. It works in my
testing environment, but in the real world users will not want to deploy my
app as a stand-alone http server, so I need to find a better solution.

I would like to explain the technique I am using and the reason for it.
Perhaps someone can suggest how this can be done in a wsgi-compliant manner.

Communication between client and server follows a typical gui event
loop. The client waits for a user action, then sends a message to the server
with the information. The server processes the information and sends a
response, which the client receives and redisplays to the user.

Sometimes one user action generates more than one 'event'. I package these
up into a list and send them to the server in one message. As the server
processes the events, it can result in multiple responses to the client.
These are also packaged up and sent in one message.

However, it can happen that while the server is working through the events,
it needs to send a message to the client to pop up a dialog box, ask a
question, and get a response before proceeding. With asyncio I can create a
Future to set up and send the message, and use 'yield from
asyncio.wait_for(...)' to wait for the response.

I am using asyncio.start_server(). For each request, the handler is passed a
client_reader and a client_writer. Normally the writer is used to write the
response to the original request, but if I need to ask a question, I use the
writer to send the 'dialog box' message. When I get the response, I take the
new client_writer and pass it back to the original request handler for it to
complete the request.

As I understand it, wsgi requires me to actually 'return' the response, so I
don't have the opportunity to call 'yield from', and I do not get access to 
the writer object.

Any suggestions welcome.

Frank Millman

More information about the Web-SIG mailing list