Latest Version: 0.9.6.2
  Dashboard > Pylons Cookbook > ... > Controllers > Attaching WSGI apps under Pylons
  Pylons Cookbook Log In | Sign Up   View a printable version of the current page.  
  Attaching WSGI apps under Pylons
Added by Ben Bangert, last edited by Philip Jenvey on Oct 31, 2007  (view change) show comment
Labels: 
(None)

Name Space Section Page Version Status Reviewed Author(s)
Attaching WSGI apps under Pylons Pylons Cookbook Controllers Attaching WSGI apps under Pylons 1.0 Draft False 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.

Site running on a free Atlassian Confluence Open Source Project License granted to Pylons. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.3 Build:#645 Feb 13, 2007) - Bug/feature request - Contact Administrators
Top