Tornado-sent events¶
An implementation of the publish/subscribe pattern for the Tornado web server.
Installation¶
Tornadose is on PyPI:
$ pip install tornadose
This will grab the latest official release. Alternatively, or for development, you can clone the repository and install it manually:
$ git clone https://github.com/mivade/tornadose.git
$ cd tornadose
$ python setup.py install
Usage¶
A simple example of using server-sent events (a.k.a. EventSource):
import random
from tornado.ioloop import IOLoop, PeriodicCallback
from tornado.web import Application
from tornadose.handlers import EventSource
from tornadose.stores import DataStore
store = DataStore()
app = Application(
[(r'/', EventSource, {'store': store})],
debug=True)
app.listen(9000)
loop = IOLoop.instance()
PeriodicCallback(lambda: store.set_data(random.random()), 1000).start()
loop.start()
To monitor the stream with curl:
$ curl http://localhost:9000
or with HTTPie:
$ http -S get localhost:9000
Additional demos can be found in the demos
directory.
Contributing¶
Contributions, complaints, criticisms, and whatever else are welcome. The source code and issue tracker can be found on GitHub.
See also¶
Some other implementations of server-sent events with Tornado include:
License¶
Tornadose is freely available under the terms of the MIT license. See
LICENSE
for details.
Contents¶
Data storage and publishing¶
In order to publish data to listeners, Tornadose utilizes a data store concept somewhat reminiscent of that used in Flux. In short, subscribers start listening to a data store and are notified when there are updates.
-
class
tornadose.stores.
BaseStore
(*args, **kwargs)[source]¶ Base class for all data store types.
At a minimum, derived classes should implement
submit
andpublish
methods.-
initialize
(*args, **kwargs)[source]¶ Hook for doing custom initialization. Child classes should implement this method instead of overwriting
__init__
.
-
publish
()[source]¶ Push messages to all listeners. This method must be implemented by child classes. A recommended way to implement this method is as a looping coroutine which yields until new data is available via the
submit()
method.
-
-
class
tornadose.stores.
DataStore
(*args, **kwargs)[source]¶ Generic object for producing data to feed to clients.
To use this, simply instantiate and update the
data
property whenever new data is available. When creating a newEventSource
handler, specify theDataStore
instance so that theEventSource
can listen for updates.
-
class
tornadose.stores.
QueueStore
(*args, **kwargs)[source]¶ Publish data via queues.
This class is meant to be used in cases where subscribers should not miss any data. Compared to the
DataStore
class, new messages to be broadcast to clients are put in a queue to be processed in order.QueueStore
will work with anytornado.web.RequestHandler
subclasses which implement asubmit
method. It is recommended that a custom subscription handler’ssubmit()
method also utilize a queue to avoid losing data. The subscriber must also register/deregister itself with theQueueStore
via theQueueStore.register()
andQueueStore.deregister()
methods.A
QueueStore
-compatible request handler is included intornadose.handlers.WebSocketSubscriber
.
Request handlers¶
Tornadose defines handlers for using the EventSource interface or
WebSockets. For other handlers, the BaseHandler
class is
provided.
-
class
tornadose.handlers.
BaseHandler
(application, request, **kwargs)[source]¶ Bases:
tornado.web.RequestHandler
Base handler for subscribers. To be compatible with data stores defined in
tornadose.stores
, custom handlers should inherit this class and implement thesubmit()
andpublish()
methods.-
initialize
(store)[source]¶ Common initialization of handlers happens here. If additional initialization is required, this method must either be called with
super
or the child class must assign thestore
attribute and register itself with the store.
-
-
class
tornadose.handlers.
EventSource
(application, request, **kwargs)[source]¶ Bases:
tornadose.handlers.BaseHandler
Handler for server-sent events a.k.a. EventSource.
The EventSource interface has a few advantages over websockets:
-
class
tornadose.handlers.
WebSocketSubscriber
(application, request, **kwargs)[source]¶ Bases:
tornadose.handlers.BaseHandler
,tornado.websocket.WebSocketHandler
A Websocket-based subscription handler.
Changelog¶
Version 0.2.2¶
2015-10-21
- Fix bug that printed out all messages sent with websocket subscribers which was originally present for debugging purposes.
Version 0.2.1¶
2015-10-17
- Subscription handlers automatically get registered with stores. This simplifies creating custom handlers.
Version 0.2.0¶
2015-10-11
- Reworks stores and handlers (backwards incompatible!).
- Adds a new queue-based
QueueStore
store. - Implements a websocket-based subscriber to supplement
EventSource
. - Begins to add unit testing.
Version 0.1.2¶
2015-09-20
- Defines an
EventSource
request handler and aDataStore
object for using server-sent events with Tornado.