Thursday, May 15, 2008

python on web - getting started : building your first app

I would be focusing here on the following tasks.


  • install pylons.

  • create a helloworld app using pylons.

  • install genshi.

  • change template engine.

  • deploy on apache using mod_wsgi.



Install Pylons

Run the following:

$ easy_install Pylons==0.9.6.1
OR
$ easy_install -f http://pylonshq.com/download/ Pylons==0.9.6.1

More details at http://wiki.pylonshq.com/display/pylonsdocs/Installing+Pylons


Create helloworld app

$ paster create -t pylons helloworld

A directory helloworld with the following structure is created

jayant@jayantbox:~/myprogs/python/helloworld$ ls -lh
total 44K
drwxr-xr-x 4 jayant jayant 4.0K 2008-04-25 17:47 data
-rwxr-xr-x 1 jayant jayant 1.5K 2008-05-15 10:41 development.ini
drwxr-xr-x 2 jayant jayant 4.0K 2008-04-25 17:47 docs
drwxr-xr-x 2 jayant jayant 4.0K 2008-04-25 17:47 ez_setup
drwxr-xr-x 9 jayant jayant 4.0K 2008-05-14 19:52 helloworld
drwxr-xr-x 2 jayant jayant 4.0K 2008-04-25 17:47 helloworld.egg-info
-rwxr-xr-x 1 jayant jayant 79 2008-04-25 17:47 MANIFEST.in
-rwxr-xr-x 1 jayant jayant 463 2008-04-25 17:47 README.txt
-rwxr-xr-x 1 jayant jayant 1.2K 2008-04-25 17:47 setup.cfg
-rwxr-xr-x 1 jayant jayant 865 2008-04-25 17:47 setup.py
-rwxr-xr-x 1 jayant jayant 507 2008-04-25 17:47 test.ini

To run the app, from within the helloworld directory do

jayant@jayantbox:~/myprogs/python/helloworld$ paster serve --reload development.ini
Starting subprocess with file monitor
Starting server in PID 15555.
serving on 0.0.0.0:5000 view at http://127.0.0.1:5000

Create a test.html in the <path_to_helloworld>helloworld/helloworld/public directory

<html>
<body>
Hello World!!
</body>
</html>


And point your browser to http://127.0.0.1:5000/test.html to see the "Hello World!!" page.

Now lets create a controller and try printing info through a template.

jayant@jayantbox:~/myprogs/python/helloworld$ paster controller hello
Creating /home/jayant/myprogs/python/helloworld/helloworld/controllers/hello.py
Creating /home/jayant/myprogs/python/helloworld/helloworld/tests/functional/test_hello.py

Edit the <path_to_helloworld>/helloworld/helloworld/controllers/hello.py file and put in some python code

import logging

from helloworld.lib.base import *

log = logging.getLogger(__name__)

class HelloController(BaseController):

    def index(self):
        # Return a rendered template
        # return render('/some/template.mako')
        # or, Return a response
        return 'Hello World'
    def serverinfo(self):
        import cgi
        import pprint
        c.pretty_environ = cgi.escape(pprint.pformat(request.environ))
        c.name = 'Jayant Kumar'
        return render('serverinfo.mako')

Now create a template serverinfo.mako in <path_to_helloworld>/helloworld/helloworld/templates

<h2>
Server info for ${request.host}
</h2>

<p>
The URL you called: ${h.url_for()}
</p>

<p>Hi there ${c.name or c.full_name or "Joe Smith"}</p>

<p>
The name you set: ${c.name}
</p>

<p>The WSGI environ:<br>
<pre>${c.pretty_environ}</pre>
</p>

Edit the <path_to_helloworld>/helloworld/helloworld/config/routing.py file and check if the following code there in the "CUSTOM ROUTES" section

map.connect('', controller='hello', action='index')
map.connect(':controller/:action/:id')
map.connect('*url', controller='template', action='view')

This means that an empty URL is matched to the index action of the hello controller. Otherwise, the route mapper looks for URLs in the form controller/action/id, but if action or controller are not specified the request is routed to the view action of the templates controller (created by the Pylons template). This raises a 404 error by default

Now go to http://localhost:5000/hello/hello and http://localhost:5000/hello/serverinfo and check out the output.

Installing genshi and switching the template engine

$ easy_install Genshi

To enable genshi in your project edit the <path_to_helloworld>/helloworld/helloworld/config/environment.py file and change the template engine from mako to genshi

    config.init_app(global_conf, app_conf, package='helloworld',
        template_engine='genshi', paths=paths)


Now create a new template in <path_to_helloworld>/helloworld/helloworld/templates, say serverinfo.html and put in the following code

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
lang="en">
<h2>
Testing...
</h2>

<p>Hi there ${c.name}</p>

<p>
The name you set: ${c.name}
</p>

<p>The WSGI environ:<br/>
<div py:content="c.pretty_environ">Pretty Environ</div>
</p>
</html>

And change your <path_to_helloworld>/helloworld/helloworld/controllers/hello.py to render the new template

        return render('serverinfo')

And check the output at http://localhost:5000/hello/hello and http://localhost:5000/hello/serverinfo

Deploy using mod_wsgi

For those who have not yet configured mod_wsgi, you can get mod_wsgi from http://code.google.com/p/modwsgi/.

Simply untar it and do a

./configure --with-apxs=/path/to/apache/bin/apxs
make
sudo make install


Bingo and you have the mod_wsgi.so file in your apache/modules directory

Change the httpd.conf and add the following

LoadModule wsgi_module modules/mod_wsgi.so

to load the wsgi module and then deploy the hello world application

WSGIDaemonProcess hello thread=25
WSGIScriptAlias /hello "/path/to/apache/anydirectory/hello.wsgi
<Location /hello>
        WSGIProcessGroup hello
        WSGIReloadMechanism Process
</Location>


This says that the application helloworld would run as a separate process with 25 threads. And since we have also enabled process reload mechanism available with mod_wsgi-2.0, all that is needed to restart/reload the application is to touch/change the wsgi script modification time.

Wait a minute, we did not create the hello.wsgi script. Create a directory in /path/to/apache or anywhere where apache has read access and where you want to keep your application startup scripts. So what i did was.

$ mkdir /path/to/apache/wsgi

And create a hello.wsgi inside it

cd /path/to/apache/wsgi
vim hello.wsgi


Add the following code here

import os, sys
sys.path.append('/path/to/python/application/helloworld')

from paste.deploy import loadapp

application = loadapp('config:/path/to/python/application/helloworld/development.ini')


And we are done. Please note that the /path/to/python/application should be readable and executable by apache. Or you can do (very unsafe - not recommended on production servers)

chmod -R a+rx /path

Now simply restart apache and point your browser to

http://localhost/hello/
and
http://localhost/hello/hello/serverinfo

To see the output.

Source:
http://wiki.pylonshq.com/display/pylonsdocs/Installing+Pylons
http://wiki.pylonshq.com/display/pylonsdocs/Getting+Started
http://wiki.pylonshq.com/display/pylonsdocs/Using+Other+Template+Languages
http://code.google.com/p/modwsgi/wiki/InstallationInstructions
http://code.google.com/p/modwsgi/wiki/IntegrationWithPylons

No comments: