[Twisted-Python] One big smile ...

Moshe Zadka m at moshez.org
Sat Jul 12 12:13:37 MDT 2003


On 12 Jul 2003, Abe Fettig <abe at fettig.net> wrote:

> I've attached two examples.  The first downloads my RSS feed using
> Twisted, parses it with feedparser, and prints the results.  As you can
> see, it's only a few lines of code.

Thanks a lot!
I would want, however, to comment on your examples and to show how
they could be a bit more "idiomatic".

from twisted.web.client import getPage
from feedparser import FeedParser
from twisted.internet import reactor, threads

def parsePage(data):
    parser = FeedParser()
    parser.feed(data)
    return parser

def formatParser(parser):
    return '\n'.join([parser.channel.get('title'), '']+
                     [i.get('title') for i in parser.items]+[''])

def getFormattedRSS(url):
    return getPage(url).addCallback(parsePage).addCallback(formatParser)

if __name__ == '__main__':
    import sys
    getFormattedRSS('http://www.fettig.net/?flav=rss'
    ).addCallback(sys.stdout.write
    ).addCallback(lambda _: reactor.stop()
    )
    reactor.run()

Note the "Golden rule": physically, the reactor.stop() and the reactor.run()
calls should be in physical proximity. This is a nice rule of thumb
for writing reusable code. Note, for example, how we can now use this
module (say, called formattedrss) to write resources:

import cgi
from twisted.web import resource, server
import formattedrss

class RSSFormatedResource(resource.Resource):

    def __init__(self, url):
        resource.Resource.__init__(self)
        self.url = url

    def render(self, request):
        getFormattedRSS(self.url).addCallback(request.write
        ).addCallback(lambda _: request.finish())
        return server.NOT_DONE_YET

or for implementing something useful for simple telnet clients:

from twisted.internet import protocol
from formattedrss import getFormattedRSS

class RSSFormattedProtocol(protocol.Protocol):

    def connectionMade(self):
        getFormattedRSS(self.factory.url).addCallback(self.transport.write
        ).addCallback(lambda _: self.transport.loseConnection())

class RSSFormattedFactory(protocol.Factory):
    protocol = RSSFormattedProtocol

    def __init__(self, url):
        self.url = url

if __name__ == '__main__':
    from twisted.internet import reactor
    reactor.listenTCP(1111,
                      RSSFormattedFactory('http://www.fettig.net/?flav=rss')

In general, this illustrates a not-completely-obvious technique: using
.addCallbacks to modify the return type of a deferred. This example
shows a common use for it: parsing raw data, and returning munged results.
-- 
Moshe Zadka -- http://moshez.org/
Buffy: I don't like you hanging out with someone that... short.
Riley: Yeah, a lot of young people nowadays are experimenting with shortness.
Agile Programming Language -- http://www.python.org/




More information about the Twisted-Python mailing list