Repoze Sprint at PyAtl: A******Glue is born

by Noah Gift

The last 7 days, have been very crazy for me. Last weekend, I ended up in Los Angeles, for a couple days, and was able to grab some Cuban Pastries:



Before hopping back on a plane for Atlanta:



Back in Georgia, I felt very much at home when I spotted some familiar local scenery, a guy with a mullet in a camaro (with a killer "G-Force" bumper sticker), next to a man in a costume in the middle of traffic, asking for money:



Next, it was a Tuesday visit to the monthly Atlanta-Plone meeting. Where we discussed the upcoming Repoze Sprint/Visit:





On Thursday, we met with Tres and Chris, who happened to write supervisor, and they gave a tremendous talk on WSGI, Repoze, and Deliverance, that blew the PyAtl crowd away.

One of the more dramatic, show and tell, pieces, was a local demonstration of their "theme trac like Plone trick". The crowd was blown away, when Tres and Chris stole, borrowed, pick your favorite word, the pyatl plone 3.0 site, and themed a localhost trac instance. We also saw a great debugging middleware WSGI tool, that "leaked" objects in the WSGI stack. WSGI is truly an incredible technology, and I am so excited about it, I almost can't sleep.

Next on Friday, we hunkered down at Georgia Tech, and starting playing with Repoze a little more:



One silly idea that came up after a few beers at lunch, was writing the simplest possible WSGI application using the WSGI spec from Pep 333. By using Ian Bicking's pythonpaste, Tres was able to walk me through setting up the most simple possible WSGI application. We used string substitution and pickle, and gave birth to A******Glue, AGlue, for short. AGlue is just a proof of concept, with a funny name.

If you are use virtualenv, and pythonpaste, it is quite simple to make a little web application using WSGI. You really only need to create an /etc directory in your virtualenv, that includeds a .ini file, such as this:

Step 1: Create a .ini file

[server:main]
use = egg:Paste#http
host = 127.0.0.1
port = 8080

[app:aglue]
paste.app_factory = aGlue.app:factory
path = %(here)s/../var

[pipeline:main]
pipeline = egg:Paste#evalerror aglue


Step 2: Next make some simple model.py like this:


class Book(object):
"""A book object"""

def __init__(self, ISBN, title, reviewer=None):
self.ISBN = ISBN
self.title = title
self.reviewer = reviewer


Step 3: Finally, make a app.py, or controller:



import os
import pickle
from paste.request import parse_formvars

from model import Book
template = """

<html>

<body>

<p>



<a href = "http://pyatl.org">pyatl.org</a>

</p>

"""

row = """

<p>%(title)s <form method="post"><input type="hidden" name="index" value = "%(index)d">

<input type = "submit" name = "delete" value="delete">

</form>

</p>

"""



epilogue="""



<form method="post">

<input type="text" name = "ISBN">

<input type="text" name = "title">

<input type="submit" name = "submit" value = "add">

</body></html>

"""
def middleFinger(environ, start_response):
"""Why did you use this, punk?
"""
form = parse_formvars(environ)
if form:
if 'submit' in form:
book = Book(ISBN=form['ISBN'],title=form['title'])
books.append(book)
saveList()
elif 'delete' in form:
index = int(form['index'])
del books[index]
saveList()
print form
page = [template]
for index in range(len(books)):
book = books[index]
page.append(row%{'index':index,'title':book.title})
page.append(epilogue)
status = '200 OK'
response_headers = [('Content-type', 'text/html')]
start_response(status, response_headers)
return [''.join(page)]

def saveList():
file = open('/tmp/persistant.db', 'w')
pickle.dump(books,file)
file.close()

def factory(global_config, persist = '/tmp/persistant.db',**local_config):
global books
books = []
if not os.path.exists(persist):
saveList()
else:
file = open(persist)
books = pickle.load(file)
return middleFinger



With that little bit of code, you get something like this:



One thing I learned from the last few days, is that Ian Bicking is amazing! Between virtualenv, and pythonpaste alone, it is an incredible, how many tools he creates to help other Python programmers. Tres and Chris, are also equally amazing, and I would recommend trying to get them to come to your local user group for a Repoze/Deliverance talk too!

There will be a video posted this week of their talk this week on YouTube, and I will also upload a more refined version of AGlue, to the cheeseshop in a few days.