[373] Walkthru of a Twisted Webserver (2/2)
in series: Python Source Walkthrough Series
video tutorial by Jeff Rush
Name:
[709] Jeff Rush
Member:
34 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 ...
Our authors tell us that feedback from you is a big motivator. Please take a few moments to let them know what you think of their work.
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.
Video Tutorials related by tag:
Got any questions?
Get answers in the ShowMeDo Learners Google Group.
Video statistics:
- Video's rank shown in the most popular listing
- Video plays: 2764 (since July 30th)
- Plays in last week: 20
- Published: 29 months ago
"""
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)
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.
Nice walk through the source code. thank you
Good, informative and easy to follow. Thanks.
Very nice intro to Twisted.
Hi,
I enjoyed especially IPython videos.
They are very valuable and efficient for me (IPython learner).
Thank you Jeff.
Regards,
Tatuya
A quick and effective intro into Twisted. Good work.
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.
Very good. Something that explains Twisted deferreds would be handy for many, many people too!
Hello Jeff,
very interesting topic, but I miss some links for twisted.
Thanks Knut
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.
Very good
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?



