Name: [709] Jeff Rush
Member: 88 months
Authored: 15 videos
Description: Greetings. I'm the (former) Python Advocacy Coordinator and a strong supporter of screencasts. I'm also the organizer of the Dallas-Ft. Worth Pythoneers and was con chair for PyCon 2006 and 2007 in Dallas. I'm also an independent consultant and work in the areas of Python/Zope, embedded Linux s ...

Walkthru of a Twisted Webserver [ID:373] (2/2)

in series: Python Source Walkthrough Series

video tutorial by Jeff Rush, added 09/07

(Showmedo is undergoing major changes. To report any problems viewing the videos please email us and include browser and OS specifics. Cheers - Kyran.)

A guided walkthrough of a website served using the Twisted framework. The site illustrates the STAN document object model, iterative construction of page content and how to hook an RSS feed of news into a side pane of the site.

A simple introduction to Twisted Web using Python for those just getting started.

"""
  Objective:

    Render a simple Web page containing text, data,
    and graphics. Wireframe design to be provided.

  Implementation:

    This sample makes use of the Twisted framework,
    which is more than a web framework but supports
    other protocols, both server and client.
    Information about Twisted can be found at:

        http://twistedmatrix.com/trac/

    The sample also makes use of STAN, a document
    object model lighter than that of W3C, and part
    of the Nevow extension to Twisted, for defining
    the page HTML layout.  Nevow can be obtained at:

        http://divmod.org/trac/wiki/DivmodNevow

    As an aside, the Nevow package provides very
    cool AJAX/COMET support for Python with its
    Athena module.  We don't use AJAX for this
    example though.

    For parsing an example RSS feed, the sample
    relies upon:

      Universal Feed Parser by Mark Pilgrim (Author
      of "Dive into Python")
      http://code.google.com/p/feedparser/
      http://feedparser.org/docs/

    Python has many web frameworks, some of which
    generate HTML source programmatically from
    within Python, and others of which use a
    template language and embed Python expressions
    into the stylized HTML.  Twisted uses a slightly
    different approach, in providing a "Pythonic
    DOM" model, where the HTML is defined, not as
    strings, in the Python program itself.  This DOM
    model allows for very powerful aggregation of
    HTML fragments, such as widgets, access to the
    full expressive power of Python, and reliable
    escaping of variable values into URL and HTML
    safe strings.

  Execution:

    This source file represents the entire webserver
    instance.  It gets imported at runtime into the
    Twisted framework, which provides network
    listening, daemon-restart/backgrounding
    management and Apache-format common logging.

    To bring up the server in the foreground:

      % twistd -noy sample.tac

    and point your browser to http://localhost:8081

"""

import sys
import os
import os.path
import urllib2
import feedparser

from twisted.application import service, strports
from nevow import appserver, loaders, static, rend
from nevow import tags as T

def SiteWelcome(context, data):
    """Return an HTML fragment for the center pane
       of the front page.
    """

    text = """
        Python is a dynamic object-oriented
        programming language that can be used for
        many kinds of software development. It
        offers strong support for integration with
        other languages and tools, comes with
        extensive standard libraries, and can be
        learned in a few days. Many Python
        programmers report substantial productivity
        gains and feel the language encourages the
        development of higher quality, more
        maintainable code.

        Python runs on Windows, Linux/Unix, Mac OS
        X, OS/2, Amiga, Palm Handhelds, and Nokia
        mobile phones. Python has also been ported
        to the Java and .NET virtual machines.

        Python is distributed under an OSI-approved
        open source license that makes it free to
        use, even for commercial products.

        The Python Software Foundation (PSF) holds
        and protects the intellectual property
        rights behind Python, underwrites the PyCon
        conference, and funds grants and other
        projects in the Python community.
    """

    return [ T.p[para] for para in text.split('\n\n') ]

def pull_rssfeed(feed_url, maxstories=9):
    "Pull the most recent N news stories and format to HTML."

    events = []

    feed = feedparser.parse(feed_url)
    for entry in feed.entries:
        events.append( T.a(href=entry.link)[ entry.title ] )
        if len(events) >= maxstories:
            break

    return events

class MySiteRootPage(rend.Page):
    """Define the content and general layout of the
       site front page.
    """
    addSlash = True

    docFactory = loaders.stan(
        T.html(xmlns='http://www.w3.org/1999/xhtml', lang='en')[
            T.head[
                T.title['Sample Code'],
                T.link(href='/samplesite.css',
                       type='text/css',
                       rel='stylesheet')
            ],
            T.body[
                T.table(style='width: 100%;', border=1)[
                    T.tr[
                        T.td(id='banner', colspan=3)[
                            T.img(src='/sitelogo.png'),
                            #T.img(src='/sitephoto.gif')
                        ],
                    ],
                    T.tr[
                        # We can indirect the
                        # content and presentation
                        # to methods defined further
                        # below in this class, with
                        # the data assembly and
                        # presentation kept
                        # separate.

                        T.td(id='sidelinks',
                             render=T.directive('linkset'),
                             data=T.directive('linkset')),

                        # Or we can point to a
                        # callable that will provide
                        # both content and
                        # presentation together.

                        T.td(id='newspane')[ SiteWelcome ],

                        # Or just assemble the
                        # pieces as we see fit.

                        T.td(id='events')[
                            T.a(href='http://us.pycon.org/')[
                                T.img(src='/eventlogo.png'),
                            ],
                            T.br,
                            T.div(id='rssfeed')[
                                pull_rssfeed(
                                  'http://www.python.org/channews.rdf',
                                  maxstories=5)
                            ],
                        ],
                    ],
                ]
            ]
        ]
    )

    def data_linkset(self, context, data):
        """Return a list of links, with labels, for
           'linkset' directive above.
        """
        return (
            ('The Basics',
             'http://www.python.org/about/'),
            ('Documentation',
             'http://www.python.org/doc/'),
            ('Downloads',
             'http://www.python.org/download/'),
            ('Code Samples',
             'http://aspn.activestate.com/ASPN/Python/Cookbook/'),
            ('Discussion Forum',
             'http://www.python.org/community/lists/'),
            ('About Us',
             'http://www.python.org/psf/'),
            )

    def render_linkset(self, context, links):
        """Given a list of links, format as a
           sequence of anchor tags.
        """
        return context.tag[
            [ T.a(href=url)[ label ] for label, url in links ]
        ]

####
# Assemble the URL address space for the website
# from various page objects and arrange for it to be
# served on a particular port.
#
# Note:
#   This is not a normal 'program main' as you might
#   be used to.  We are using the 'twistd' command
#   to start the server.  That command imports this
#   module, which executes the various setups, and
#   then plucks out the module-level variable
#   'application' as the top of the tree of various
#   protocols/services to activate.  In our case,
#   there is only one service but there could also
#   be IMAP, POP, DNS, etc. etc.

# directory of this file
site_dir = os.path.split(os.path.abspath(__file__))[0]

root = MySiteRootPage()

root.putChild('samplesite.css',
    static.File(os.path.join(site_dir, 'sample.css')))

root.putChild('sitelogo.png',
    static.File(os.path.join(site_dir, 'sitelogo.png')))

root.putChild('sitephoto.gif',
    static.File(os.path.join(site_dir, 'sitephoto.gif')))

root.putChild('eventlogo.png',
    static.File(os.path.join(site_dir, 'eventlogo.png')))

# magic var name
application = service.Application("sampleserver")

http_site = appserver.NevowSite(root)
strports.service("8081",
    http_site).setServiceParent(application)

Got any questions?

Get answers in the ShowMeDo Learners Google Group.

Video statistics:

  • Video's rank shown in the most popular listing
  • Video plays: 4843 (since July 30th)
  • Plays in last week: 2
  • Published: 84 months ago

Thank-yous, questions and comments

If this video tutorial was helpful please take some time to say thank-you to the authors for their hard work. Feel free to ask questions. Let the author know why their video tutorial was useful - what are you learning about? Did the video tutorial save you time? Would you like to see more?

You may also want to see our ShowMeDo Google Group to speak to our active users and authors.

Your email address will not be published.

Show some quick comments >>








All comments excluding tick-boxed quick-comments

20. Ash Scheder Black Sat, 25 Sep 2010 18:45

Thanks Jeff, a concise and helpful tutorial. Much appreciated.

--ash


19. Wojciech Mamrak Wed, 26 May 2010 09:37

Great work, thanks!


18. Drake Smith Sat, 08 May 2010 09:04

Thank you Jeff for taking the time to put together this extremely helpful walk-through. I found it to be very informative.


Good video!

Didn't know you could do stuff like that.

Chris Norway


Nice work.


good very good


Nice walk through the source code. thank you


13. anonymous Mon, 12 Oct 2009 20:10

Good, informative and easy to follow. Thanks.


Very nice intro to Twisted.


11. anonymous Mon, 28 Sep 2009 09:30

Hi,

I enjoyed especially IPython videos.

They are very valuable and efficient for me (IPython learner).

Thank you Jeff.

Regards,

Tatuya


10. anonymous Sun, 27 Sep 2009 16:20

A quick and effective intro into Twisted. Good work.


9. anonymous Thu, 07 May 2009 08:54

I've been looking at a bunch of webserver alternatives over the last month or so and your demo really has made me rethink how I use Twisted. I had no idea I can use it as a webserver (totally in my blindspot), but will definitely leverage this ability thanks to your timely presentation. Also, I'm from Dallas (now live in NYC) and will definitely look up the DFW Pythoneers next time I'm in town. Thanks again for the very informative demo presentation.


8. anonymous Tue, 14 Apr 2009 18:02

Very good. Something that explains Twisted deferreds would be handy for many, many people too!


7. anonymous Thu, 26 Mar 2009 02:56

Hello Jeff,

very interesting topic, but I miss some links for twisted.

Thanks Knut


6. anonymous Tue, 10 Mar 2009 23:07

The Twisted development team believes in text-only documentation (which probably suits their consulting business model), but videos explaining some of the concepts will be very useful.


very nice lecture .please give me if you have other lectures or reference for twisted web server

thans you for interesting lecture.


Thank you for showing us an application of the amazing twisted framework. Please please keep those coming...


External templates are good when you're (a) dealing with the whole page layout or (b) handing off the design work to a graphics designer.

STAN is good when (a) you're dealing with fragments of the whole page, a table here or a column there, that get programmatically assembled at runtime or (b) the person doing the layout is a Python programmer comfortable with the Pythonic syntax of STAN.

Many template languages also require XML syntax which just wasn't designed for direct human manipulation. Sure, some few like it or put up with it but others find it awkward. Template languages, and whether to put your logic in your template, your template in your logic, or to keep them totally separate (with coordination overhead) is a somewhat controversial topic.


Are there good reasons for using stan? why would you not use a template and keep the html separate?


Showmedo is a peer-produced video-tutorials and screencasts site for free and open-source software (FOSS)- with the exception of some club videos, the large majority are free to watch and download.

how to help » about » faq »

Educating the Open-source Community With Showmedo

Although as important as the software it supports, education and documentation are relatively neglected in the Open-source world. Coders love to code, and explaining how best to use or improve the software tends to be deferred or even sidelined.

At Showmedo we believe the community can play a vital role here and also say thanks for the tools and software that make our lives easier. If you have a piece of software you love or a programming langugage you are enthusiastic about, why not make a screencast showing others how to use it? All the stuff you wish you'd been told, the tips, tricks, insights that would have saved you time and frustration.

Screencasting is easier than you think, and we're happy to help you. You can emailus for advice or just use some of the how-to screencasts on the site. This screencasting learning-pathis a good place to start.

Kudos and Thanks for Jeff

Learning Paths

This series lies on the following learning-paths. Learning-paths are a new initiative at Showmedo, to start structuring our content better. You can find out more here.

Content

Feedback

Showmedo's development is fairly rapid and bugs will inevitably creep in. If you have any problems please drop us a line using the contact address below. Likewise, any suggestions for improvements to the site are gratefully received.

feedback@showmedo.com