Building a Subscriber in Python

Now let’s explore the same subscriber implementation, but now using Python. For this example, the subscriber classes are stored in a file name subscriber.py:

import re
import urllib
import urllib2

'''
' Class: Subscription Error
' Description: Custom error class for subscription exceptions
'''
class SubscribeError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

'''
' Class: Subscriber
' Description: Provides ability to subscribe / unsubscribe from hub feeds
'''
class Subscriber:
    regex_url = re.compile('^https?://')    #simple URL string validator

    #constructor that stores the hub and callback URLs for the subscriber
    def __init__(self, hub, callback):
        if self.regex_url.match(hub): self.hub = hub
        else: raise SubscribeError('Invalid hub URL supplied')

        if self.regex_url.match(callback): self.callback = callback
        else: raise SubscribeError('Invalid callback URL supplied')

    #initiates a request to subscribe to a feed
    def subscribe(self, feed):
        return self.change_subscription('subscribe', feed)

    #initiates a request to unsubscribe from a feed
    def unsubscribe(self, feed):
        return self.change_subscription('unsubscribe', feed)

    #makes request to hub to subscribe / unsubscribe
    def change_subscription(self, mode, feed):
        #check if provided feed is a valid URL
        if self.regex_url.match(feed):
            #set the post string for subscribe / unsubscribe
            post_string = 'hub.mode=%s&hub.callback=%s&hub.verify=async&hub.topic=%s'
                        % (mode, self.callback, urllib.quote(feed))

            try:
                #make return to hub
                file = urllib2.urlopen(self.hub, post_string)
                return True
            except (IOError, urllib2.HTTPError), e:
                #process http conditions in 2xx range as valid
                if hasattr(e, 'code') and str(e.code)[0] == '2':
                    return True

                #process alternative error conditions
                error = ''
                if hasattr(e, 'read'):
                    error = e.read()
                raise SubscribeError('%s, Response: "%s"' % (e, error))
        else:
            raise SubscribeError('Invalid feed URL supplied')

Just like with the Python publisher, the subscriber file has a custom exception class, SubscribeError, whose purpose is to output exceptions that are encountered during the execution of the subscription.

When a new instance of the Subscriber class is created, the constructor will be called. The constructor’s purpose is to accept URLs for the hub and callback, check that they are valid, and store them if valid or display exceptions if they’re not.

The subscribe(...) and unsubscribe(...) methods are helper methods that accept a feed URL and then call the change_subscription(...) method with the appropriate mode for the action to be taken, either subscribe or unsubscribe.

change_subscription(...) is used to make the request to the hub to subscribe to a feed. We start by checking if the feed URL provided is valid. If so, we start constructing the POST string that will be sent to the hub. It will consist of:

hub.mode

The subscription mode to run, either subscribe or unsubscribe

hub.callback

The callback URL on the subscriber site, to which new feed updates from the publisher should be POSTed

hub.verify

The verify mode, either sync or async

hub.topic

The feed URL

We then issue a POST request to the hub URL, passing in the POST string. If the request completes successfully, we return True. If an error is thrown, we handle it by first checking the HTTP response code. If the code is in the 2xx range, we treat it as a valid response and return True. A valid response should be an HTTP 202 code, but anything in the 2xx range is a success. If the code isn’t in that range, we throw an exception with the appropriate error response.

Now let’s see how we can use these classes to build a subscriber:

from subscriber import *

#define hub, callback and feed
hub = 'http://pubsubhubbub.appspot.com/'
callback = 'http://www.example.com/publish'
feed = 'http://www.example.com'

#create new subscriber
subscriber = Subscriber(hub, callback)

#subscribe / unsubscribe methods: response == True on success
response = subscriber.subscribe(feed)
#response = subscriber.unsubscribe(feed)

#print message on success
if (response == True):
    print 'Content-Type: text/plain'
    print ''
    print 'Request successful'

We start by importing the subscriber file that we created earlier and then define the URLs for our hub, callback, and the feed that we will be performing the action on. Next, we create a new Subscriber object, passing in the hub and callback. Using that new object, we call either the subscribe(...) or unsubscribe(...) methods, passing in the feed URL. Last, we check the response from the called method and, if True, display a message stating that the request was successful.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.136.84