I've got a small backlog of code that I've been meaning to open source and "announce" so this week may very well be "coding" week here on my blog. I promise to try to mix things up and get my Round Table post written this week (not that I have many days after this week to do so) as well.

The first couple, at least, will be remotely Assassins!-related. Because right now the codebase is the most valuable asset in my poor, poor company I don't plan to open source the majority of the code itself. I do plan to re-release the last version of Assassins, which now is merely a distant relative to the "modern" codebase. This week my plan is to release some of the sub-projects that Assassins has yielded.

Today's choice bit is webappfb.py, which is a relative to the djangofb toolset that Pyfacebook provides for Facebook applications targeting Django. In this case it is many similar tools for Google App Engine's bare bones object-oriented webapp framework. I know that webapp isn't the greatest framework, nor is it one with a great amount of support. However, it is a great minimal framework that seems perfect for the super-fast response times that are needed for a Facebook application. webappfb.py is a similarly "minimal" toolkit to remove some of the repetition needed in developing Facebook apps against webapp.

I'm not a huge fan of git, but it's what "upstream", Pyfacebook, has swapped to, so it's what I've used in this case. I've posted webappfb.py to my fork at github: webappfb.py. I also did the kind thing and sent a pull request upstream to see if it sticks.

I'll have to write "real" documentation, probably, but it should be mostly self-explanatory to anyone that has seen webapp documentation. Primarily, webappfb.FacebookRequestHandler can be used just about anywhere you would use webapp.RequestHandler. FacebookRequestHandler provides a self.facebook instance (using the API key and secret key that you can store in a simple facebook.yaml file).

FacebookRequestHandler also provides the functionality offered by djangofb.requires_login decorator. To use it, just set a requires_login attribute on your request handler. You'll also want to check against self.redirecting to keep from performing application logic when not-logged in. FacebookRequestHandler provides a Facebook-friendly self.redirect() that takes case of the proper FBML response.

FacebookRequestHandler also provides memcache-backed "user" messages tagged to a Facebook uid and stored for a limited time. This is a simple relative to Django's user messaging that makes use of the always-available nature of App Engine's memcache.

Finally, FacebookCanvasHandler is a simple FacebookRequestHandler subclass that realizes that canvas requests (for Facebook applications choosing to use the FBML route) are always HTTP POST and takes care of self.redirecting among other things, providing a canvas() handler to use rather than post().

A simple example:

from webappfb import FacebookCanvasHandler, FacebookRequestHandler

class SampleHandler(FacebookRequestHandler):
   requires_login = True

   def post(self):
       if self.redirecting: return

       # TODO: Your application logic

       # Can use self.facebook here to make API calls

       # Save a temporary "flash" message for the current
       # Facebook user
       self.add_user_message('success', 'This is a test.')

       self.redirect(self.facebook.get_app_url('other/page'))

class OtherPageHandler(FacebookCanvasHandler):
    requires_login = True

    def canvas(self):
        for msg in self.get_and_delete_messages():
            self.response.write("""<fb:%(kind)s>
                 <fb:message>%(message)s</fb:message>
                 %(detail)s
                 </fb:%(kind)s>""" % msg)