Recently I released ws4py, a package that provides client and server WebSocket support for Python 2.6 and 2.7.
Let’s first have a quick overview of what ws4py offers for now:
- WebSocket specification draft-10 of the current specification.
- A threaded client. This gives a simple client that doesn’t require an external dependency.
- A Tornado client. This client is based on Tornado 2.0 which is quite a popular way of running asynchronous networking code these days. Tornado provides its own server implementation so I didn’t include mine in ws4py.
- A CherryPy extension so that you can integrate WebSocket from within your CherryPy 3.2.1 server.
- A gevent server based on the popular gevent library. This is courtesy of Jeff Lindsay.
- Based on Jeff’s work, a pure WSGI middleware as well (available in the current master branch only until the next release).
- ws4py runs on Android devices thanks to the SL4A package
Hopefully more client and servers will be added along the way as well as Python 3.x support. The former should be rather simple to add due to the way I designed ws4py.
The main idea is to make a distinction between the bytes provider and the bytes processing. The former is essentially reading and writing bytes from the connected socket. The latter is the function of making something out of the received bytes based on the WebSocket specification. In most implementations I have seen so far, both are rather heavily intertwined making it difficult to use a different bytes provider.
ws4py tries a different path by relying on a great feature of Python: the possibility to send data back to a generator. For instance, the frame parsing yields the quantity of bytes each time it needs more and the caller feeds back the generator those bytes once they are received. In fact, the caller of a frame parser is a stream object which acts the same way. The caller of that stream object is in fact the bytes provider (a client or a server). The stream is in charge of aggregating frames into a WebSocket message. Thanks to that design, both the frame and stream objects are totally unaware of the bytes provider and can be easily adapted in various contexts (gevent, tornado, CherryPy, etc.).
On my TODO list for ws4py:
- Upgrade to a more recent version of the specification
- Python 3.x implementation
- Better documentation, read, write documentation.
- Better performances on very large WebSocket messages
CherryPy runs on Android thanks to the SL4A project. So if you feel like running Python and your own web server on your Android device, well you can just do so. You’ve probably not heard something that awesome since the pizza delivery guy rung the door.
How to get on about it? Well that’s the surprise, CherryPy in itself doesn’t need to be patched. Granted I haven’t tried all the various tools provided by CherryPy but the server and the dispatching works just fine.
First, you need get the CherryPy source code, build and copy the resulting cherrypy package into the SL4A scripts directory.
Once you’ve plugged your phone to your machine through USB, run the next commands:
$ svn co http://svn.cherrypy.org/trunk cp3-trunk
$ cd cp3-trunk
$ python setup.py build
$ cp -r build/lib.linux-i686-2.6/cherrypy/ /media/usb0/sl4a/scripts/
Just change the path to match your environment.Â That’s it.
Now you can copy your own script, let’s assume you use something like below:
# -*- coding: utf-8 -*-
# The multiprocessing package isn't
# part of the ASE installation so
# we must disable multiprocessing logging
logging.logMultiprocessing = 0
self.droid = android.Android()
return "Hello from my phone"
location = self.droid.getLastKnownLocation().result
location = location.get('network', location.get('gps'))
return "LAT: %s, LON: %s" % (location['latitude'],
if __name__ == '__main__':
As you can see we must disable the multiprocessing logging since the multiprocessing package isn’t included with SL4A.
Save that script on your computer as cpdroid.py for example. Copy that file into the scripts directory of SL4A.
$ cp cpdroid.py /media/usb0/sl4a/scripts/
Unplug your phone and go to the SL4A application. Click on the cpdroid.py script, it should start fine. Then from your browser, go to http://phone_IP:8080/ and tada! You can also go to the /location path to get the geoloc of your phone.
Today is my last day at Ipsis as I’m joining Ubikod starting from Monday to become a senior software developer.
Ubikod is a young but enthusiastic company that is geared toward the future as they’re leading the way of social network for the Google Android platform through BuddyMob.
The team is passionate and has gathered quite a great knowledge of the platform. On top of that they’re using foxy technologies like XMPP for their platform and I’m excited about getting my hands on.
Things are looking great.