PylonsHQ.

Layout: Fixed-width

Attaching WSGI apps under Pylons

Unknown macro: {metadata-list}
Name Attaching WSGI apps under Pylons
Space Pylons Cookbook
Section Controllers
Page Attaching WSGI apps under Pylons
Version 1.0
Status Draft
Reviewed False
Author(s) Ben Bangert

This recipe assumes a basic level of familiarity with the WSGI Specification (PEP 333)

Introduction

WSGI runs deep through Pylons, and is present in many parts of the architecture. Since Pylons controllers are actually called with the WSGI interface, normal WSGI applications can also be Pylons 'controllers'. Optionally, if a full WSGI app should be mounted and handle the remainder of the URL, Routes can automatically move the right part of the URL into the SCRIPT_NAME, so that the WSGI application can properly handle its PATH_INFO part.

This recipe will demonstrate adding a basic WSGI app as a Pylons controller.

Developing WSGI apps under Pylons

First, you will need to assure that you have Pylons installed. See the installation instructions, or in a nutshell:

1
easy_install -U Pylons>=0.9.6

Then create your project:

1
paster create -t pylons wsgitest

Now you should be set to make sure your project launches:

1
2
cd wsgitest
paster serve --reload development.ini

Create the Controller

Now, create a new controller file in your Pylons project directory:

1
paster controller wsgiapp

This sets up the basic imports that you may want available when using other WSGI applications.

Update the Controller for a WSGI App

In this case, the project is named 'wsgitest'; if your project is named something else, your project will have slightly different imports. Now update your controller, controllers/wsgiapp.py, so it looks like this:

1
2
3
4
5
6
7
8
9
import logging

from wsgitest.lib.base import *

log = logging.getLogger(__name__)

def WsgiappController(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')])
    return ["Hello World"]

To test that this works, load up your pylons app,

1
paster serve development.ini

Then visit http://localhost:5000/wsgiapp

You should see "Hello World" printed out.

Caveats

This basic approach has one drawback, the full PATH_INFO has not been adjusted given that some of the URL was used to get to this location. When hooking up other WSGI applications, they will expect the part of the URL that was used to get to this controller, to have been moved into the SCRIPT_NAME variable in environ.

To see this, change the above controller, controllers/wsgiapp.py, to show these two environ variables:

1
2
3
4
5
6
7
8
9
import logging

from wsgitest.lib.base import *

log = logging.getLogger(__name__)

def WsgiappController(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')])
    return ["The app is located at: %s, and the path here is: %s" % (environ['SCRIPT_NAME'], environ['PATH_INFO'])]

If you load a URL now such as "http://localhost:5000/wsgiapp/fred", you should see:
The app is located at: , and the path here is: /wsgiapp/fred

Setting Up Routes

The Pylons routing system (Routes) has functionality to properly setup the environ in this configuration, with the small addition a map route for this controller.

Edit your projects config/routing.py to include this new route. Your config/routing.py should now look something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from pylons import config
from routes import Mapper

def make_map():
    """Create, configure and return the routes Mapper"""
    map = Mapper(directory=config['pylons.paths']['controllers'],
                 always_scan=config['debug'])

    # The ErrorController route (handles 404/500 error pages); it should likely
    # stay at the top, ensuring it can always be resolved
    map.connect('error/:action/:id', controller='error')

    # CUSTOM ROUTES HERE

    # Map the WSGI application
    map.connect('wsgiapp/*path_info', controller='wsgiapp')
    
    map.connect(':controller/:action/:id')
    map.connect('*url', controller='template', action='view')

    return map

The important addition being the WSGI application mapping. By specifying the '*path_info' dynamic path, Routes knows you intend to map a WSGI application under this mount point in your application. It will put everything leading up to the *path_info in the SCRIPT_NAME, and the rest will go in the PATH_INFO.

Here's the output of the same URL (http://localhost:5000/wsgiapp/fred) with the new route in place:
The app is located at: /wsgiapp, and the path here is: /fred

Conclusion

Pylons WSGI capabilities make using WSGI applications a breeze inside your Pylons app. Whether you need to control access to a sub-site, or just use smaller WSGI apps you've developed elsewhere.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

Powered by Pylons - Contact Administrators