Table Of Contents

Previous topic

Maintainabiity

Next topic

How Tos

This Page

Other

Dev app (process)

Suggestions while developing application that uses pubsub:

  • Design your application into independent modules or subpackages that don’t import one another

  • Define basic topics exist in the application: ‘user’ (events from user interface), ‘filesystem’ (events from local filesystem), etc. These are your messaging topics. You may find it useful to use printTreeDocs from pubsub.utils.

  • Use Topic Definition Providers as eary as possible. Use pub.exportTopicTreeSpec() if already have partial implementation, and pub.addTopicDefnProvider() and pub.setTopicUnspecifiedFatal().

  • Start all listener functions and methods with pubOn, for instance def psOnCloseDocument()

  • Define some data for each message type, and which data are optional/required

  • Implement your modules

    • Subscribe listeners with appropriate signature (according to data for each topic/event type)
    • Send messages with appropriate data
    • Handle messages in listeners, without making any assumptions about sender or order of receipt
  • Testing: import your control modules and generate messages to exercise them.

You can see a very informative view of an application before and after incorporatng pubsub, at Steven Sproat’s dev site (click “expand all” and “show diffs side-by-side”). Steven says:

You can see how I removed some GUI logic from the Canvas class (a child of the GUI) and placed “controller” functions into my GUI that subscribed to pubsub topics and delegates to the appropriate classes.

Messaging Protocol

Pubsub supports two ways to send messages and transmit the data to listeners:

  • kwargs: this is the syntax that requires each message datum to be a separate keyword argument in the sendMessage, i.e. pub.sendMessage(topicName, **msgArgs). The listener signature can provide default values to its arguments, in which case the corresponding message data are optional: def listener(a, b, c=1, d=2): pass is a listener that requires a and b, and optonally accepts c and d.
  • arg1: this is the syntax that requires all message data to be inserted in one object, i.e. pub.sendMessage(topicName, msg) and pub.sendMessage(topicName, msg). I.e. msg is optional. The listener must access fields of msg to retrieve the message data.

The arg1 was the first and only protocol of pubsub. It was difficult to specify what data was allowed in a topic, thus requiring the developer to put in verification code in the listener, having to deal with exceptions resulting from mismatches in field names, etc, it worked but for larger applications it involved more effort than seemed necessary.

The kwargs protocol was then designed: it allows the sender to name each datum, and the recipient (listener) to be checked via introspection at subscription time for its capability to receive the data. It also made it easier to document the message data. The protocol was implemented as pubsub version 3.

Due to the significant differences between the two, and the goal of kwargs being to allow for better runtime checks by pubsub, only one protocol can be active when importing pubsub: the application must choose either kwargs or arg1. The default is the kwargs protocol. In order to use arg1, the application must import pubsub.setuparg1.

The only reason for using the arg1 protocol is to avoid upgrading an application that was developed when this protocol was the only choice. Any new application should use the default kwargs protocol.

API Versions

As pubsub matured, its API went through 2 dramatic changes:

  • version 1: the version that was part of wxPython, supported a message sending syntax that corresponded to the “arg1” messaging protocol
  • version 2: also part of wxPython, made various improvements but was short lived as it did not address the inherent limitations of the arg1 protocol
  • version 3: pubsub was moved out of wxPython to be a standalone project. Since then, wxPython includes a copy of the pubsub package in wx.lib.

The version 1 of pubsub API is called v1 and was supported until the end of pypubsub v3.1 branch by importing pubsub.setupv1. Starting version 3.2, the v1 API is no longer available as part of pubsub. The version 3 of pubsub API is called v3

The version 1 API was the default in wx.lib.pubsub until pubsub version 3.1.0 (wx.lib.pubsub did the setupv1 import automatically). After that, it was deprecated. Eventually the default in wx.lib.pubsub was the v3 API with kwargs protocol; users had to manually import setuparg1 once in their application if they did not want to port their application to use the kwargs protocol. If this was a problem, they could continue to use setupv1. WxPython Phoenix will use pubsub 3.2, with the default being the kwargs protocol, and no support for v1 API.

Receiving all data of a topic

Listener uses **kwargs then will be given all data of message, not just portion specific to registration topic. For example,

>>> def listener(**kwargs): pass
>>> pub.subscribe(listener, 'topic')
>>> pub.sendMessage('topic', arg1=1, arg2=2)

Then listener will receive arg1 and arg2.