| 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.