Lingwo.ws with Pylons

This is a short addendum to part 1 of my Lingwo.ws tutorial.

Aaron wanted to know how to run Lingwo.ws on WebFaction.  In talking to him later, it turns out he wants to use it inside of a Pylons application.  I have just the code for him!  I'm using Lingwo.ws inside of Lingwo.flashcards which is built on Pylons.

So, quickly, some background: when you create a Pylons application, you end up with a small library of code named like your application.  For example, in Lingwo.flashcards, that app is actually called "lingwo_flashcards".  Anyway, all your code goes in there.  For the rest of this example, we'll pretend that our application is named "myapp", ok?

First, you need to make a function creating your service with all its containers.  We'll put this in myapp/lib/api.py:

from myapp.server import *

# here you would define your container classes..
# we will be covering how to do this in Part 2 of the tutorial.
class MyAwesomeContainer(object):
    # TODO: define me!
    pass

def createService(base_url):
    # create your Service object and attach all your container instances
    return Service('1.0', base_url, {
        'awesome': MyAwesomeContainer()
    })

Then add the following to myapp/config/middleware.py, right before "return app" at the bottom of make_app():

    from paste.urlmap import URLMap
    from myapp.lib.api import createService
    urlmap = URLMap(app)
    api_base_url = config.get('myapp.api.base_url', 'http://localhost/api')
    urlmap[api_base_url] = createService(api_base_url)
    app = urlmap

Then we add the "myapp.api.base_url" variable to your development.ini underneath [app:main]:

[app:main]
use = egg:myapp
# etc ...
myapp.api.base_url = http://localhost/api

Et voila!

A few notes:

  • Building your API will happen in myapp/lib/api.py.  This mostly involves creating custom containers to model your application.  We will be covering how to do this Part 2 of the tutorial.  There are a few other things that aren't covered yet, that you'll need to add there too: multiple versions of your API and your key store if you're going to use authentication.  If you're exploding for an example, check-out the Lingwo.flashcards code from Bazaar.
  • We added the service to the middleware using paste.urlmap.  This means the service will only respond to exactly its base_url.  This is alot like a virtual host in Apache.  There are a couple of ways to make it respond to any URL that reaches the server, including: using paste.cascade or a custom routing middleware.
  • When you move your Pylons app into production, you will need to make sure that "myapp.api.base_url" in your production.ini contains the real URL of the service (ie., http://www.example.com/api).  This is used by the Service when returning _href properties on a document, as well as by paste.urlmap per the previous point.

Happy Hacking!